From cba5f6bd01bc3ba692c355ca82212db069cd800c Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Tue, 5 Dec 2017 18:07:28 +0100 Subject: [PATCH 001/830] Rewrite Borrow's trait documentation. --- src/libcore/borrow.rs | 147 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 132 insertions(+), 15 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 61558034e63e..76f6215fae65 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -12,26 +12,143 @@ #![stable(feature = "rust1", since = "1.0.0")] -/// A trait for borrowing data. +// impl Borrow for String +// impl Borrow for Arc +// impl HashSet { fn get(&self, q: &Q) where K: Borrow } + +/// A trait identifying how borrowed data behaves. /// -/// In general, there may be several ways to "borrow" a piece of data. The -/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` -/// (a mutable borrow). But types like `Vec` provide additional kinds of -/// borrows: the borrowed slices `&[T]` and `&mut [T]`. +/// If a type implements this trait, it signals that a reference to it behaves +/// exactly like a reference to `Borrowed`. As a consequence, if a trait is +/// implemented both by `Self` and `Borrowed`, all trait methods that +/// take a `&self` argument must produce the same result in both +/// implementations. /// -/// When writing generic code, it is often desirable to abstract over all ways -/// of borrowing data from a given type. That is the role of the `Borrow` -/// trait: if `T: Borrow`, then `&U` can be borrowed from `&T`. A given -/// type can be borrowed as multiple different types. In particular, `Vec: -/// Borrow>` and `Vec: Borrow<[T]>`. +/// As a consequence, this trait should only be implemented for types managing +/// a value of another type without modifying its behavior. Examples are +/// smart pointers such as [`Box`] or [`Rc`] as well the owned version of +/// slices such as [`Vec`]. /// -/// If you are implementing `Borrow` and both `Self` and `Borrowed` implement -/// `Hash`, `Eq`, and/or `Ord`, they must produce the same result. +/// A relaxed version that allows providing a reference to some other type +/// without any further promises is available through [`AsRef`]. /// -/// `Borrow` is very similar to, but different than, `AsRef`. See -/// [the book][book] for more. +/// When writing generic code, a use of `Borrow` should always be justified +/// by additional trait bounds, making it clear that the two types need to +/// behave identically in a certain context. If the code should merely be +/// able to operate on any type that can produce a reference to a given type, +/// you should use [`AsRef`] instead. /// -/// [book]: ../../book/first-edition/borrow-and-asref.html +/// The companion trait [`BorrowMut`] provides the same guarantees for +/// mutable references. +/// +/// [`Box`]: ../boxed/struct.Box.html +/// [`Rc`]: ../rc/struct.Rc.html +/// [`Vec`]: ../vec/struct.Vec.html +/// [`AsRef`]: ../convert/trait.AsRef.html +/// [`BorrowMut`]: trait.BorrowMut.html +/// +/// # Examples +/// +/// As a data collection, [`HashMap`] owns both keys and values. If the key’s +/// actual data is wrapped in a managing type of some kind, it should, +/// however, still be possible to search for a value using a reference to the +/// key’s data. For instance, if the key is a string, then it is likely +/// stored with the hash map as a [`String`], while it should be possible +/// to search using a [`&str`][`str`]. Thus, `insert` needs to operate on a +/// string while `get` needs to be able to use a `&str`. +/// +/// Slightly simplified, the relevant parts of `HashMap` look like this: +/// +/// ``` +/// use std::borrow::Borrow; +/// use std::hash::Hash; +/// +/// pub struct HashMap { +/// # marker: ::std::marker::PhantomData<(K, V)>, +/// // fields omitted +/// } +/// +/// impl HashMap { +/// pub fn insert(&self, key: K, value: V) -> Option +/// where K: Hash + Eq +/// { +/// # unimplemented!() +/// // ... +/// } +/// +/// pub fn get(&self, k: &Q) -> Option<&V> +/// where K: Borrow, +/// Q: Hash + Eq + ?Sized +/// { +/// # unimplemented!() +/// // ... +/// } +/// } +/// ``` +/// +/// The entire hash map is generic over the stored type for the key, `K`. +/// When inserting a value, the map is given such a `K` and needs to find +/// the correct hash bucket and check if the key is already present based +/// on that `K` value. It therefore requires `K: Hash + Eq`. +/// +/// In order to search for a value based on the key’s data, the `get` method +/// is generic over some type `Q`. Technically, it needs to convert that `Q` +/// into a `K` in order to use `K`’s [`Hash`] implementation to be able to +/// arrive at the same hash value as during insertion in order to look into +/// the right hash bucket. Since `K` is some kind of owned value, this likely +/// would involve cloning and isn’t really practical. +/// +/// Instead, `get` relies on `Q`’s implementation of `Hash` and uses `Borrow` +/// to indicate that `K`’s implementation of `Hash` must produce the same +/// result as `Q`’s by demanding that `K: Borrow`. +/// +/// As a consequence, the hash map breaks if a `K` wrapping a `Q` value +/// produces a different hash than `Q`. For instance, image you have a +/// type that wraps a string but compares ASCII letters case-insensitive: +/// +/// ``` +/// use std::ascii::AsciiExt; +/// +/// pub struct CIString(String); +/// +/// impl PartialEq for CIString { +/// fn eq(&self, other: &Self) -> bool { +/// self.0.eq_ignore_ascii_case(&other.0) +/// } +/// } +/// +/// impl Eq for CIString { } +/// ``` +/// +/// Because two equal values need to produce the same hash value, the +/// implementation of `Hash` need to reflect that, too: +/// +/// ``` +/// # use std::ascii::AsciiExt; +/// # use std::hash::{Hash, Hasher}; +/// # pub struct CIString(String); +/// impl Hash for CIString { +/// fn hash(&self, state: &mut H) { +/// for c in self.0.as_bytes() { +/// c.to_ascii_lowercase().hash(state) +/// } +/// } +/// } +/// ``` +/// +/// Can `CIString` implement `Borrow`? It certainly can provide a +/// reference to a string slice via its contained owned string. But because +/// its `Hash` implementation differs, it cannot fulfill the guarantee for +/// `Borrow` that all common trait implementations must behave the same way +/// and must not, in fact, implement `Borrow`. If it wants to allow +/// others access to the underlying `str`, it can do that via `AsRef` +/// which doesn’t carry any such restrictions. +/// +/// [`Hash`]: ../hash/trait.Hash.html +/// [`HashMap`]: ../collections/struct.HashMap.html +/// [`String`]: ../string/struct.String.html +/// [`str`]: ../primitive.str.html +/// #[stable(feature = "rust1", since = "1.0.0")] pub trait Borrow { /// Immutably borrows from an owned value. From c4ea700041f78a016dca557c2da86006a7bbedf8 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Tue, 5 Dec 2017 18:28:29 +0100 Subject: [PATCH 002/830] Remove trailing white space. --- src/libcore/borrow.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 76f6215fae65..4d4a07f59d14 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -100,12 +100,12 @@ /// /// Instead, `get` relies on `Q`’s implementation of `Hash` and uses `Borrow` /// to indicate that `K`’s implementation of `Hash` must produce the same -/// result as `Q`’s by demanding that `K: Borrow`. +/// result as `Q`’s by demanding that `K: Borrow`. /// /// As a consequence, the hash map breaks if a `K` wrapping a `Q` value /// produces a different hash than `Q`. For instance, image you have a /// type that wraps a string but compares ASCII letters case-insensitive: -/// +/// /// ``` /// use std::ascii::AsciiExt; /// @@ -148,7 +148,7 @@ /// [`HashMap`]: ../collections/struct.HashMap.html /// [`String`]: ../string/struct.String.html /// [`str`]: ../primitive.str.html -/// +/// #[stable(feature = "rust1", since = "1.0.0")] pub trait Borrow { /// Immutably borrows from an owned value. From 85e8a9ba00e8ac090ceaac619110264e8e8bf6c6 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Thu, 7 Dec 2017 16:50:37 +0100 Subject: [PATCH 003/830] Include feedback and try to make examples build on all channels. --- src/libcore/borrow.rs | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 4d4a07f59d14..77006193a585 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -12,10 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -// impl Borrow for String -// impl Borrow for Arc -// impl HashSet { fn get(&self, q: &Q) where K: Borrow } - /// A trait identifying how borrowed data behaves. /// /// If a type implements this trait, it signals that a reference to it behaves @@ -26,10 +22,10 @@ /// /// As a consequence, this trait should only be implemented for types managing /// a value of another type without modifying its behavior. Examples are -/// smart pointers such as [`Box`] or [`Rc`] as well the owned version of -/// slices such as [`Vec`]. +/// smart pointers such as [`Box`] or [`Rc`] as well the owned version +/// of slices such as [`Vec`]. /// -/// A relaxed version that allows providing a reference to some other type +/// A relaxed version that allows converting a reference to some other type /// without any further promises is available through [`AsRef`]. /// /// When writing generic code, a use of `Borrow` should always be justified @@ -41,23 +37,24 @@ /// The companion trait [`BorrowMut`] provides the same guarantees for /// mutable references. /// -/// [`Box`]: ../boxed/struct.Box.html -/// [`Rc`]: ../rc/struct.Rc.html -/// [`Vec`]: ../vec/struct.Vec.html +/// [`Box`]: ../boxed/struct.Box.html +/// [`Rc`]: ../rc/struct.Rc.html +/// [`Vec`]: ../vec/struct.Vec.html /// [`AsRef`]: ../convert/trait.AsRef.html /// [`BorrowMut`]: trait.BorrowMut.html /// /// # Examples /// -/// As a data collection, [`HashMap`] owns both keys and values. If the key’s -/// actual data is wrapped in a managing type of some kind, it should, -/// however, still be possible to search for a value using a reference to the -/// key’s data. For instance, if the key is a string, then it is likely -/// stored with the hash map as a [`String`], while it should be possible -/// to search using a [`&str`][`str`]. Thus, `insert` needs to operate on a -/// string while `get` needs to be able to use a `&str`. +/// As a data collection, [`HashMap`] owns both keys and values. If +/// the key’s actual data is wrapped in a managing type of some kind, it +/// should, however, still be possible to search for a value using a +/// reference to the key’s data. For instance, if the key is a string, then +/// it is likely stored with the hash map as a [`String`], while it should +/// be possible to search using a [`&str`][`str`]. Thus, `insert` needs to +/// operate on a `String` while `get` needs to be able to use a `&str`. /// -/// Slightly simplified, the relevant parts of `HashMap` look like this: +/// Slightly simplified, the relevant parts of `HashMap` look like +/// this: /// /// ``` /// use std::borrow::Borrow; @@ -70,15 +67,16 @@ /// /// impl HashMap { /// pub fn insert(&self, key: K, value: V) -> Option -/// where K: Hash + Eq +/// where K: Hash + Eq /// { /// # unimplemented!() /// // ... /// } /// /// pub fn get(&self, k: &Q) -> Option<&V> -/// where K: Borrow, -/// Q: Hash + Eq + ?Sized +/// where +/// K: Borrow, +/// Q: Hash + Eq + ?Sized /// { /// # unimplemented!() /// // ... @@ -86,10 +84,11 @@ /// } /// ``` /// -/// The entire hash map is generic over the stored type for the key, `K`. -/// When inserting a value, the map is given such a `K` and needs to find -/// the correct hash bucket and check if the key is already present based -/// on that `K` value. It therefore requires `K: Hash + Eq`. +/// The entire hash map is generic over a key type `K`. Because these keys +/// are stored by with the hash map, this type as to own the key’s data. +/// When inserting a key-value pair, the map is given such a `K` and needs +/// to find the correct hash bucket and check if the key is already present +/// based on that `K`. It therefore requires `K: Hash + Eq`. /// /// In order to search for a value based on the key’s data, the `get` method /// is generic over some type `Q`. Technically, it needs to convert that `Q` @@ -103,10 +102,11 @@ /// result as `Q`’s by demanding that `K: Borrow`. /// /// As a consequence, the hash map breaks if a `K` wrapping a `Q` value -/// produces a different hash than `Q`. For instance, image you have a -/// type that wraps a string but compares ASCII letters case-insensitive: +/// produces a different hash than `Q`. For instance, imagine you have a +/// type that wraps a string but compares ASCII letters ignoring their case: /// /// ``` +/// # #[allow(unused_imports)] /// use std::ascii::AsciiExt; /// /// pub struct CIString(String); @@ -121,10 +121,10 @@ /// ``` /// /// Because two equal values need to produce the same hash value, the -/// implementation of `Hash` need to reflect that, too: +/// implementation of `Hash` needs to reflect that, too: /// /// ``` -/// # use std::ascii::AsciiExt; +/// # #[allow(unused_imports)] use std::ascii::AsciiExt; /// # use std::hash::{Hash, Hasher}; /// # pub struct CIString(String); /// impl Hash for CIString { @@ -145,7 +145,7 @@ /// which doesn’t carry any such restrictions. /// /// [`Hash`]: ../hash/trait.Hash.html -/// [`HashMap`]: ../collections/struct.HashMap.html +/// [`HashMap`]: ../collections/struct.HashMap.html /// [`String`]: ../string/struct.String.html /// [`str`]: ../primitive.str.html /// From fc6c6383f6999d87c92be3dfd5f09c357be41135 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Wed, 13 Dec 2017 08:48:29 +0100 Subject: [PATCH 004/830] Fix documentation links. --- src/libcore/borrow.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 77006193a585..33e4c8780d63 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -37,10 +37,10 @@ /// The companion trait [`BorrowMut`] provides the same guarantees for /// mutable references. /// -/// [`Box`]: ../boxed/struct.Box.html -/// [`Rc`]: ../rc/struct.Rc.html -/// [`Vec`]: ../vec/struct.Vec.html -/// [`AsRef`]: ../convert/trait.AsRef.html +/// [`Box`]: ../../std/boxed/struct.Box.html +/// [`Rc`]: ../../std/rc/struct.Rc.html +/// [`Vec`]: ../../std/vec/struct.Vec.html +/// [`AsRef`]: ../../std/convert/trait.AsRef.html /// [`BorrowMut`]: trait.BorrowMut.html /// /// # Examples @@ -144,10 +144,10 @@ /// others access to the underlying `str`, it can do that via `AsRef` /// which doesn’t carry any such restrictions. /// -/// [`Hash`]: ../hash/trait.Hash.html -/// [`HashMap`]: ../collections/struct.HashMap.html -/// [`String`]: ../string/struct.String.html -/// [`str`]: ../primitive.str.html +/// [`Hash`]: ../../std/hash/trait.Hash.html +/// [`HashMap`]: ../../std/collections/struct.HashMap.html +/// [`String`]: ../../std/string/struct.String.html +/// [`str`]: ../../std/primitive.str.html /// #[stable(feature = "rust1", since = "1.0.0")] pub trait Borrow { From 7ae7e5393367cdc9a630cd56911ab42f499c091f Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Thu, 8 Feb 2018 11:07:05 +0100 Subject: [PATCH 005/830] New introduction and revised hash map explanation. --- src/libcore/borrow.rs | 70 ++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 33e4c8780d63..1f692d019c3d 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -14,19 +14,28 @@ /// A trait identifying how borrowed data behaves. /// -/// If a type implements this trait, it signals that a reference to it behaves -/// exactly like a reference to `Borrowed`. As a consequence, if a trait is -/// implemented both by `Self` and `Borrowed`, all trait methods that -/// take a `&self` argument must produce the same result in both -/// implementations. +/// In Rust, it is common to provide different representations of a type for +/// different use cases. For instance, storage location and management for a +/// value can be specifically chosen as appropriate for a particular use via +/// pointer types such as [`Box`] or [`Rc`] or one can opt into +/// concurrency via synchronization types such as [`Mutex`], avoiding the +/// associated cost when in parallel doesn’t happen. Beyond these generic +/// wrappers that can be used with any type, some types provide optional +/// facets providing potentially costly functionality. An example for such a +/// type is [`String`] which adds the ability to extend a string to the basic +/// [`str`]. This requires keeping additional information unnecessary for a +/// simple, imutable string. /// -/// As a consequence, this trait should only be implemented for types managing -/// a value of another type without modifying its behavior. Examples are -/// smart pointers such as [`Box`] or [`Rc`] as well the owned version -/// of slices such as [`Vec`]. +/// These types signal that they are a specialized representation of a basic +/// type `T` by implementing `Borrow`. The method `borrow` provides a way +/// to convert a reference to the type into a reference to the underlying +/// basic type. /// -/// A relaxed version that allows converting a reference to some other type -/// without any further promises is available through [`AsRef`]. +/// If a type implementing `Borrow` implements other traits also +/// implemented by `T`, these implementations behave identically if the trait +/// is concerned with the data rather than its representation. For instance, +/// the comparison traits such as `PartialEq` or `PartialOrd` must behave +/// identical for `T` and any type implemeting `Borrow`. /// /// When writing generic code, a use of `Borrow` should always be justified /// by additional trait bounds, making it clear that the two types need to @@ -37,11 +46,13 @@ /// The companion trait [`BorrowMut`] provides the same guarantees for /// mutable references. /// -/// [`Box`]: ../../std/boxed/struct.Box.html -/// [`Rc`]: ../../std/rc/struct.Rc.html -/// [`Vec`]: ../../std/vec/struct.Vec.html /// [`AsRef`]: ../../std/convert/trait.AsRef.html /// [`BorrowMut`]: trait.BorrowMut.html +/// [`Box`]: ../../std/boxed/struct.Box.html +/// [`Mutex`]: ../../std/sync/struct.Mutex.html +/// [`Rc`]: ../../std/rc/struct.Rc.html +/// [`str`]: ../../std/primitive.str.html +/// [`String`]: ../../std/string/struct.String.html /// /// # Examples /// @@ -85,30 +96,34 @@ /// ``` /// /// The entire hash map is generic over a key type `K`. Because these keys -/// are stored by with the hash map, this type as to own the key’s data. +/// are stored with the hash map, this type has to own the key’s data. /// When inserting a key-value pair, the map is given such a `K` and needs /// to find the correct hash bucket and check if the key is already present /// based on that `K`. It therefore requires `K: Hash + Eq`. /// -/// In order to search for a value based on the key’s data, the `get` method -/// is generic over some type `Q`. Technically, it needs to convert that `Q` -/// into a `K` in order to use `K`’s [`Hash`] implementation to be able to -/// arrive at the same hash value as during insertion in order to look into -/// the right hash bucket. Since `K` is some kind of owned value, this likely -/// would involve cloning and isn’t really practical. +/// When searching for a value in the map, however, having to provide a +/// reference to a `K` as the key to search for would require to always +/// create such an owned value. For string keys, this would mean a `String` +/// value needs to be created just for the search for cases where only a +/// `str` is available. /// -/// Instead, `get` relies on `Q`’s implementation of `Hash` and uses `Borrow` -/// to indicate that `K`’s implementation of `Hash` must produce the same -/// result as `Q`’s by demanding that `K: Borrow`. +/// Instead, the `get` method is generic over the type of the underlying key +/// data, called `Q` in the method signature above. It states that `K` is a +/// representation of `Q` by requiring that `K: Borrow`. By additionally +/// requiring `Q: Hash + Eq`, it demands that `K` and `Q` have +/// implementations of the `Hash` and `Eq` traits that procude identical +/// results. +/// +/// The implementation of `get` relies in particular on identical +/// implementations of `Hash` by determining the key’s hash bucket by calling +/// `Hash::hash` on the `Q` value even though it inserted the key based on +/// the hash value calculated from the `K` value. /// /// As a consequence, the hash map breaks if a `K` wrapping a `Q` value /// produces a different hash than `Q`. For instance, imagine you have a /// type that wraps a string but compares ASCII letters ignoring their case: /// /// ``` -/// # #[allow(unused_imports)] -/// use std::ascii::AsciiExt; -/// /// pub struct CIString(String); /// /// impl PartialEq for CIString { @@ -124,7 +139,6 @@ /// implementation of `Hash` needs to reflect that, too: /// /// ``` -/// # #[allow(unused_imports)] use std::ascii::AsciiExt; /// # use std::hash::{Hash, Hasher}; /// # pub struct CIString(String); /// impl Hash for CIString { From f1c1fc2dbe442bedf214219d281b0d83b42cff67 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Wed, 14 Feb 2018 09:19:01 +0200 Subject: [PATCH 006/830] rephrase UnsafeCell doc Make UnsafeCell doc easier to follow --- src/libcore/cell.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index ec0d1b704dce..6270e87c9cce 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1164,11 +1164,12 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or /// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`, /// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way -/// to do this. When `UnsafeCell` is immutably aliased, it is still safe to obtain a mutable -/// reference to its interior and/or to mutate it. However, it is up to the abstraction designer -/// to ensure that no two mutable references obtained this way are active at the same time, and -/// that there are no active mutable references or mutations when an immutable reference is obtained -/// from the cell. This is often done via runtime checks. +/// to do this. When `UnsafeCell` _itself_ is immutably aliased, it is still safe to obtain +/// a mutable reference to its _interior_ and/or to mutate the interior. However, it is up to +/// the abstraction designer to ensure that no two mutable references obtained this way are active +/// at the same time, there are no active immutable reference when a mutable reference is obtained +/// from the cell, and that there are no active mutable references or mutations when an immutable +/// reference is obtained. This is often done via runtime checks. /// /// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell` is /// okay (provided you enforce the invariants some other way); it is still undefined behavior @@ -1240,9 +1241,9 @@ impl UnsafeCell { /// Gets a mutable pointer to the wrapped value. /// /// This can be cast to a pointer of any kind. - /// Ensure that the access is unique when casting to - /// `&mut T`, and ensure that there are no mutations or mutable - /// aliases going on when casting to `&T` + /// Ensure that the access is unique (no active references, mutable or not) + /// when casting to `&mut T`, and ensure that there are no mutations + /// or mutable aliases going on when casting to `&T` /// /// # Examples /// From b9b82490206fc41eb10662d6847a1ad28618ee59 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Wed, 14 Feb 2018 10:11:37 +0200 Subject: [PATCH 007/830] fix tidy checks --- src/libcore/cell.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 6270e87c9cce..6f91e743999b 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1165,7 +1165,7 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`, /// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way /// to do this. When `UnsafeCell` _itself_ is immutably aliased, it is still safe to obtain -/// a mutable reference to its _interior_ and/or to mutate the interior. However, it is up to +/// a mutable reference to its _interior_ and/or to mutate the interior. However, it is up to /// the abstraction designer to ensure that no two mutable references obtained this way are active /// at the same time, there are no active immutable reference when a mutable reference is obtained /// from the cell, and that there are no active mutable references or mutations when an immutable @@ -1243,7 +1243,7 @@ impl UnsafeCell { /// This can be cast to a pointer of any kind. /// Ensure that the access is unique (no active references, mutable or not) /// when casting to `&mut T`, and ensure that there are no mutations - /// or mutable aliases going on when casting to `&T` + /// or mutable aliases going on when casting to `&T` /// /// # Examples /// From 312e53d39f287551631b8f2e717452360e2d6786 Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Tue, 20 Feb 2018 16:34:49 +0000 Subject: [PATCH 008/830] Update RELEASES.md for 1.25.0 --- RELEASES.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 64e2145e0f37..aec2162dccd6 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,100 @@ +Version 1.25.0 (2018-03-29) +========================== + +Language +-------- +- [Stabilised `#[repr(align(x))]`.][47006] [RFC 1358] +- [You can now use nested groups of imports.][47948] + eg. `use std::{fs::File, io::Read, path::{Path, PathBuf}};` +- [You can now have `|` at the start of a match arm.][47947] eg. +```rust +enum Foo { A, B, C } + +fn main() { + let x = Foo::A; + match x { + | Foo::A + | Foo::B => println!("AB"), + | Foo::C => println!("C"), + } +} +``` + +Compiler +-------- +- [Upgraded to LLVM 6.][47828] +- [Added `-C lto=val` option.][47521] +- [Added `i586-unknown-linux-musl` target][47282] + +Libraries +--------- +- [Impl Send for `process::Command` on Unix.][47760] +- [Impl PartialEq and Eq for `ParseCharError`.][47790] +- [`UnsafeCell::into_inner` is now safe.][47204] +- [Implement libstd for CloudABI.][47268] +- [`Float::{from_bits, to_bits}` is now available in libcore.][46931] +- [renamed `ptr::Shared` to `ptr::NonNull`.][46952] +- [Implement `AsRef` for Component][46985] +- [Deprecated `[T]::rotate` in favor of `[T]::rotate_{left,right}`.][46777] +- [Implemented `Write` for `Cursor<&mut Vec>`][46830] +- [Moved `Duration` to libcore.][46666] + +Stabilized APIs +--------------- +- [`Location::column`] + +The following functions can now be used in a constant expression. +eg. `static MINUTE: Duration = Duration::from_secs(60);` +- [`Duration::new`][47300] +- [`Duration::from_secs`][47300] +- [`Duration::from_millis`][47300] +- [`Duration::from_micros`][47300] +- [`Duration::from_nanos`][47300] + +Cargo +----- +- [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013] +- [`cargo new` now defaults to creating a binary crate, instead of a + libary crate.][cargo/5029] + +Misc +---- + +Compatibility Notes +------------------- +- [Deprecated `net::lookup_host`.][47510] +- [`rustdoc` has switched to pulldown as the default markdown renderer.][47398] +- The borrow checker was sometimes incorrectly permitting overlapping borrows + around indexing operations (see #47349). This has been fixed (which also + enabled some correct code that used to cause errors (e.g. #33903 and #46095). +- [Removed deprecated unstable attribute `#[simd]`.][47251] + +[47947]: https://github.com/rust-lang/rust/pull/47947 +[47948]: https://github.com/rust-lang/rust/pull/47948 +[47760]: https://github.com/rust-lang/rust/pull/47760 +[47790]: https://github.com/rust-lang/rust/pull/47790 +[47828]: https://github.com/rust-lang/rust/pull/47828 +[47398]: https://github.com/rust-lang/rust/pull/47398 +[47510]: https://github.com/rust-lang/rust/pull/47510 +[47521]: https://github.com/rust-lang/rust/pull/47521 +[47204]: https://github.com/rust-lang/rust/pull/47204 +[47251]: https://github.com/rust-lang/rust/pull/47251 +[47268]: https://github.com/rust-lang/rust/pull/47268 +[47282]: https://github.com/rust-lang/rust/pull/47282 +[47300]: https://github.com/rust-lang/rust/pull/47300 +[46931]: https://github.com/rust-lang/rust/pull/46931 +[46952]: https://github.com/rust-lang/rust/pull/46952 +[46985]: https://github.com/rust-lang/rust/pull/46985 +[47006]: https://github.com/rust-lang/rust/pull/47006 +[46777]: https://github.com/rust-lang/rust/pull/46777 +[46830]: https://github.com/rust-lang/rust/pull/46830 +[46666]: https://github.com/rust-lang/rust/pull/46666 +[cargo/5013]: https://github.com/rust-lang/cargo/pull/5013 +[cargo/5029]: https://github.com/rust-lang/cargo/pull/5029 +[RFC 1358]: https://github.com/rust-lang/rfcs/pull/1358 +[`Location::column`]: https://doc.rust-lang.org/std/panic/struct.Location.html#method.column + + Version 1.24.0 (2018-02-15) ========================== From 1f3b626527ed71f70c0a6602895f677e1baf479c Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Tue, 20 Feb 2018 19:55:14 +0000 Subject: [PATCH 009/830] Update RELEASES.md --- RELEASES.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index aec2162dccd6..9ba5384602bb 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -33,15 +33,15 @@ Libraries - [`UnsafeCell::into_inner` is now safe.][47204] - [Implement libstd for CloudABI.][47268] - [`Float::{from_bits, to_bits}` is now available in libcore.][46931] -- [renamed `ptr::Shared` to `ptr::NonNull`.][46952] + - [Implement `AsRef` for Component][46985] -- [Deprecated `[T]::rotate` in favor of `[T]::rotate_{left,right}`.][46777] - [Implemented `Write` for `Cursor<&mut Vec>`][46830] - [Moved `Duration` to libcore.][46666] Stabilized APIs --------------- - [`Location::column`] +- [`ptr::NonNull`] The following functions can now be used in a constant expression. eg. `static MINUTE: Duration = Duration::from_secs(60);` @@ -65,10 +65,11 @@ Compatibility Notes - [Deprecated `net::lookup_host`.][47510] - [`rustdoc` has switched to pulldown as the default markdown renderer.][47398] - The borrow checker was sometimes incorrectly permitting overlapping borrows - around indexing operations (see #47349). This has been fixed (which also - enabled some correct code that used to cause errors (e.g. #33903 and #46095). + around indexing operations (see [#47349][47349]). This has been fixed (which also + enabled some correct code that used to cause errors (e.g. [#33903][33903] and [#46095][46095]). - [Removed deprecated unstable attribute `#[simd]`.][47251] +[33903]: https://github.com/rust-lang/rust/pull/33903 [47947]: https://github.com/rust-lang/rust/pull/47947 [47948]: https://github.com/rust-lang/rust/pull/47948 [47760]: https://github.com/rust-lang/rust/pull/47760 @@ -82,17 +83,18 @@ Compatibility Notes [47268]: https://github.com/rust-lang/rust/pull/47268 [47282]: https://github.com/rust-lang/rust/pull/47282 [47300]: https://github.com/rust-lang/rust/pull/47300 +[47349]: https://github.com/rust-lang/rust/pull/47349 [46931]: https://github.com/rust-lang/rust/pull/46931 -[46952]: https://github.com/rust-lang/rust/pull/46952 [46985]: https://github.com/rust-lang/rust/pull/46985 [47006]: https://github.com/rust-lang/rust/pull/47006 -[46777]: https://github.com/rust-lang/rust/pull/46777 [46830]: https://github.com/rust-lang/rust/pull/46830 +[46095]: https://github.com/rust-lang/rust/pull/46095 [46666]: https://github.com/rust-lang/rust/pull/46666 [cargo/5013]: https://github.com/rust-lang/cargo/pull/5013 [cargo/5029]: https://github.com/rust-lang/cargo/pull/5029 [RFC 1358]: https://github.com/rust-lang/rfcs/pull/1358 [`Location::column`]: https://doc.rust-lang.org/std/panic/struct.Location.html#method.column +[`ptr::NonNull`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html Version 1.24.0 (2018-02-15) From acc1b6dc99e6b9bef412024ed0803dd08f33c1c8 Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Thu, 22 Feb 2018 13:29:37 +0000 Subject: [PATCH 010/830] Update RELEASES.md --- RELEASES.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 9ba5384602bb..1b2097144d71 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -5,8 +5,8 @@ Language -------- - [Stabilised `#[repr(align(x))]`.][47006] [RFC 1358] - [You can now use nested groups of imports.][47948] - eg. `use std::{fs::File, io::Read, path::{Path, PathBuf}};` -- [You can now have `|` at the start of a match arm.][47947] eg. + e.g. `use std::{fs::File, io::Read, path::{Path, PathBuf}};` +- [You can now have `|` at the start of a match arm.][47947] e.g. ```rust enum Foo { A, B, C } @@ -55,7 +55,7 @@ Cargo ----- - [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013] - [`cargo new` now defaults to creating a binary crate, instead of a - libary crate.][cargo/5029] + library crate.][cargo/5029] Misc ---- From cfad25ee8fb9866d0cbdc43e3a89a00aed13e12c Mon Sep 17 00:00:00 2001 From: jethrogb Date: Fri, 23 Feb 2018 11:57:38 -0800 Subject: [PATCH 011/830] Clarify interfaction between File::set_len and file cursor --- src/libstd/fs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 292a78278ab0..db52ed67d3a8 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -453,6 +453,10 @@ impl File { /// will be extended to `size` and have all of the intermediate data filled /// in with 0s. /// + /// The file's cursor isn't changed. In particular, if the cursor was at the + /// end and the file is shrunk using this operation, the cursor will now be + /// past the end. + /// /// # Errors /// /// This function will return an error if the file is not opened for writing. From 273166e7655dc736f444de43505c3ddda5c742f7 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Tue, 27 Feb 2018 16:41:28 +0200 Subject: [PATCH 012/830] remove italic remove italic as per @GuillaumeGomez suggestion --- src/libcore/cell.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 6f91e743999b..4a1d68efc99b 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1164,8 +1164,8 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or /// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`, /// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way -/// to do this. When `UnsafeCell` _itself_ is immutably aliased, it is still safe to obtain -/// a mutable reference to its _interior_ and/or to mutate the interior. However, it is up to +/// to do this. When `UnsafeCell` itself is immutably aliased, it is still safe to obtain +/// a mutable reference to its interior and/or to mutate the interior. However, it is up to /// the abstraction designer to ensure that no two mutable references obtained this way are active /// at the same time, there are no active immutable reference when a mutable reference is obtained /// from the cell, and that there are no active mutable references or mutations when an immutable From 44be054a2acbeeb682d02a5f88ddedc0cb5c9bf2 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Tue, 27 Feb 2018 16:24:52 +0100 Subject: [PATCH 013/830] Further refinement of Borrow documentation. --- src/libcore/borrow.rs | 68 +++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 1f692d019c3d..c0f1989f8794 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -17,36 +17,41 @@ /// In Rust, it is common to provide different representations of a type for /// different use cases. For instance, storage location and management for a /// value can be specifically chosen as appropriate for a particular use via -/// pointer types such as [`Box`] or [`Rc`] or one can opt into -/// concurrency via synchronization types such as [`Mutex`], avoiding the -/// associated cost when in parallel doesn’t happen. Beyond these generic +/// pointer types such as [`Box`] or [`Rc`]. Beyond these generic /// wrappers that can be used with any type, some types provide optional /// facets providing potentially costly functionality. An example for such a /// type is [`String`] which adds the ability to extend a string to the basic /// [`str`]. This requires keeping additional information unnecessary for a -/// simple, imutable string. +/// simple, immutable string. /// /// These types signal that they are a specialized representation of a basic /// type `T` by implementing `Borrow`. The method `borrow` provides a way -/// to convert a reference to the type into a reference to the underlying -/// basic type. +/// to convert a reference to the type into a reference to this basic type +/// `T`. /// -/// If a type implementing `Borrow` implements other traits also -/// implemented by `T`, these implementations behave identically if the trait -/// is concerned with the data rather than its representation. For instance, -/// the comparison traits such as `PartialEq` or `PartialOrd` must behave -/// identical for `T` and any type implemeting `Borrow`. +/// Further, when providing implementations for additional traits, it needs +/// to be considered whether they should behave identical to those of the +/// underlying type as a consequence of acting as a representation of that +/// underlying type. /// -/// When writing generic code, a use of `Borrow` should always be justified -/// by additional trait bounds, making it clear that the two types need to -/// behave identically in a certain context. If the code should merely be -/// able to operate on any type that can produce a reference to a given type, -/// you should use [`AsRef`] instead. +/// Generic code typically uses `Borrow` when it not only needs access +/// to a reference of the underlying type but relies on the identical +/// behavior of these additional trait implementations. These traits are +/// likely to appear as additional trait bounds. /// -/// The companion trait [`BorrowMut`] provides the same guarantees for -/// mutable references. +/// If generic code merely needs to work for all types that can +/// provide a reference to related type `T`, it is often better to use +/// [`AsRef`] as more types can safely implement it. /// -/// [`AsRef`]: ../../std/convert/trait.AsRef.html +/// If a type implementing `Borrow` also wishes to allow mutable access +/// to the underlying type `T`, it can do so by implementing the companion +/// trait [`BorrowMut`]. +/// +/// Note also that it is perfectly fine for a single type to have multiple +/// implementations of `Borrow` for different `T`s. In fact, a blanket +/// implementation lets every type be at least a borrow of itself. +/// +/// [`AsRef`]: ../../std/convert/trait.AsRef.html /// [`BorrowMut`]: trait.BorrowMut.html /// [`Box`]: ../../std/boxed/struct.Box.html /// [`Mutex`]: ../../std/sync/struct.Mutex.html @@ -111,7 +116,7 @@ /// data, called `Q` in the method signature above. It states that `K` is a /// representation of `Q` by requiring that `K: Borrow`. By additionally /// requiring `Q: Hash + Eq`, it demands that `K` and `Q` have -/// implementations of the `Hash` and `Eq` traits that procude identical +/// implementations of the `Hash` and `Eq` traits that produce identical /// results. /// /// The implementation of `get` relies in particular on identical @@ -124,15 +129,15 @@ /// type that wraps a string but compares ASCII letters ignoring their case: /// /// ``` -/// pub struct CIString(String); +/// pub struct CaseInsensitiveString(String); /// -/// impl PartialEq for CIString { +/// impl PartialEq for CaseInsensitiveString { /// fn eq(&self, other: &Self) -> bool { /// self.0.eq_ignore_ascii_case(&other.0) /// } /// } /// -/// impl Eq for CIString { } +/// impl Eq for CaseInsensitiveString { } /// ``` /// /// Because two equal values need to produce the same hash value, the @@ -140,8 +145,8 @@ /// /// ``` /// # use std::hash::{Hash, Hasher}; -/// # pub struct CIString(String); -/// impl Hash for CIString { +/// # pub struct CaseInsensitiveString(String); +/// impl Hash for CaseInsensitiveString { /// fn hash(&self, state: &mut H) { /// for c in self.0.as_bytes() { /// c.to_ascii_lowercase().hash(state) @@ -150,13 +155,12 @@ /// } /// ``` /// -/// Can `CIString` implement `Borrow`? It certainly can provide a -/// reference to a string slice via its contained owned string. But because -/// its `Hash` implementation differs, it cannot fulfill the guarantee for -/// `Borrow` that all common trait implementations must behave the same way -/// and must not, in fact, implement `Borrow`. If it wants to allow -/// others access to the underlying `str`, it can do that via `AsRef` -/// which doesn’t carry any such restrictions. +/// Can `CaseInsensitiveString` implement `Borrow`? It certainly can +/// provide a reference to a string slice via its contained owned string. +/// But because its `Hash` implementation differs, it behaves differently +/// from `str` and therefore must not, in fact, implement `Borrow`. +/// If it wants to allow others access to the underlying `str`, it can do +/// that via `AsRef` which doesn’t carry any extra requirements. /// /// [`Hash`]: ../../std/hash/trait.Hash.html /// [`HashMap`]: ../../std/collections/struct.HashMap.html From d9b8724a8072d51c014d2d8c6852e5a398c757d3 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Tue, 27 Feb 2018 23:21:04 +0200 Subject: [PATCH 014/830] style fix --- src/libcore/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 4a1d68efc99b..01e618421cc5 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1172,7 +1172,7 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// reference is obtained. This is often done via runtime checks. /// /// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell` is -/// okay (provided you enforce the invariants some other way); it is still undefined behavior +/// okay (provided you enforce the invariants some other way), it is still undefined behavior /// to have multiple `&mut UnsafeCell` aliases. /// /// From 50f5ea919231b41b7d8ccb1023b4dc0fd6e6730d Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Tue, 27 Feb 2018 23:23:19 +0200 Subject: [PATCH 015/830] Simplify Merge three rules into one following @cramertj --- src/libcore/cell.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 01e618421cc5..b57667df9916 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1165,11 +1165,15 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`, /// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way /// to do this. When `UnsafeCell` itself is immutably aliased, it is still safe to obtain -/// a mutable reference to its interior and/or to mutate the interior. However, it is up to -/// the abstraction designer to ensure that no two mutable references obtained this way are active -/// at the same time, there are no active immutable reference when a mutable reference is obtained -/// from the cell, and that there are no active mutable references or mutations when an immutable -/// reference is obtained. This is often done via runtime checks. +/// a mutable reference to its interior and/or to mutate the interior. However, the abstraction +/// designer must ensure that any active mutable references to the interior obtained this way does +/// not co-exist with other active references to the interior, either mutable or not. This is often +/// done via runtime checks. Naturally, several active immutable references to the interior can +/// co-exits with each other (but not with a mutable reference). +/// +/// To put it in other words, if a mutable reference to the contents is active, no other references +/// can be active at the same time, and if an immutable reference to the contents is active, then +/// only other immutable reference may be active. /// /// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell` is /// okay (provided you enforce the invariants some other way), it is still undefined behavior From ff6754c68ec293d46eb294f3b7efeca8300b2251 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Tue, 27 Feb 2018 23:34:38 +0200 Subject: [PATCH 016/830] fix tidy checks --- src/libcore/cell.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index b57667df9916..6f18b8466a66 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1166,12 +1166,12 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way /// to do this. When `UnsafeCell` itself is immutably aliased, it is still safe to obtain /// a mutable reference to its interior and/or to mutate the interior. However, the abstraction -/// designer must ensure that any active mutable references to the interior obtained this way does -/// not co-exist with other active references to the interior, either mutable or not. This is often +/// designer must ensure that any active mutable references to the interior obtained this way does +/// not co-exist with other active references to the interior, either mutable or not. This is often /// done via runtime checks. Naturally, several active immutable references to the interior can /// co-exits with each other (but not with a mutable reference). /// -/// To put it in other words, if a mutable reference to the contents is active, no other references +/// To put it in other words, if a mutable reference to the contents is active, no other references /// can be active at the same time, and if an immutable reference to the contents is active, then /// only other immutable reference may be active. /// From 78789add6c4ab8a4b81e717803be63c384438595 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Tue, 27 Feb 2018 23:52:47 +0200 Subject: [PATCH 017/830] and some more tidy checks --- src/libcore/cell.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 6f18b8466a66..8accbc204c1d 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1168,12 +1168,12 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// a mutable reference to its interior and/or to mutate the interior. However, the abstraction /// designer must ensure that any active mutable references to the interior obtained this way does /// not co-exist with other active references to the interior, either mutable or not. This is often -/// done via runtime checks. Naturally, several active immutable references to the interior can +/// done via runtime checks. Naturally, several active immutable references to the interior can /// co-exits with each other (but not with a mutable reference). /// /// To put it in other words, if a mutable reference to the contents is active, no other references /// can be active at the same time, and if an immutable reference to the contents is active, then -/// only other immutable reference may be active. +/// only other immutable reference may be active. /// /// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell` is /// okay (provided you enforce the invariants some other way), it is still undefined behavior From 518b3f7eeed94027673b55b6f459a22983ac542f Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 28 Feb 2018 15:33:36 -0800 Subject: [PATCH 018/830] Update libc to bring in posix_spawn bindings for FreeBSD. --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liblibc b/src/liblibc index 56444a4545bd..8bed48a75156 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 56444a4545bd71430d64b86b8a71714cfdbe9f5d +Subproject commit 8bed48a751562c1c396b361bb6940c677268e997 From 11696acd6d070a90e8dd386a3c9ae877740fb0e2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 Jan 2018 18:13:45 -0800 Subject: [PATCH 019/830] Support posix_spawn() when possible. --- src/libstd/sys/unix/process/process_unix.rs | 102 ++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 189280a4ba9a..d66c2375140c 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -24,6 +24,7 @@ impl Command { -> io::Result<(Process, StdioPipes)> { use sys; + const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX"; let envp = self.capture_env(); @@ -34,6 +35,11 @@ impl Command { } let (ours, theirs) = self.setup_io(default, needs_stdin)?; + + if let Some(ret) = self.posix_spawn(&theirs, envp.as_ref())? { + return Ok((ret, ours)) + } + let (input, output) = sys::pipe::anon_pipe()?; let pid = unsafe { @@ -229,6 +235,102 @@ impl Command { libc::execvp(self.get_argv()[0], self.get_argv().as_ptr()); io::Error::last_os_error() } + + #[cfg(not(any(target_os = "linux", target_os = "macos")))] + fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) + -> io::Result> + { + Ok(None) + } + + #[cfg(any(target_os = "linux", target_os = "macos"))] + fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) + -> io::Result> + { + use mem; + use sys; + + if self.get_cwd().is_some() || + self.get_gid().is_some() || + self.get_uid().is_some() || + self.get_closures().len() != 0 { + return Ok(None) + } + + let mut p = Process { pid: 0, status: None }; + + struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t); + + impl Drop for PosixSpawnFileActions { + fn drop(&mut self) { + unsafe { + libc::posix_spawn_file_actions_destroy(&mut self.0); + } + } + } + + struct PosixSpawnattr(libc::posix_spawnattr_t); + + impl Drop for PosixSpawnattr { + fn drop(&mut self) { + unsafe { + libc::posix_spawnattr_destroy(&mut self.0); + } + } + } + + unsafe { + let mut file_actions = PosixSpawnFileActions(mem::zeroed()); + let mut attrs = PosixSpawnattr(mem::zeroed()); + + libc::posix_spawnattr_init(&mut attrs.0); + libc::posix_spawn_file_actions_init(&mut file_actions.0); + + if let Some(fd) = stdio.stdin.fd() { + cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + fd, + libc::STDIN_FILENO))?; + } + if let Some(fd) = stdio.stdout.fd() { + cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + fd, + libc::STDOUT_FILENO))?; + } + if let Some(fd) = stdio.stderr.fd() { + cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0, + fd, + libc::STDERR_FILENO))?; + } + + let mut set: libc::sigset_t = mem::zeroed(); + cvt(libc::sigemptyset(&mut set))?; + cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0, + &set))?; + cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?; + cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0, + &set))?; + + let flags = libc::POSIX_SPAWN_SETSIGDEF | + libc::POSIX_SPAWN_SETSIGMASK; + cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?; + + let envp = envp.map(|c| c.as_ptr()) + .unwrap_or(sys::os::environ() as *const _); + let ret = libc::posix_spawnp( + &mut p.pid, + self.get_argv()[0], + &file_actions.0, + &attrs.0, + self.get_argv().as_ptr() as *const _, + envp as *const _, + ); + if ret == 0 { + Ok(Some(p)) + } else { + Err(io::Error::last_os_error()) + } + } + } } //////////////////////////////////////////////////////////////////////////////// From f4633865d37dea15a88220e886e77839aa1fd1ba Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 17:33:44 -0800 Subject: [PATCH 020/830] Avoid error for unused variables --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index d66c2375140c..05b4b9b085b4 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -237,7 +237,7 @@ impl Command { } #[cfg(not(any(target_os = "linux", target_os = "macos")))] - fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) + fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) -> io::Result> { Ok(None) From 94630e4ca509f9b37e4c066eee94f40da12cba51 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 20:23:46 -0800 Subject: [PATCH 021/830] No need to zero when an initializer for the object is already used. --- src/libstd/sys/unix/process/process_unix.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 05b4b9b085b4..b394d5ff41aa 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -280,8 +280,8 @@ impl Command { } unsafe { - let mut file_actions = PosixSpawnFileActions(mem::zeroed()); - let mut attrs = PosixSpawnattr(mem::zeroed()); + let mut file_actions = PosixSpawnFileActions(mem::uninitialized()); + let mut attrs = PosixSpawnattr(mem::uninitialized()); libc::posix_spawnattr_init(&mut attrs.0); libc::posix_spawn_file_actions_init(&mut file_actions.0); @@ -302,7 +302,7 @@ impl Command { libc::STDERR_FILENO))?; } - let mut set: libc::sigset_t = mem::zeroed(); + let mut set: libc::sigset_t = mem::uninitialized(); cvt(libc::sigemptyset(&mut set))?; cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0, &set))?; From 8e3fa0d3c450051d6445aa82682416eb307b2d5b Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 23:51:19 -0800 Subject: [PATCH 022/830] Pass proper pointer for envp. --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index b394d5ff41aa..9765ff37e9b7 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -315,7 +315,7 @@ impl Command { cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?; let envp = envp.map(|c| c.as_ptr()) - .unwrap_or(sys::os::environ() as *const _); + .unwrap_or(*sys::os::environ() as *const _); let ret = libc::posix_spawnp( &mut p.pid, self.get_argv()[0], From b3ecf5f57ca9d34d10ffd9d064a027ce3f4888ac Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 26 Feb 2018 23:51:39 -0800 Subject: [PATCH 023/830] Remove excess newline --- src/libstd/sys/unix/process/process_unix.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 9765ff37e9b7..fa66245abb6d 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -24,7 +24,6 @@ impl Command { -> io::Result<(Process, StdioPipes)> { use sys; - const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX"; let envp = self.capture_env(); From 85b82f254e28f5e50b25d8e096af0f01e4441ef7 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Tue, 27 Feb 2018 14:12:52 -0800 Subject: [PATCH 024/830] Support posix_spawn() for FreeBSD. spawn() is expected to return an error if the specified file could not be executed. FreeBSD's posix_spawn() supports returning ENOENT/ENOEXEC if the exec() fails, which not all platforms support. This brings a very significant performance improvement for FreeBSD, involving heavy use of Command in threads, due to fork() invoking jemalloc fork handlers and causing lock contention. FreeBSD's posix_spawn() avoids this problem due to using vfork() internally. --- src/libstd/sys/unix/process/process_unix.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index fa66245abb6d..c7841a861ceb 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -235,14 +235,14 @@ impl Command { io::Error::last_os_error() } - #[cfg(not(any(target_os = "linux", target_os = "macos")))] + #[cfg(not(any(target_os = "freebsd")))] fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) -> io::Result> { Ok(None) } - #[cfg(any(target_os = "linux", target_os = "macos"))] + #[cfg(any(target_os = "freebsd"))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> { From e6efd0d640742ed4a2fbd32fe79fb743772838cc Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 28 Feb 2018 19:09:59 -0800 Subject: [PATCH 025/830] Add a specific test for spawn() returning ENOENT --- .../run-pass/process-spawn-nonexistent.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/run-pass/process-spawn-nonexistent.rs diff --git a/src/test/run-pass/process-spawn-nonexistent.rs b/src/test/run-pass/process-spawn-nonexistent.rs new file mode 100644 index 000000000000..9219cd625f30 --- /dev/null +++ b/src/test/run-pass/process-spawn-nonexistent.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-cloudabi no processes +// ignore-emscripten no processes + +use std::io::ErrorKind; +use std::process::Command; + +fn main() { + assert_eq!(Command::new("nonexistent") + .spawn() + .unwrap_err() + .kind(), + ErrorKind::NotFound); +} From a9ea876960a06f3ae00049515bf9ef706cca806b Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 28 Feb 2018 22:16:35 -0800 Subject: [PATCH 026/830] posix_spawn() always returns its error rather than setting errno. --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index c7841a861ceb..c5dda6273efa 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -326,7 +326,7 @@ impl Command { if ret == 0 { Ok(Some(p)) } else { - Err(io::Error::last_os_error()) + Err(io::Error::from_raw_os_error(ret)) } } } From 55cc9a43368aae6e6ed3a0c75ee8fd47ac4f3bcd Mon Sep 17 00:00:00 2001 From: Peter Lyons Date: Wed, 28 Feb 2018 20:51:40 -0700 Subject: [PATCH 027/830] Remember state of top-level collapse toggle widget --- src/librustdoc/html/static/main.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 960f2f198d8b..4f90b86a3f7a 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1623,6 +1623,7 @@ function toggleAllDocs() { var toggle = document.getElementById("toggle-all-docs"); if (hasClass(toggle, "will-expand")) { + updateLocalStorage("collapse", "false"); removeClass(toggle, "will-expand"); onEveryMatchingChild(toggle, "inner", function(e) { e.innerHTML = labelForToggleButton(false); @@ -1632,6 +1633,7 @@ collapseDocs(e, "show"); }); } else { + updateLocalStorage("collapse", "true"); addClass(toggle, "will-expand"); onEveryMatchingChild(toggle, "inner", function(e) { e.innerHTML = labelForToggleButton(true); @@ -1972,6 +1974,10 @@ window.onresize = function() { hideSidebar(); }; + + if (getCurrentValue("collapse") === "true") { + toggleAllDocs(); + } }()); // Sets the focus on the search bar at the top of the page From 2dd81c86c51435ed57d7a2b16f1b66c254a64cc8 Mon Sep 17 00:00:00 2001 From: Peter Lyons Date: Thu, 1 Mar 2018 02:50:32 -0700 Subject: [PATCH 028/830] Rename doc collapse sentinal to rustdoc-collapse --- 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 4f90b86a3f7a..c5c31d109fbf 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1623,7 +1623,7 @@ function toggleAllDocs() { var toggle = document.getElementById("toggle-all-docs"); if (hasClass(toggle, "will-expand")) { - updateLocalStorage("collapse", "false"); + updateLocalStorage("rustdoc-collapse", "false"); removeClass(toggle, "will-expand"); onEveryMatchingChild(toggle, "inner", function(e) { e.innerHTML = labelForToggleButton(false); @@ -1633,7 +1633,7 @@ collapseDocs(e, "show"); }); } else { - updateLocalStorage("collapse", "true"); + updateLocalStorage("rustdoc-collapse", "true"); addClass(toggle, "will-expand"); onEveryMatchingChild(toggle, "inner", function(e) { e.innerHTML = labelForToggleButton(true); @@ -1975,7 +1975,7 @@ hideSidebar(); }; - if (getCurrentValue("collapse") === "true") { + if (getCurrentValue("rustdoc-collapse") === "true") { toggleAllDocs(); } }()); From 2e2d9260f9425cd700199383096d8201190737de Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 1 Mar 2018 09:17:49 -0800 Subject: [PATCH 029/830] posix_spawn() on OSX supports returning ENOENT. --- src/libstd/sys/unix/process/process_unix.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index c5dda6273efa..dcf0278b4aaa 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -235,14 +235,14 @@ impl Command { io::Error::last_os_error() } - #[cfg(not(any(target_os = "freebsd")))] + #[cfg(not(any(target_os = "macos", target_os = "freebsd")))] fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) -> io::Result> { Ok(None) } - #[cfg(any(target_os = "freebsd"))] + #[cfg(any(target_os = "macos", target_os = "freebsd"))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> { From ef73b3ae2eac3a03f5b966a4f8b2a568e3619d51 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 1 Mar 2018 09:18:16 -0800 Subject: [PATCH 030/830] Add comment explaining when posix_spawn() can be supported. --- src/libstd/sys/unix/process/process_unix.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index dcf0278b4aaa..bd6a8d3f64be 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -242,6 +242,8 @@ impl Command { Ok(None) } + // Only support platforms for which posix_spawn() can return ENOENT + // directly. #[cfg(any(target_os = "macos", target_os = "freebsd"))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> From 99b50efb6eb048297cda699ad017821822591d7a Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Fri, 2 Mar 2018 08:50:37 -0800 Subject: [PATCH 031/830] Use _ --- src/libstd/sys/unix/process/process_unix.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index bd6a8d3f64be..51ae0aa73159 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -236,7 +236,7 @@ impl Command { } #[cfg(not(any(target_os = "macos", target_os = "freebsd")))] - fn posix_spawn(&mut self, _stdio: &ChildPipes, _envp: Option<&CStringArray>) + fn posix_spawn(&mut self, _: &ChildPipes, _: Option<&CStringArray>) -> io::Result> { Ok(None) From 5ba6b3a728fb50cd65237b8eeac2f2df05c3c77f Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Fri, 2 Mar 2018 12:50:07 -0800 Subject: [PATCH 032/830] Move glibc version lookup handling to sys::os and add a simpler glibc_version() --- src/libstd/sys/unix/net.rs | 33 +++++---------------------------- src/libstd/sys/unix/os.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs index 3f65975e6088..04d9f0b06d34 100644 --- a/src/libstd/sys/unix/net.rs +++ b/src/libstd/sys/unix/net.rs @@ -383,12 +383,12 @@ impl IntoInner for Socket { // believe it's thread-safe). #[cfg(target_env = "gnu")] fn on_resolver_failure() { + use sys; + // If the version fails to parse, we treat it the same as "not glibc". - if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) { - if let Some(version) = parse_glibc_version(version_str) { - if version < (2, 26) { - unsafe { libc::res_init() }; - } + if let Some(version) = sys::os::glibc_version() { + if version < (2, 26) { + unsafe { libc::res_init() }; } } } @@ -396,29 +396,6 @@ fn on_resolver_failure() { #[cfg(not(target_env = "gnu"))] fn on_resolver_failure() {} -#[cfg(target_env = "gnu")] -fn glibc_version_cstr() -> Option<&'static CStr> { - weak! { - fn gnu_get_libc_version() -> *const libc::c_char - } - if let Some(f) = gnu_get_libc_version.get() { - unsafe { Some(CStr::from_ptr(f())) } - } else { - None - } -} - -// Returns Some((major, minor)) if the string is a valid "x.y" version, -// ignoring any extra dot-separated parts. Otherwise return None. -#[cfg(target_env = "gnu")] -fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { - let mut parsed_ints = version.split(".").map(str::parse::).fuse(); - match (parsed_ints.next(), parsed_ints.next()) { - (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)), - _ => None - } -} - #[cfg(all(test, taget_env = "gnu"))] mod test { use super::*; diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index a46e855b4a6f..4c86fddee4b4 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -546,3 +546,35 @@ pub fn getpid() -> u32 { pub fn getppid() -> u32 { unsafe { libc::getppid() as u32 } } + +#[cfg(target_env = "gnu")] +pub fn glibc_version() -> Option<(usize, usize)> { + if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) { + parse_glibc_version(version_str) + } else { + None + } +} + +#[cfg(target_env = "gnu")] +fn glibc_version_cstr() -> Option<&'static CStr> { + weak! { + fn gnu_get_libc_version() -> *const libc::c_char + } + if let Some(f) = gnu_get_libc_version.get() { + unsafe { Some(CStr::from_ptr(f())) } + } else { + None + } +} + +// Returns Some((major, minor)) if the string is a valid "x.y" version, +// ignoring any extra dot-separated parts. Otherwise return None. +#[cfg(target_env = "gnu")] +fn parse_glibc_version(version: &str) -> Option<(usize, usize)> { + let mut parsed_ints = version.split(".").map(str::parse::).fuse(); + match (parsed_ints.next(), parsed_ints.next()) { + (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)), + _ => None + } +} From d740083fc8981ee933dc48a6b3dcee21b82c993e Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Fri, 2 Mar 2018 13:02:38 -0800 Subject: [PATCH 033/830] Support posix_spawn() for Linux glibc 2.24+. The relevant support was added in https://sourceware.org/bugzilla/show_bug.cgi?id=10354#c12 --- src/libstd/sys/unix/process/process_unix.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 51ae0aa73159..29e33ee822ee 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -235,7 +235,8 @@ impl Command { io::Error::last_os_error() } - #[cfg(not(any(target_os = "macos", target_os = "freebsd")))] + #[cfg(not(any(target_os = "macos", target_os = "freebsd", + all(target_os = "linux", target_env = "gnu"))))] fn posix_spawn(&mut self, _: &ChildPipes, _: Option<&CStringArray>) -> io::Result> { @@ -244,7 +245,8 @@ impl Command { // Only support platforms for which posix_spawn() can return ENOENT // directly. - #[cfg(any(target_os = "macos", target_os = "freebsd"))] + #[cfg(any(target_os = "macos", target_os = "freebsd", + all(target_os = "linux", target_env = "gnu")))] fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>) -> io::Result> { @@ -258,6 +260,18 @@ impl Command { return Ok(None) } + // Only glibc 2.24+ posix_spawn() supports returning ENOENT directly. + #[cfg(all(target_os = "linux", target_env = "gnu"))] + { + if let Some(version) = sys::os::glibc_version() { + if version < (2, 24) { + return Ok(None) + } + } else { + return Ok(None) + } + } + let mut p = Process { pid: 0, status: None }; struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t); From f9c5b1f8e8fbc9c6d8e4b69ecbef6345a73ce515 Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Sat, 3 Mar 2018 11:12:09 -0800 Subject: [PATCH 034/830] Update Feature Request instructions --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 552961b9b66c..2b389888e518 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,10 +26,10 @@ As a reminder, all contributors are expected to follow our [Code of Conduct][coc ## Feature Requests [feature-requests]: #feature-requests -To request a change to the way that the Rust language works, please open an -issue in the [RFCs repository](https://github.com/rust-lang/rfcs/issues/new) -rather than this one. New features and other significant language changes -must go through the RFC process. +To request a change to the way the Rust language works, please head over +to the [RFCs repository](https://github.com/rust-lang/rfcs) and view the +[README](https://github.com/rust-lang/rfcs/blob/master/README.md) +for instructions. ## Bug Reports [bug-reports]: #bug-reports From 4e4c1b5b325c4c474426a7e3c346c316fbc644f1 Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Sun, 4 Mar 2018 13:33:34 -0500 Subject: [PATCH 035/830] Added `ascii` module to core --- src/libcore/ascii.rs | 499 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 499 insertions(+) create mode 100644 src/libcore/ascii.rs diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs new file mode 100644 index 000000000000..e7bee41ac348 --- /dev/null +++ b/src/libcore/ascii.rs @@ -0,0 +1,499 @@ +// Copyright 2013-2014 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. + +//! Operations on ASCII strings and characters. +//! +//! Most string operations in Rust act on UTF-8 strings. However, at times it +//! makes more sense to only consider the ASCII character set for a specific +//! operation. +//! +//! The [`escape_default`] function provides an iterator over the bytes of an +//! escaped version of the character given. +//! +//! [`escape_default`]: fn.escape_default.html + +#![stable(feature = "rust1", since = "1.0.0")] + +use fmt; +use ops::Range; +use iter::FusedIterator; + +/// An iterator over the escaped version of a byte. +/// +/// This `struct` is created by the [`escape_default`] function. See its +/// documentation for more. +/// +/// [`escape_default`]: fn.escape_default.html +#[unstable(feature = "core_ascii", issue = "46409")] +pub struct EscapeDefault { + range: Range, + data: [u8; 4], +} + +/// Returns an iterator that produces an escaped version of a `u8`. +/// +/// The default is chosen with a bias toward producing literals that are +/// legal in a variety of languages, including C++11 and similar C-family +/// languages. The exact rules are: +/// +/// * Tab is escaped as `\t`. +/// * Carriage return is escaped as `\r`. +/// * Line feed is escaped as `\n`. +/// * Single quote is escaped as `\'`. +/// * Double quote is escaped as `\"`. +/// * Backslash is escaped as `\\`. +/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e` +/// inclusive is not escaped. +/// * Any other chars are given hex escapes of the form '\xNN'. +/// * Unicode escapes are never generated by this function. +/// +/// # Examples +/// +/// ``` +/// let escaped = ascii::escape_default(b'0').next().unwrap(); +/// assert_eq!(b'0', escaped); +/// +/// let mut escaped = ascii::escape_default(b'\t'); +/// +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// assert_eq!(b't', escaped.next().unwrap()); +/// +/// let mut escaped = ascii::escape_default(b'\r'); +/// +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// assert_eq!(b'r', escaped.next().unwrap()); +/// +/// let mut escaped = ascii::escape_default(b'\n'); +/// +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// assert_eq!(b'n', escaped.next().unwrap()); +/// +/// let mut escaped = ascii::escape_default(b'\''); +/// +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// assert_eq!(b'\'', escaped.next().unwrap()); +/// +/// let mut escaped = ascii::escape_default(b'"'); +/// +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// assert_eq!(b'"', escaped.next().unwrap()); +/// +/// let mut escaped = ascii::escape_default(b'\\'); +/// +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// +/// let mut escaped = ascii::escape_default(b'\x9d'); +/// +/// assert_eq!(b'\\', escaped.next().unwrap()); +/// assert_eq!(b'x', escaped.next().unwrap()); +/// assert_eq!(b'9', escaped.next().unwrap()); +/// assert_eq!(b'd', escaped.next().unwrap()); +/// ``` +#[unstable(feature = "core_ascii", issue = "46409")] +pub fn escape_ascii(c: u8) -> EscapeDefault { + let (data, len) = match c { + b'\t' => ([b'\\', b't', 0, 0], 2), + b'\r' => ([b'\\', b'r', 0, 0], 2), + b'\n' => ([b'\\', b'n', 0, 0], 2), + b'\\' => ([b'\\', b'\\', 0, 0], 2), + b'\'' => ([b'\\', b'\'', 0, 0], 2), + b'"' => ([b'\\', b'"', 0, 0], 2), + b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1), + _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4), + }; + + return EscapeDefault { range: 0..len, data }; + + fn hexify(b: u8) -> u8 { + match b { + 0 ... 9 => b'0' + b, + _ => b'a' + b - 10, + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for EscapeDefault { + type Item = u8; + fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } + fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for EscapeDefault { + fn next_back(&mut self) -> Option { + self.range.next_back().map(|i| self.data[i]) + } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for EscapeDefault {} +#[unstable(feature = "fused", issue = "35602")] +impl FusedIterator for EscapeDefault {} + +#[stable(feature = "std_debug", since = "1.16.0")] +impl fmt::Debug for EscapeDefault { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("EscapeDefault { .. }") + } +} + + +#[cfg(test)] +mod tests { + use char::from_u32; + + #[test] + fn test_is_ascii() { + assert!(b"".is_ascii()); + assert!(b"banana\0\x7F".is_ascii()); + assert!(b"banana\0\x7F".iter().all(|b| b.is_ascii())); + assert!(!b"Vi\xe1\xbb\x87t Nam".is_ascii()); + assert!(!b"Vi\xe1\xbb\x87t Nam".iter().all(|b| b.is_ascii())); + assert!(!b"\xe1\xbb\x87".iter().any(|b| b.is_ascii())); + + assert!("".is_ascii()); + assert!("banana\0\u{7F}".is_ascii()); + assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii())); + assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii())); + assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii())); + } + + #[test] + fn test_to_ascii_uppercase() { + assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL"); + assert_eq!("hıKß".to_ascii_uppercase(), "HıKß"); + + for i in 0..501 { + let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } + else { i }; + assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(), + (from_u32(upper).unwrap()).to_string()); + } + } + + #[test] + fn test_to_ascii_lowercase() { + assert_eq!("url()URL()uRl()Ürl".to_ascii_lowercase(), "url()url()url()Ürl"); + // Dotted capital I, Kelvin sign, Sharp S. + assert_eq!("HİKß".to_ascii_lowercase(), "hİKß"); + + for i in 0..501 { + let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } + else { i }; + assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(), + (from_u32(lower).unwrap()).to_string()); + } + } + + #[test] + fn test_make_ascii_lower_case() { + macro_rules! test { + ($from: expr, $to: expr) => { + { + let mut x = $from; + x.make_ascii_lowercase(); + assert_eq!(x, $to); + } + } + } + test!(b'A', b'a'); + test!(b'a', b'a'); + test!(b'!', b'!'); + test!('A', 'a'); + test!('À', 'À'); + test!('a', 'a'); + test!('!', '!'); + test!(b"H\xc3\x89".to_vec(), b"h\xc3\x89"); + test!("HİKß".to_string(), "hİKß"); + } + + + #[test] + fn test_make_ascii_upper_case() { + macro_rules! test { + ($from: expr, $to: expr) => { + { + let mut x = $from; + x.make_ascii_uppercase(); + assert_eq!(x, $to); + } + } + } + test!(b'a', b'A'); + test!(b'A', b'A'); + test!(b'!', b'!'); + test!('a', 'A'); + test!('à', 'à'); + test!('A', 'A'); + test!('!', '!'); + test!(b"h\xc3\xa9".to_vec(), b"H\xc3\xa9"); + test!("hıKß".to_string(), "HıKß"); + + let mut x = "Hello".to_string(); + x[..3].make_ascii_uppercase(); // Test IndexMut on String. + assert_eq!(x, "HELlo") + } + + #[test] + fn test_eq_ignore_ascii_case() { + assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl")); + assert!(!"Ürl".eq_ignore_ascii_case("ürl")); + // Dotted capital I, Kelvin sign, Sharp S. + assert!("HİKß".eq_ignore_ascii_case("hİKß")); + assert!(!"İ".eq_ignore_ascii_case("i")); + assert!(!"K".eq_ignore_ascii_case("k")); + assert!(!"ß".eq_ignore_ascii_case("s")); + + for i in 0..501 { + let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } + else { i }; + assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case( + &from_u32(lower).unwrap().to_string())); + } + } + + #[test] + fn inference_works() { + let x = "a".to_string(); + x.eq_ignore_ascii_case("A"); + } + + // Shorthands used by the is_ascii_* tests. + macro_rules! assert_all { + ($what:ident, $($str:tt),+) => {{ + $( + for b in $str.chars() { + if !b.$what() { + panic!("expected {}({}) but it isn't", + stringify!($what), b); + } + } + for b in $str.as_bytes().iter() { + if !b.$what() { + panic!("expected {}(0x{:02x})) but it isn't", + stringify!($what), b); + } + } + assert!($str.$what()); + assert!($str.as_bytes().$what()); + )+ + }}; + ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+)) + } + macro_rules! assert_none { + ($what:ident, $($str:tt),+) => {{ + $( + for b in $str.chars() { + if b.$what() { + panic!("expected not-{}({}) but it is", + stringify!($what), b); + } + } + for b in $str.as_bytes().iter() { + if b.$what() { + panic!("expected not-{}(0x{:02x})) but it is", + stringify!($what), b); + } + } + )* + }}; + ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+)) + } + + #[test] + fn test_is_ascii_alphabetic() { + assert_all!(is_ascii_alphabetic, + "", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + ); + assert_none!(is_ascii_alphabetic, + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_uppercase() { + assert_all!(is_ascii_uppercase, + "", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + ); + assert_none!(is_ascii_uppercase, + "abcdefghijklmnopqrstuvwxyz", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_lowercase() { + assert_all!(is_ascii_lowercase, + "abcdefghijklmnopqrstuvwxyz", + ); + assert_none!(is_ascii_lowercase, + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_alphanumeric() { + assert_all!(is_ascii_alphanumeric, + "", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + ); + assert_none!(is_ascii_alphanumeric, + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_digit() { + assert_all!(is_ascii_digit, + "", + "0123456789", + ); + assert_none!(is_ascii_digit, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_hexdigit() { + assert_all!(is_ascii_hexdigit, + "", + "0123456789", + "abcdefABCDEF", + ); + assert_none!(is_ascii_hexdigit, + "ghijklmnopqrstuvwxyz", + "GHIJKLMNOQPRSTUVWXYZ", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_punctuation() { + assert_all!(is_ascii_punctuation, + "", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + ); + assert_none!(is_ascii_punctuation, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_graphic() { + assert_all!(is_ascii_graphic, + "", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + ); + assert_none!(is_ascii_graphic, + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_whitespace() { + assert_all!(is_ascii_whitespace, + "", + " \t\n\x0c\r", + ); + assert_none!(is_ascii_whitespace, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x0b\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + } + + #[test] + fn test_is_ascii_control() { + assert_all!(is_ascii_control, + "", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + assert_none!(is_ascii_control, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " ", + ); + } +} From 16076d47507cc42e2c519f2fbd5e4a1733b17b55 Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Sun, 4 Mar 2018 13:44:43 -0500 Subject: [PATCH 036/830] Declare `ascii` module in libcore/lib.rs --- src/libcore/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1efd605112dc..b6208f91ac0a 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -165,6 +165,7 @@ pub mod borrow; pub mod any; pub mod array; +pub mod ascii; pub mod sync; pub mod cell; pub mod char; From bebc34003e2d60297448b73b964db89a8030ba47 Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Sun, 4 Mar 2018 14:39:14 -0500 Subject: [PATCH 037/830] Fix unintended rename and a doc example --- src/libcore/ascii.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index e7bee41ac348..989a98ec8e78 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -57,6 +57,8 @@ pub struct EscapeDefault { /// # Examples /// /// ``` +/// use core::ascii; +/// /// let escaped = ascii::escape_default(b'0').next().unwrap(); /// assert_eq!(b'0', escaped); /// @@ -98,7 +100,7 @@ pub struct EscapeDefault { /// assert_eq!(b'd', escaped.next().unwrap()); /// ``` #[unstable(feature = "core_ascii", issue = "46409")] -pub fn escape_ascii(c: u8) -> EscapeDefault { +pub fn escape_default(c: u8) -> EscapeDefault { let (data, len) = match c { b'\t' => ([b'\\', b't', 0, 0], 2), b'\r' => ([b'\\', b'r', 0, 0], 2), From 1a4aa1eb6e3f91e24d255c346036de64d95d120b Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Sun, 4 Mar 2018 18:36:32 -0500 Subject: [PATCH 038/830] Fix doc example --- src/libcore/ascii.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index 989a98ec8e78..32847506cdfb 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -57,6 +57,7 @@ pub struct EscapeDefault { /// # Examples /// /// ``` +/// #![no_std] /// use core::ascii; /// /// let escaped = ascii::escape_default(b'0').next().unwrap(); From 9bfc06272310600e93e3127a3a257031d15eab7f Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Sun, 4 Mar 2018 20:32:44 -0500 Subject: [PATCH 039/830] Fix doc example, and change fn annotation to stable --- src/libcore/ascii.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index 32847506cdfb..d61b91995605 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -31,7 +31,7 @@ use iter::FusedIterator; /// documentation for more. /// /// [`escape_default`]: fn.escape_default.html -#[unstable(feature = "core_ascii", issue = "46409")] +#[stable(feature = "core_ascii", since = "1.26.0")] pub struct EscapeDefault { range: Range, data: [u8; 4], @@ -57,8 +57,7 @@ pub struct EscapeDefault { /// # Examples /// /// ``` -/// #![no_std] -/// use core::ascii; +/// use std::ascii; /// /// let escaped = ascii::escape_default(b'0').next().unwrap(); /// assert_eq!(b'0', escaped); @@ -100,7 +99,7 @@ pub struct EscapeDefault { /// assert_eq!(b'9', escaped.next().unwrap()); /// assert_eq!(b'd', escaped.next().unwrap()); /// ``` -#[unstable(feature = "core_ascii", issue = "46409")] +#[stable(feature = "core_ascii", since = "1.26.0")] pub fn escape_default(c: u8) -> EscapeDefault { let (data, len) = match c { b'\t' => ([b'\\', b't', 0, 0], 2), From 264c2013eb25f929135a5f4fc8b20b3baeae2af1 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Wed, 21 Feb 2018 21:38:10 -0500 Subject: [PATCH 040/830] Fix #48276 The ExplicitSelf::determine function expects to be able to compare regions. However, when the compare_self_type error reporting code runs we haven't resolved bound regions yet. Thus we replace them with free regions first. --- src/librustc_typeck/check/compare_method.rs | 4 ++ src/test/ui/issue-48276.rs | 43 +++++++++++++++++++++ src/test/ui/issue-48276.stderr | 27 +++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 src/test/ui/issue-48276.rs create mode 100644 src/test/ui/issue-48276.stderr diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index d0419382bc31..a3a1f2a93077 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -504,6 +504,10 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let param_env = ty::ParamEnv::empty(Reveal::All); tcx.infer_ctxt().enter(|infcx| { + let self_arg_ty = tcx.liberate_late_bound_regions( + method.def_id, + &ty::Binder(self_arg_ty) + ); let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok(); match ExplicitSelf::determine(self_arg_ty, can_eq_self) { ExplicitSelf::ByValue => "self".to_string(), diff --git a/src/test/ui/issue-48276.rs b/src/test/ui/issue-48276.rs new file mode 100644 index 000000000000..30d11a2e37f1 --- /dev/null +++ b/src/test/ui/issue-48276.rs @@ -0,0 +1,43 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for issue #48276 - ICE when self type does not match what is +// required by a trait and regions are involved. + +trait MyFrom { + fn from(a: A) -> Self; +} + +struct A; + +impl<'a, 'b> MyFrom for &'a str { + fn from(self: &'a Self) -> &'b str { + //~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait + "asdf" + } +} + +struct B; + +impl From for B { + fn from(&self) -> B { + //~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait + B + } +} + +impl From for &'static str { + fn from(&self) -> &'static str { + //~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait + "" + } +} + +fn main(){} diff --git a/src/test/ui/issue-48276.stderr b/src/test/ui/issue-48276.stderr new file mode 100644 index 000000000000..43986c5f4d81 --- /dev/null +++ b/src/test/ui/issue-48276.stderr @@ -0,0 +1,27 @@ +error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait + --> $DIR/issue-48276.rs:21:5 + | +15 | fn from(a: A) -> Self; + | ---------------------- trait method declared without `&self` +... +21 | fn from(self: &'a Self) -> &'b str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl + +error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait + --> $DIR/issue-48276.rs:30:5 + | +30 | fn from(&self) -> B { + | ^^^^^^^^^^^^^^^^^^^ `&self` used in impl + | + = note: `from` from trait: `fn(T) -> Self` + +error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait + --> $DIR/issue-48276.rs:37:5 + | +37 | fn from(&self) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl + | + = note: `from` from trait: `fn(T) -> Self` + +error: aborting due to 3 previous errors + From c0d41fb22c050803fb0e831113b6837f80a1db62 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Mon, 5 Mar 2018 04:20:04 -0500 Subject: [PATCH 041/830] Update issue-48276 test to new stderr format --- src/test/ui/issue-48276.stderr | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/ui/issue-48276.stderr b/src/test/ui/issue-48276.stderr index 43986c5f4d81..9273ece2c908 100644 --- a/src/test/ui/issue-48276.stderr +++ b/src/test/ui/issue-48276.stderr @@ -1,16 +1,16 @@ error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait --> $DIR/issue-48276.rs:21:5 | -15 | fn from(a: A) -> Self; +LL | fn from(a: A) -> Self; | ---------------------- trait method declared without `&self` ... -21 | fn from(self: &'a Self) -> &'b str { +LL | fn from(self: &'a Self) -> &'b str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait --> $DIR/issue-48276.rs:30:5 | -30 | fn from(&self) -> B { +LL | fn from(&self) -> B { | ^^^^^^^^^^^^^^^^^^^ `&self` used in impl | = note: `from` from trait: `fn(T) -> Self` @@ -18,10 +18,11 @@ error[E0185]: method `from` has a `&self` declaration in the impl, but not in th error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait --> $DIR/issue-48276.rs:37:5 | -37 | fn from(&self) -> &'static str { +LL | fn from(&self) -> &'static str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl | = note: `from` from trait: `fn(T) -> Self` error: aborting due to 3 previous errors +If you want more information on this error, try using "rustc --explain E0185" From 1b3d1fc2aad94f73d927057f497cb086f1fb0d83 Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Mon, 5 Mar 2018 16:39:09 -0500 Subject: [PATCH 042/830] Move tests, re-export items from core::ascii --- src/libcore/ascii.rs | 356 +-------------------------- src/libcore/tests/ascii.rs | 349 +++++++++++++++++++++++++++ src/libstd/ascii.rs | 477 +------------------------------------ 3 files changed, 353 insertions(+), 829 deletions(-) create mode 100644 src/libcore/tests/ascii.rs diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index d61b91995605..f409536d1b0e 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -19,7 +19,7 @@ //! //! [`escape_default`]: fn.escape_default.html -#![stable(feature = "rust1", since = "1.0.0")] +#![stable(feature = "core_ascii", since = "1.26.0")] use fmt; use ops::Range; @@ -145,357 +145,3 @@ impl fmt::Debug for EscapeDefault { f.pad("EscapeDefault { .. }") } } - - -#[cfg(test)] -mod tests { - use char::from_u32; - - #[test] - fn test_is_ascii() { - assert!(b"".is_ascii()); - assert!(b"banana\0\x7F".is_ascii()); - assert!(b"banana\0\x7F".iter().all(|b| b.is_ascii())); - assert!(!b"Vi\xe1\xbb\x87t Nam".is_ascii()); - assert!(!b"Vi\xe1\xbb\x87t Nam".iter().all(|b| b.is_ascii())); - assert!(!b"\xe1\xbb\x87".iter().any(|b| b.is_ascii())); - - assert!("".is_ascii()); - assert!("banana\0\u{7F}".is_ascii()); - assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii())); - assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii())); - assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii())); - } - - #[test] - fn test_to_ascii_uppercase() { - assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL"); - assert_eq!("hıKß".to_ascii_uppercase(), "HıKß"); - - for i in 0..501 { - let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } - else { i }; - assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(), - (from_u32(upper).unwrap()).to_string()); - } - } - - #[test] - fn test_to_ascii_lowercase() { - assert_eq!("url()URL()uRl()Ürl".to_ascii_lowercase(), "url()url()url()Ürl"); - // Dotted capital I, Kelvin sign, Sharp S. - assert_eq!("HİKß".to_ascii_lowercase(), "hİKß"); - - for i in 0..501 { - let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } - else { i }; - assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(), - (from_u32(lower).unwrap()).to_string()); - } - } - - #[test] - fn test_make_ascii_lower_case() { - macro_rules! test { - ($from: expr, $to: expr) => { - { - let mut x = $from; - x.make_ascii_lowercase(); - assert_eq!(x, $to); - } - } - } - test!(b'A', b'a'); - test!(b'a', b'a'); - test!(b'!', b'!'); - test!('A', 'a'); - test!('À', 'À'); - test!('a', 'a'); - test!('!', '!'); - test!(b"H\xc3\x89".to_vec(), b"h\xc3\x89"); - test!("HİKß".to_string(), "hİKß"); - } - - - #[test] - fn test_make_ascii_upper_case() { - macro_rules! test { - ($from: expr, $to: expr) => { - { - let mut x = $from; - x.make_ascii_uppercase(); - assert_eq!(x, $to); - } - } - } - test!(b'a', b'A'); - test!(b'A', b'A'); - test!(b'!', b'!'); - test!('a', 'A'); - test!('à', 'à'); - test!('A', 'A'); - test!('!', '!'); - test!(b"h\xc3\xa9".to_vec(), b"H\xc3\xa9"); - test!("hıKß".to_string(), "HıKß"); - - let mut x = "Hello".to_string(); - x[..3].make_ascii_uppercase(); // Test IndexMut on String. - assert_eq!(x, "HELlo") - } - - #[test] - fn test_eq_ignore_ascii_case() { - assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl")); - assert!(!"Ürl".eq_ignore_ascii_case("ürl")); - // Dotted capital I, Kelvin sign, Sharp S. - assert!("HİKß".eq_ignore_ascii_case("hİKß")); - assert!(!"İ".eq_ignore_ascii_case("i")); - assert!(!"K".eq_ignore_ascii_case("k")); - assert!(!"ß".eq_ignore_ascii_case("s")); - - for i in 0..501 { - let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } - else { i }; - assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case( - &from_u32(lower).unwrap().to_string())); - } - } - - #[test] - fn inference_works() { - let x = "a".to_string(); - x.eq_ignore_ascii_case("A"); - } - - // Shorthands used by the is_ascii_* tests. - macro_rules! assert_all { - ($what:ident, $($str:tt),+) => {{ - $( - for b in $str.chars() { - if !b.$what() { - panic!("expected {}({}) but it isn't", - stringify!($what), b); - } - } - for b in $str.as_bytes().iter() { - if !b.$what() { - panic!("expected {}(0x{:02x})) but it isn't", - stringify!($what), b); - } - } - assert!($str.$what()); - assert!($str.as_bytes().$what()); - )+ - }}; - ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+)) - } - macro_rules! assert_none { - ($what:ident, $($str:tt),+) => {{ - $( - for b in $str.chars() { - if b.$what() { - panic!("expected not-{}({}) but it is", - stringify!($what), b); - } - } - for b in $str.as_bytes().iter() { - if b.$what() { - panic!("expected not-{}(0x{:02x})) but it is", - stringify!($what), b); - } - } - )* - }}; - ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+)) - } - - #[test] - fn test_is_ascii_alphabetic() { - assert_all!(is_ascii_alphabetic, - "", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - ); - assert_none!(is_ascii_alphabetic, - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_uppercase() { - assert_all!(is_ascii_uppercase, - "", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - ); - assert_none!(is_ascii_uppercase, - "abcdefghijklmnopqrstuvwxyz", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_lowercase() { - assert_all!(is_ascii_lowercase, - "abcdefghijklmnopqrstuvwxyz", - ); - assert_none!(is_ascii_lowercase, - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_alphanumeric() { - assert_all!(is_ascii_alphanumeric, - "", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - ); - assert_none!(is_ascii_alphanumeric, - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_digit() { - assert_all!(is_ascii_digit, - "", - "0123456789", - ); - assert_none!(is_ascii_digit, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_hexdigit() { - assert_all!(is_ascii_hexdigit, - "", - "0123456789", - "abcdefABCDEF", - ); - assert_none!(is_ascii_hexdigit, - "ghijklmnopqrstuvwxyz", - "GHIJKLMNOQPRSTUVWXYZ", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_punctuation() { - assert_all!(is_ascii_punctuation, - "", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - ); - assert_none!(is_ascii_punctuation, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_graphic() { - assert_all!(is_ascii_graphic, - "", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - ); - assert_none!(is_ascii_graphic, - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_whitespace() { - assert_all!(is_ascii_whitespace, - "", - " \t\n\x0c\r", - ); - assert_none!(is_ascii_whitespace, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x0b\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_control() { - assert_all!(is_ascii_control, - "", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - assert_none!(is_ascii_control, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " ", - ); - } -} diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs new file mode 100644 index 000000000000..9cc3cd18be5b --- /dev/null +++ b/src/libcore/tests/ascii.rs @@ -0,0 +1,349 @@ +use char::from_u32; + +#[test] +fn test_is_ascii() { + assert!(b"".is_ascii()); + assert!(b"banana\0\x7F".is_ascii()); + assert!(b"banana\0\x7F".iter().all(|b| b.is_ascii())); + assert!(!b"Vi\xe1\xbb\x87t Nam".is_ascii()); + assert!(!b"Vi\xe1\xbb\x87t Nam".iter().all(|b| b.is_ascii())); + assert!(!b"\xe1\xbb\x87".iter().any(|b| b.is_ascii())); + + assert!("".is_ascii()); + assert!("banana\0\u{7F}".is_ascii()); + assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii())); + assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii())); + assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii())); +} + +#[test] +fn test_to_ascii_uppercase() { + assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL"); + assert_eq!("hıKß".to_ascii_uppercase(), "HıKß"); + + for i in 0..501 { + let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } + else { i }; + assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(), + (from_u32(upper).unwrap()).to_string()); + } +} + +#[test] +fn test_to_ascii_lowercase() { + assert_eq!("url()URL()uRl()Ürl".to_ascii_lowercase(), "url()url()url()Ürl"); + // Dotted capital I, Kelvin sign, Sharp S. + assert_eq!("HİKß".to_ascii_lowercase(), "hİKß"); + + for i in 0..501 { + let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } + else { i }; + assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(), + (from_u32(lower).unwrap()).to_string()); + } +} + +#[test] +fn test_make_ascii_lower_case() { + macro_rules! test { + ($from: expr, $to: expr) => { + { + let mut x = $from; + x.make_ascii_lowercase(); + assert_eq!(x, $to); + } + } + } + test!(b'A', b'a'); + test!(b'a', b'a'); + test!(b'!', b'!'); + test!('A', 'a'); + test!('À', 'À'); + test!('a', 'a'); + test!('!', '!'); + test!(b"H\xc3\x89".to_vec(), b"h\xc3\x89"); + test!("HİKß".to_string(), "hİKß"); +} + + +#[test] +fn test_make_ascii_upper_case() { + macro_rules! test { + ($from: expr, $to: expr) => { + { + let mut x = $from; + x.make_ascii_uppercase(); + assert_eq!(x, $to); + } + } + } + test!(b'a', b'A'); + test!(b'A', b'A'); + test!(b'!', b'!'); + test!('a', 'A'); + test!('à', 'à'); + test!('A', 'A'); + test!('!', '!'); + test!(b"h\xc3\xa9".to_vec(), b"H\xc3\xa9"); + test!("hıKß".to_string(), "HıKß"); + + let mut x = "Hello".to_string(); + x[..3].make_ascii_uppercase(); // Test IndexMut on String. + assert_eq!(x, "HELlo") +} + +#[test] +fn test_eq_ignore_ascii_case() { + assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl")); + assert!(!"Ürl".eq_ignore_ascii_case("ürl")); + // Dotted capital I, Kelvin sign, Sharp S. + assert!("HİKß".eq_ignore_ascii_case("hİKß")); + assert!(!"İ".eq_ignore_ascii_case("i")); + assert!(!"K".eq_ignore_ascii_case("k")); + assert!(!"ß".eq_ignore_ascii_case("s")); + + for i in 0..501 { + let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } + else { i }; + assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case( + &from_u32(lower).unwrap().to_string())); + } +} + +#[test] +fn inference_works() { + let x = "a".to_string(); + x.eq_ignore_ascii_case("A"); +} + +// Shorthands used by the is_ascii_* tests. +macro_rules! assert_all { + ($what:ident, $($str:tt),+) => {{ + $( + for b in $str.chars() { + if !b.$what() { + panic!("expected {}({}) but it isn't", + stringify!($what), b); + } + } + for b in $str.as_bytes().iter() { + if !b.$what() { + panic!("expected {}(0x{:02x})) but it isn't", + stringify!($what), b); + } + } + assert!($str.$what()); + assert!($str.as_bytes().$what()); + )+ + }}; + ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+)) +} +macro_rules! assert_none { + ($what:ident, $($str:tt),+) => {{ + $( + for b in $str.chars() { + if b.$what() { + panic!("expected not-{}({}) but it is", + stringify!($what), b); + } + } + for b in $str.as_bytes().iter() { + if b.$what() { + panic!("expected not-{}(0x{:02x})) but it is", + stringify!($what), b); + } + } + )* + }}; + ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+)) +} + +#[test] +fn test_is_ascii_alphabetic() { + assert_all!(is_ascii_alphabetic, + "", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + ); + assert_none!(is_ascii_alphabetic, + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_uppercase() { + assert_all!(is_ascii_uppercase, + "", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + ); + assert_none!(is_ascii_uppercase, + "abcdefghijklmnopqrstuvwxyz", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_lowercase() { + assert_all!(is_ascii_lowercase, + "abcdefghijklmnopqrstuvwxyz", + ); + assert_none!(is_ascii_lowercase, + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_alphanumeric() { + assert_all!(is_ascii_alphanumeric, + "", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + ); + assert_none!(is_ascii_alphanumeric, + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_digit() { + assert_all!(is_ascii_digit, + "", + "0123456789", + ); + assert_none!(is_ascii_digit, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_hexdigit() { + assert_all!(is_ascii_hexdigit, + "", + "0123456789", + "abcdefABCDEF", + ); + assert_none!(is_ascii_hexdigit, + "ghijklmnopqrstuvwxyz", + "GHIJKLMNOQPRSTUVWXYZ", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_punctuation() { + assert_all!(is_ascii_punctuation, + "", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + ); + assert_none!(is_ascii_punctuation, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_graphic() { + assert_all!(is_ascii_graphic, + "", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + ); + assert_none!(is_ascii_graphic, + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_whitespace() { + assert_all!(is_ascii_whitespace, + "", + " \t\n\x0c\r", + ); + assert_none!(is_ascii_whitespace, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x0b\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] +fn test_is_ascii_control() { + assert_all!(is_ascii_control, + "", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); + assert_none!(is_ascii_control, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "0123456789", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " ", + ); +} diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 430c9df396a5..70fef9ef5d44 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -30,6 +30,9 @@ use fmt; use ops::Range; use iter::FusedIterator; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::ascii::{EscapeDefault, escape_default}; + /// Extension methods for ASCII-subset only operations. /// /// Be aware that operations on seemingly non-ASCII characters can sometimes @@ -483,477 +486,3 @@ impl AsciiExt for str { self.bytes().all(|b| b.is_ascii_control()) } } - -/// An iterator over the escaped version of a byte. -/// -/// This `struct` is created by the [`escape_default`] function. See its -/// documentation for more. -/// -/// [`escape_default`]: fn.escape_default.html -#[stable(feature = "rust1", since = "1.0.0")] -pub struct EscapeDefault { - range: Range, - data: [u8; 4], -} - -/// Returns an iterator that produces an escaped version of a `u8`. -/// -/// The default is chosen with a bias toward producing literals that are -/// legal in a variety of languages, including C++11 and similar C-family -/// languages. The exact rules are: -/// -/// - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively. -/// - Single-quote, double-quote and backslash chars are backslash-escaped. -/// - Any other chars in the range [0x20,0x7e] are not escaped. -/// - Any other chars are given hex escapes of the form '\xNN'. -/// - Unicode escapes are never generated by this function. -/// -/// # Examples -/// -/// ``` -/// use std::ascii; -/// -/// let escaped = ascii::escape_default(b'0').next().unwrap(); -/// assert_eq!(b'0', escaped); -/// -/// let mut escaped = ascii::escape_default(b'\t'); -/// -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// assert_eq!(b't', escaped.next().unwrap()); -/// -/// let mut escaped = ascii::escape_default(b'\r'); -/// -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// assert_eq!(b'r', escaped.next().unwrap()); -/// -/// let mut escaped = ascii::escape_default(b'\n'); -/// -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// assert_eq!(b'n', escaped.next().unwrap()); -/// -/// let mut escaped = ascii::escape_default(b'\''); -/// -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// assert_eq!(b'\'', escaped.next().unwrap()); -/// -/// let mut escaped = ascii::escape_default(b'"'); -/// -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// assert_eq!(b'"', escaped.next().unwrap()); -/// -/// let mut escaped = ascii::escape_default(b'\\'); -/// -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// -/// let mut escaped = ascii::escape_default(b'\x9d'); -/// -/// assert_eq!(b'\\', escaped.next().unwrap()); -/// assert_eq!(b'x', escaped.next().unwrap()); -/// assert_eq!(b'9', escaped.next().unwrap()); -/// assert_eq!(b'd', escaped.next().unwrap()); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub fn escape_default(c: u8) -> EscapeDefault { - let (data, len) = match c { - b'\t' => ([b'\\', b't', 0, 0], 2), - b'\r' => ([b'\\', b'r', 0, 0], 2), - b'\n' => ([b'\\', b'n', 0, 0], 2), - b'\\' => ([b'\\', b'\\', 0, 0], 2), - b'\'' => ([b'\\', b'\'', 0, 0], 2), - b'"' => ([b'\\', b'"', 0, 0], 2), - b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1), - _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4), - }; - - return EscapeDefault { range: (0.. len), data: data }; - - fn hexify(b: u8) -> u8 { - match b { - 0 ... 9 => b'0' + b, - _ => b'a' + b - 10, - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for EscapeDefault { - type Item = u8; - fn next(&mut self) -> Option { self.range.next().map(|i| self.data[i]) } - fn size_hint(&self) -> (usize, Option) { self.range.size_hint() } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for EscapeDefault { - fn next_back(&mut self) -> Option { - self.range.next_back().map(|i| self.data[i]) - } -} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for EscapeDefault {} -#[unstable(feature = "fused", issue = "35602")] -impl FusedIterator for EscapeDefault {} - -#[stable(feature = "std_debug", since = "1.16.0")] -impl fmt::Debug for EscapeDefault { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("EscapeDefault { .. }") - } -} - - -#[cfg(test)] -mod tests { - //! Note that most of these tests are not testing `AsciiExt` methods, but - //! test inherent ascii methods of char, u8, str and [u8]. `AsciiExt` is - //! just using those methods, though. - use super::AsciiExt; - use char::from_u32; - - #[test] - fn test_is_ascii() { - assert!(b"".is_ascii()); - assert!(b"banana\0\x7F".is_ascii()); - assert!(b"banana\0\x7F".iter().all(|b| b.is_ascii())); - assert!(!b"Vi\xe1\xbb\x87t Nam".is_ascii()); - assert!(!b"Vi\xe1\xbb\x87t Nam".iter().all(|b| b.is_ascii())); - assert!(!b"\xe1\xbb\x87".iter().any(|b| b.is_ascii())); - - assert!("".is_ascii()); - assert!("banana\0\u{7F}".is_ascii()); - assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii())); - assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii())); - assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii())); - } - - #[test] - fn test_to_ascii_uppercase() { - assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL"); - assert_eq!("hıKß".to_ascii_uppercase(), "HıKß"); - - for i in 0..501 { - let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 } - else { i }; - assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(), - (from_u32(upper).unwrap()).to_string()); - } - } - - #[test] - fn test_to_ascii_lowercase() { - assert_eq!("url()URL()uRl()Ürl".to_ascii_lowercase(), "url()url()url()Ürl"); - // Dotted capital I, Kelvin sign, Sharp S. - assert_eq!("HİKß".to_ascii_lowercase(), "hİKß"); - - for i in 0..501 { - let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } - else { i }; - assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(), - (from_u32(lower).unwrap()).to_string()); - } - } - - #[test] - fn test_make_ascii_lower_case() { - macro_rules! test { - ($from: expr, $to: expr) => { - { - let mut x = $from; - x.make_ascii_lowercase(); - assert_eq!(x, $to); - } - } - } - test!(b'A', b'a'); - test!(b'a', b'a'); - test!(b'!', b'!'); - test!('A', 'a'); - test!('À', 'À'); - test!('a', 'a'); - test!('!', '!'); - test!(b"H\xc3\x89".to_vec(), b"h\xc3\x89"); - test!("HİKß".to_string(), "hİKß"); - } - - - #[test] - fn test_make_ascii_upper_case() { - macro_rules! test { - ($from: expr, $to: expr) => { - { - let mut x = $from; - x.make_ascii_uppercase(); - assert_eq!(x, $to); - } - } - } - test!(b'a', b'A'); - test!(b'A', b'A'); - test!(b'!', b'!'); - test!('a', 'A'); - test!('à', 'à'); - test!('A', 'A'); - test!('!', '!'); - test!(b"h\xc3\xa9".to_vec(), b"H\xc3\xa9"); - test!("hıKß".to_string(), "HıKß"); - - let mut x = "Hello".to_string(); - x[..3].make_ascii_uppercase(); // Test IndexMut on String. - assert_eq!(x, "HELlo") - } - - #[test] - fn test_eq_ignore_ascii_case() { - assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl")); - assert!(!"Ürl".eq_ignore_ascii_case("ürl")); - // Dotted capital I, Kelvin sign, Sharp S. - assert!("HİKß".eq_ignore_ascii_case("hİKß")); - assert!(!"İ".eq_ignore_ascii_case("i")); - assert!(!"K".eq_ignore_ascii_case("k")); - assert!(!"ß".eq_ignore_ascii_case("s")); - - for i in 0..501 { - let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 } - else { i }; - assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case( - &from_u32(lower).unwrap().to_string())); - } - } - - #[test] - fn inference_works() { - let x = "a".to_string(); - x.eq_ignore_ascii_case("A"); - } - - // Shorthands used by the is_ascii_* tests. - macro_rules! assert_all { - ($what:ident, $($str:tt),+) => {{ - $( - for b in $str.chars() { - if !b.$what() { - panic!("expected {}({}) but it isn't", - stringify!($what), b); - } - } - for b in $str.as_bytes().iter() { - if !b.$what() { - panic!("expected {}(0x{:02x})) but it isn't", - stringify!($what), b); - } - } - assert!($str.$what()); - assert!($str.as_bytes().$what()); - )+ - }}; - ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+)) - } - macro_rules! assert_none { - ($what:ident, $($str:tt),+) => {{ - $( - for b in $str.chars() { - if b.$what() { - panic!("expected not-{}({}) but it is", - stringify!($what), b); - } - } - for b in $str.as_bytes().iter() { - if b.$what() { - panic!("expected not-{}(0x{:02x})) but it is", - stringify!($what), b); - } - } - )* - }}; - ($what:ident, $($str:tt),+,) => (assert_none!($what,$($str),+)) - } - - #[test] - fn test_is_ascii_alphabetic() { - assert_all!(is_ascii_alphabetic, - "", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - ); - assert_none!(is_ascii_alphabetic, - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_uppercase() { - assert_all!(is_ascii_uppercase, - "", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - ); - assert_none!(is_ascii_uppercase, - "abcdefghijklmnopqrstuvwxyz", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_lowercase() { - assert_all!(is_ascii_lowercase, - "abcdefghijklmnopqrstuvwxyz", - ); - assert_none!(is_ascii_lowercase, - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_alphanumeric() { - assert_all!(is_ascii_alphanumeric, - "", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - ); - assert_none!(is_ascii_alphanumeric, - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_digit() { - assert_all!(is_ascii_digit, - "", - "0123456789", - ); - assert_none!(is_ascii_digit, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_hexdigit() { - assert_all!(is_ascii_hexdigit, - "", - "0123456789", - "abcdefABCDEF", - ); - assert_none!(is_ascii_hexdigit, - "ghijklmnopqrstuvwxyz", - "GHIJKLMNOQPRSTUVWXYZ", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_punctuation() { - assert_all!(is_ascii_punctuation, - "", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - ); - assert_none!(is_ascii_punctuation, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_graphic() { - assert_all!(is_ascii_graphic, - "", - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - ); - assert_none!(is_ascii_graphic, - " \t\n\x0c\r", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_whitespace() { - assert_all!(is_ascii_whitespace, - "", - " \t\n\x0c\r", - ); - assert_none!(is_ascii_whitespace, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x0b\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - } - - #[test] - fn test_is_ascii_control() { - assert_all!(is_ascii_control, - "", - "\x00\x01\x02\x03\x04\x05\x06\x07", - "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", - "\x10\x11\x12\x13\x14\x15\x16\x17", - "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", - "\x7f", - ); - assert_none!(is_ascii_control, - "abcdefghijklmnopqrstuvwxyz", - "ABCDEFGHIJKLMNOQPRSTUVWXYZ", - "0123456789", - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", - " ", - ); - } -} From a39b62d838d7642ca100c069b6b1b716ef7eb97b Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Mon, 5 Mar 2018 17:02:11 -0500 Subject: [PATCH 043/830] Copy license into libcore/tests/ascii.rs --- src/libcore/tests/ascii.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs index 9cc3cd18be5b..dbed5920519b 100644 --- a/src/libcore/tests/ascii.rs +++ b/src/libcore/tests/ascii.rs @@ -1,3 +1,13 @@ +// Copyright 2013-2014 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 char::from_u32; #[test] From aa1ded9286d7ff5bdc0c9b389fc10d564c23c4db Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Mon, 5 Mar 2018 18:13:56 -0500 Subject: [PATCH 044/830] Remove unnecessary imports --- src/libstd/ascii.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 70fef9ef5d44..0837ff91c142 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -26,10 +26,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use fmt; -use ops::Range; -use iter::FusedIterator; - #[stable(feature = "rust1", since = "1.0.0")] pub use core::ascii::{EscapeDefault, escape_default}; From 6701d9020f0deb0e8d673fe5ad1247514b3e9db3 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 6 Mar 2018 00:58:01 +0000 Subject: [PATCH 045/830] Remove IdxSet::reset_to_empty --- src/librustc_data_structures/indexed_set.rs | 5 ----- src/librustc_mir/dataflow/at_location.rs | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/librustc_data_structures/indexed_set.rs b/src/librustc_data_structures/indexed_set.rs index 223e08de826c..7c926cc784b4 100644 --- a/src/librustc_data_structures/indexed_set.rs +++ b/src/librustc_data_structures/indexed_set.rs @@ -231,11 +231,6 @@ impl IdxSet { each_bit(self, max_bits, f) } - /// Removes all elements from this set. - pub fn reset_to_empty(&mut self) { - for word in self.words_mut() { *word = 0; } - } - pub fn elems(&self, universe_size: usize) -> Elems { Elems { i: 0, set: self, universe_size: universe_size } } diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index b1f73bfbe228..30248ccf931c 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -147,8 +147,8 @@ impl FlowsAtLocation for FlowAtLocation } fn reconstruct_statement_effect(&mut self, loc: Location) { - self.stmt_gen.reset_to_empty(); - self.stmt_kill.reset_to_empty(); + self.stmt_gen.clear(); + self.stmt_kill.clear(); { let mut sets = BlockSets { on_entry: &mut self.curr_state, @@ -172,8 +172,8 @@ impl FlowsAtLocation for FlowAtLocation } fn reconstruct_terminator_effect(&mut self, loc: Location) { - self.stmt_gen.reset_to_empty(); - self.stmt_kill.reset_to_empty(); + self.stmt_gen.clear(); + self.stmt_kill.clear(); { let mut sets = BlockSets { on_entry: &mut self.curr_state, From 89d12478ac4f56e45da7ece5d5cac983897653d6 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 6 Mar 2018 01:00:44 +0000 Subject: [PATCH 046/830] Remove IdxSet::each_bit --- src/librustc_data_structures/indexed_set.rs | 33 --------------------- src/librustc_mir/dataflow/at_location.rs | 6 ++-- src/librustc_mir/dataflow/mod.rs | 3 +- 3 files changed, 3 insertions(+), 39 deletions(-) diff --git a/src/librustc_data_structures/indexed_set.rs b/src/librustc_data_structures/indexed_set.rs index 7c926cc784b4..34457d94c3ae 100644 --- a/src/librustc_data_structures/indexed_set.rs +++ b/src/librustc_data_structures/indexed_set.rs @@ -225,12 +225,6 @@ impl IdxSet { } } - /// Calls `f` on each index value held in this set, up to the - /// bound `max_bits` on the size of universe of indexes. - pub fn each_bit(&self, max_bits: usize, f: F) where F: FnMut(T) { - each_bit(self, max_bits, f) - } - pub fn elems(&self, universe_size: usize) -> Elems { Elems { i: 0, set: self, universe_size: universe_size } } @@ -256,33 +250,6 @@ impl<'a, T: Idx> Iterator for Elems<'a, T> { } } } - -fn each_bit(words: &IdxSet, max_bits: usize, mut f: F) where F: FnMut(T) { - let usize_bits: usize = mem::size_of::() * 8; - - for (word_index, &word) in words.words().iter().enumerate() { - if word != 0 { - let base_index = word_index * usize_bits; - for offset in 0..usize_bits { - let bit = 1 << offset; - if (word & bit) != 0 { - // NB: we round up the total number of bits - // that we store in any given bit set so that - // it is an even multiple of usize::BITS. This - // means that there may be some stray bits at - // the end that do not correspond to any - // actual value; that's why we first check - // that we are in range of bits_per_block. - let bit_index = base_index + offset as usize; - if bit_index >= max_bits { - return; - } else { - f(Idx::new(bit_index)); - } - } - } - } - } } pub struct Iter<'a, T: Idx> { diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index 30248ccf931c..32ca513d7df2 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -81,8 +81,7 @@ where where F: FnMut(BD::Idx), { - self.curr_state - .each_bit(self.base_results.operator().bits_per_block(), f) + self.curr_state.iter().for_each(f) } /// Iterate over each `gen` bit in the current effect (invoke @@ -92,8 +91,7 @@ where where F: FnMut(BD::Idx), { - self.stmt_gen - .each_bit(self.base_results.operator().bits_per_block(), f) + self.stmt_gen.iter().for_each(f) } pub fn new(results: DataflowResults) -> Self { diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index aa7bb6f97786..7785b6ec1737 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -444,8 +444,7 @@ pub struct DataflowState impl DataflowState { pub fn each_bit(&self, words: &IdxSet, f: F) where F: FnMut(O::Idx) { - let bits_per_block = self.operator.bits_per_block(); - words.each_bit(bits_per_block, f) + words.iter().for_each(f) } pub(crate) fn interpret_set<'c, P>(&self, From f69a0999e742a6fc45fd4b962c30c56d04c2245c Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 6 Mar 2018 01:00:53 +0000 Subject: [PATCH 047/830] Remove IdxSet::elems --- src/librustc_data_structures/indexed_set.rs | 26 --------------------- src/librustc_mir/borrow_check/mod.rs | 10 ++++---- src/librustc_mir/dataflow/at_location.rs | 14 +++++------ 3 files changed, 11 insertions(+), 39 deletions(-) diff --git a/src/librustc_data_structures/indexed_set.rs b/src/librustc_data_structures/indexed_set.rs index 34457d94c3ae..7ab6a2691488 100644 --- a/src/librustc_data_structures/indexed_set.rs +++ b/src/librustc_data_structures/indexed_set.rs @@ -224,32 +224,6 @@ impl IdxSet { _pd: PhantomData, } } - - pub fn elems(&self, universe_size: usize) -> Elems { - Elems { i: 0, set: self, universe_size: universe_size } - } -} - -pub struct Elems<'a, T: Idx> { i: usize, set: &'a IdxSet, universe_size: usize } - -impl<'a, T: Idx> Iterator for Elems<'a, T> { - type Item = T; - fn next(&mut self) -> Option { - if self.i >= self.universe_size { return None; } - let mut i = self.i; - loop { - if i >= self.universe_size { - self.i = i; // (mark iteration as complete.) - return None; - } - if self.set.contains(&T::new(i)) { - self.i = i + 1; // (next element to start at.) - return Some(T::new(i)); - } - i = i + 1; - } - } -} } pub struct Iter<'a, T: Idx> { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 1ff0ffaaa68b..f0304ccd0405 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -555,7 +555,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx // Look for any active borrows to locals let domain = flow_state.borrows.operator(); let data = domain.borrows(); - flow_state.borrows.with_elems_outgoing(|borrows| { + flow_state.borrows.with_iter_outgoing(|borrows| { for i in borrows { let borrow = &data[i.borrow_index()]; self.check_for_local_borrow(borrow, span); @@ -571,7 +571,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx // so this "extra check" serves as a kind of backup. let domain = flow_state.borrows.operator(); let data = domain.borrows(); - flow_state.borrows.with_elems_outgoing(|borrows| { + flow_state.borrows.with_iter_outgoing(|borrows| { for i in borrows { let borrow = &data[i.borrow_index()]; let context = ContextKind::StorageDead.new(loc); @@ -1310,7 +1310,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { place ); - for i in flow_state.ever_inits.elems_incoming() { + for i in flow_state.ever_inits.iter_incoming() { let init = self.move_data.inits[i]; let init_place = &self.move_data.move_paths[init.path].place; if self.places_conflict(&init_place, place, Deep) { @@ -2155,8 +2155,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // check for loan restricting path P being used. Accounts for // borrows of P, P.a.b, etc. - let mut elems_incoming = flow_state.borrows.elems_incoming(); - while let Some(i) = elems_incoming.next() { + let mut iter_incoming = flow_state.borrows.iter_incoming(); + while let Some(i) = iter_incoming.next() { let borrowed = &data[i.borrow_index()]; if self.places_conflict(&borrowed.borrowed_place, place, access) { diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index 32ca513d7df2..0fbb54e8e0a0 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -12,7 +12,7 @@ //! locations. use rustc::mir::{BasicBlock, Location}; -use rustc_data_structures::indexed_set::{self, IdxSetBuf}; +use rustc_data_structures::indexed_set::{IdxSetBuf, Iter}; use rustc_data_structures::indexed_vec::Idx; use dataflow::{BitDenotation, BlockSets, DataflowResults}; @@ -117,23 +117,21 @@ where } /// Returns an iterator over the elements present in the current state. - pub fn elems_incoming(&self) -> iter::Peekable> { - let univ = self.base_results.sets().bits_per_block(); - self.curr_state.elems(univ).peekable() + pub fn iter_incoming(&self) -> iter::Peekable> { + self.curr_state.iter().peekable() } /// Creates a clone of the current state and applies the local /// effects to the clone (leaving the state of self intact). /// Invokes `f` with an iterator over the resulting state. - pub fn with_elems_outgoing(&self, f: F) + pub fn with_iter_outgoing(&self, f: F) where - F: FnOnce(indexed_set::Elems), + F: FnOnce(Iter), { let mut curr_state = self.curr_state.clone(); curr_state.union(&self.stmt_gen); curr_state.subtract(&self.stmt_kill); - let univ = self.base_results.sets().bits_per_block(); - f(curr_state.elems(univ)); + f(curr_state.iter()); } } From c97c7bfcf377a37f400f1e1a3e25ace2eba85316 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 6 Mar 2018 00:01:30 -0500 Subject: [PATCH 048/830] Add info message for -Wall command Users coming from other languages (namely C and C++) often expect to use a -Wall flag. Rustc doesn't support that, and previously it simply printed that it didn't recognize the "all" lint. This change makes rustc print out a help message, explaining: - Why there is no -Wall flag - How to view all the available warnings - Point out that the most commonly used warning is -Wunused - Instead of using a command-line flag, the user should consider a !#[warn(unused)] directive in the root of their crate. --- src/librustc_driver/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index d89a3e9d907e..b9b36616e69f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1136,6 +1136,16 @@ fn usage(verbose: bool, include_unstable_options: bool) { verbose_help); } +fn print_wall_help() { + println!(" +The flag -Wall does not exist in rustc. Most useful lints are enabled by default. +Use `rustc -W help` to see all available lints. The most used lints that are not +enabled by default covered by -Wunused; however, the best practice is to put +warning settings in the crate root using `#![warn(unused)]` instead of using +the command line flag directly. +"); +} + fn describe_lints(sess: &Session, lint_store: &lint::LintStore, loaded_plugins: bool) { println!(" Available lint options: @@ -1379,6 +1389,13 @@ pub fn handle_options(args: &[String]) -> Option { nightly_options::is_unstable_enabled(&matches)); return None; } + + // Handle the special case of -Wall. + let wall = matches.opt_strs("W"); + if wall.iter().any(|x| *x == "all") { + print_wall_help(); + return None; + } // Don't handle -W help here, because we might first load plugins. let r = matches.opt_strs("Z"); From a0c626227eeb98f864f67c42845b76f126bc519a Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Tue, 6 Mar 2018 16:33:38 -0500 Subject: [PATCH 049/830] FusedIterator will be stabilized --- src/libcore/ascii.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ascii.rs b/src/libcore/ascii.rs index f409536d1b0e..2c4bccebceb9 100644 --- a/src/libcore/ascii.rs +++ b/src/libcore/ascii.rs @@ -136,7 +136,7 @@ impl DoubleEndedIterator for EscapeDefault { } #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for EscapeDefault {} -#[unstable(feature = "fused", issue = "35602")] +#[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for EscapeDefault {} #[stable(feature = "std_debug", since = "1.16.0")] From 1246eef9a9508e6eb5ecbf9718f3b320b07aab05 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 6 Mar 2018 17:24:58 -0500 Subject: [PATCH 050/830] Fix trailing whitespace --- src/librustc_driver/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index b9b36616e69f..47168cb955a0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1389,7 +1389,7 @@ pub fn handle_options(args: &[String]) -> Option { nightly_options::is_unstable_enabled(&matches)); return None; } - + // Handle the special case of -Wall. let wall = matches.opt_strs("W"); if wall.iter().any(|x| *x == "all") { From f0c459ebd2edbf6ad18eac91fb1ad80b98d3359e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= Date: Thu, 22 Feb 2018 21:28:20 +0100 Subject: [PATCH 051/830] Make relro-level=off explicitly disable RELRO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously relro-level=off would just not tell the linker to use RELRO, but when you want to disable RELRO you most likely want to entirely prevent. Signed-off-by: Johannes Löthberg --- src/librustc_trans/back/link.rs | 4 +++- src/librustc_trans/back/linker.rs | 23 ++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 636b3984117d..56b845c30493 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1014,7 +1014,9 @@ fn link_args(cmd: &mut Linker, RelroLevel::Partial => { cmd.partial_relro(); }, - RelroLevel::Off => {}, + RelroLevel::Off => { + cmd.no_relro(); + }, } // Pass optimization flags down to the linker. diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 3fe667f15437..9bd7d83a1918 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -113,8 +113,9 @@ pub trait Linker { fn gc_sections(&mut self, keep_metadata: bool); fn position_independent_executable(&mut self); fn no_position_independent_executable(&mut self); - fn partial_relro(&mut self); fn full_relro(&mut self); + fn partial_relro(&mut self); + fn no_relro(&mut self); fn optimize(&mut self); fn debuginfo(&mut self); fn no_default_libraries(&mut self); @@ -188,8 +189,9 @@ impl<'a> Linker for GccLinker<'a> { fn add_object(&mut self, path: &Path) { self.cmd.arg(path); } fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); } fn no_position_independent_executable(&mut self) { self.cmd.arg("-no-pie"); } - fn partial_relro(&mut self) { self.linker_arg("-z,relro"); } fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); } + fn partial_relro(&mut self) { self.linker_arg("-z,relro"); } + fn no_relro(&mut self) { self.linker_arg("-z,norelro"); } fn build_static_executable(&mut self) { self.cmd.arg("-static"); } fn args(&mut self, args: &[String]) { self.cmd.args(args); } @@ -452,11 +454,15 @@ impl<'a> Linker for MsvcLinker<'a> { // noop } + fn full_relro(&mut self) { + // noop + } + fn partial_relro(&mut self) { // noop } - fn full_relro(&mut self) { + fn no_relro(&mut self) { // noop } @@ -664,11 +670,15 @@ impl<'a> Linker for EmLinker<'a> { // noop } + fn full_relro(&mut self) { + // noop + } + fn partial_relro(&mut self) { // noop } - fn full_relro(&mut self) { + fn no_relro(&mut self) { // noop } @@ -829,10 +839,13 @@ impl Linker for WasmLd { fn position_independent_executable(&mut self) { } + fn full_relro(&mut self) { + } + fn partial_relro(&mut self) { } - fn full_relro(&mut self) { + fn no_relro(&mut self) { } fn build_static_executable(&mut self) { From 54b68b656913baa760dc9daf75796e84172f810a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= Date: Thu, 22 Feb 2018 20:38:35 +0100 Subject: [PATCH 052/830] Add RELRO run-make tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johannes Löthberg --- src/test/run-make/relro-levels/Makefile | 21 +++++++++++++++++++++ src/test/run-make/relro-levels/hello.rs | 13 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/run-make/relro-levels/Makefile create mode 100644 src/test/run-make/relro-levels/hello.rs diff --git a/src/test/run-make/relro-levels/Makefile b/src/test/run-make/relro-levels/Makefile new file mode 100644 index 000000000000..673ba9a9a02c --- /dev/null +++ b/src/test/run-make/relro-levels/Makefile @@ -0,0 +1,21 @@ +-include ../tools.mk + +# This tests the different -Zrelro-level values, and makes sure that they they work properly. + +all: +ifeq ($(UNAME),Linux) + # Ensure that binaries built with the full relro level links them with both + # RELRO and BIND_NOW for doing eager symbol resolving. + $(RUSTC) -Zrelro-level=full hello.rs + readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO + readelf -d $(TMPDIR)/hello | grep -q BIND_NOW + + $(RUSTC) -Zrelro-level=partial hello.rs + readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO + + # Ensure that we're *not* built with RELRO when setting it to off. We do + # not want to check for BIND_NOW however, as the linker might have that + # enabled by default. + $(RUSTC) -Zrelro-level=off hello.rs + ! readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO +endif diff --git a/src/test/run-make/relro-levels/hello.rs b/src/test/run-make/relro-levels/hello.rs new file mode 100644 index 000000000000..41782851a1a6 --- /dev/null +++ b/src/test/run-make/relro-levels/hello.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() { + println!("Hello, world!"); +} From 517083fbad1cab6652efe66f36ed7f085eb67b61 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Wed, 7 Mar 2018 16:13:15 +0900 Subject: [PATCH 053/830] Make `assert` macro a built-in procedural macro --- src/libcore/macros.rs | 15 +++++++++ src/libstd/lib.rs | 3 +- src/libstd/macros.rs | 54 +++++++++++++++++++++++++++++++ src/libsyntax_ext/assert.rs | 64 +++++++++++++++++++++++++++++++++++++ src/libsyntax_ext/lib.rs | 2 ++ 5 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/libsyntax_ext/assert.rs diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 52eb9f29d57a..8a87bea71e25 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -76,6 +76,7 @@ macro_rules! panic { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(stage0)] macro_rules! assert { ($cond:expr) => ( if !$cond { @@ -784,4 +785,18 @@ mod builtin { ($file:expr) => ({ /* compiler built-in */ }); ($file:expr,) => ({ /* compiler built-in */ }); } + + /// Ensure that a boolean expression is `true` at runtime. + /// + /// For more information, see the documentation for [`std::assert!`]. + /// + /// [`std::assert!`]: ../std/macro.assert.html + #[macro_export] + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(dox)] + macro_rules! assert { + ($cond:expr) => ({ /* compiler built-in */ }); + ($cond:expr,) => ({ /* compiler built-in */ }); + ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ }); + } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index a7e1c0ce732e..b2e45f0f4379 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -355,8 +355,9 @@ use prelude::v1::*; // We want to re-export a few macros from core but libcore has already been // imported by the compiler (via our #[no_std] attribute) In this case we just // add a new crate name so we can attach the re-exports to it. -#[macro_reexport(assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, +#[macro_reexport(assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, unreachable, unimplemented, write, writeln, try)] +#[cfg_attr(stage0, macro_reexport(assert))] extern crate core as __core; #[macro_use] diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a18c811d1963..da982af498bc 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -719,6 +719,60 @@ pub mod builtin { ($file:expr) => ({ /* compiler built-in */ }); ($file:expr,) => ({ /* compiler built-in */ }); } + + /// Ensure that a boolean expression is `true` at runtime. + /// + /// This will invoke the [`panic!`] macro if the provided expression cannot be + /// evaluated to `true` at runtime. + /// + /// # Uses + /// + /// Assertions are always checked in both debug and release builds, and cannot + /// be disabled. See [`debug_assert!`] for assertions that are not enabled in + /// release builds by default. + /// + /// Unsafe code relies on `assert!` to enforce run-time invariants that, if + /// violated could lead to unsafety. + /// + /// Other use-cases of `assert!` include [testing] and enforcing run-time + /// invariants in safe code (whose violation cannot result in unsafety). + /// + /// # Custom Messages + /// + /// This macro has a second form, where a custom panic message can + /// be provided with or without arguments for formatting. See [`std::fmt`] + /// for syntax for this form. + /// + /// [`panic!`]: macro.panic.html + /// [`debug_assert!`]: macro.debug_assert.html + /// [testing]: ../book/second-edition/ch11-01-writing-tests.html#checking-results-with-the-assert-macro + /// [`std::fmt`]: ../std/fmt/index.html + /// + /// # Examples + /// + /// ``` + /// // the panic message for these assertions is the stringified value of the + /// // expression given. + /// assert!(true); + /// + /// fn some_computation() -> bool { true } // a very simple function + /// + /// assert!(some_computation()); + /// + /// // assert with a custom message + /// let x = true; + /// assert!(x, "x wasn't true!"); + /// + /// let a = 3; let b = 27; + /// assert!(a + b == 30, "a = {}, b = {}", a, b); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[macro_export] + macro_rules! assert { + ($cond:expr) => ({ /* compiler built-in */ }); + ($cond:expr,) => ({ /* compiler built-in */ }); + ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ }); + } } /// A macro for defining #[cfg] if-else statements. diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs new file mode 100644 index 000000000000..7962ec26c37a --- /dev/null +++ b/src/libsyntax_ext/assert.rs @@ -0,0 +1,64 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use syntax::ast::*; +use syntax::codemap::Spanned; +use syntax::ext::base::*; +use syntax::ext::build::AstBuilder; +use syntax::parse::token; +use syntax::print::pprust; +use syntax::tokenstream::{TokenStream, TokenTree}; +use syntax_pos::Span; + +pub fn expand_assert<'cx>( + cx: &'cx mut ExtCtxt, + sp: Span, + tts: &[TokenTree], +) -> Box { + let mut parser = cx.new_parser_from_tts(tts); + let cond_expr = panictry!(parser.parse_expr()); + let custom_msg_args = if parser.eat(&token::Comma) { + let ts = parser.parse_tokens(); + if !ts.is_empty() { + Some(ts) + } else { + None + } + } else { + None + }; + + let sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark)); + let panic_call = Mac_ { + path: Path::from_ident(sp, Ident::from_str("panic")), + tts: if let Some(ts) = custom_msg_args { + ts.into() + } else { + let panic_str = format!("assertion failed: {}", pprust::expr_to_string(&cond_expr)); + TokenStream::from(token::Literal( + token::Lit::Str_(Name::intern(&panic_str)), + None, + )).into() + }, + }; + let if_expr = cx.expr_if( + sp, + cx.expr(sp, ExprKind::Unary(UnOp::Not, cond_expr)), + cx.expr( + sp, + ExprKind::Mac(Spanned { + span: sp, + node: panic_call, + }), + ), + None, + ); + MacEager::expr(if_expr) +} diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 772dec72ab98..a01878530b2a 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -26,6 +26,7 @@ extern crate proc_macro; extern crate rustc_data_structures; extern crate rustc_errors as errors; +mod assert; mod asm; mod cfg; mod compile_error; @@ -111,6 +112,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, log_syntax: log_syntax::expand_syntax_ext, trace_macros: trace_macros::expand_trace_macros, compile_error: compile_error::expand_compile_error, + assert: assert::expand_assert, } // format_args uses `unstable` things internally. From ca1c91bc653caa2c51d70a0f9ed81dd364da1a5f Mon Sep 17 00:00:00 2001 From: David Alber Date: Wed, 7 Mar 2018 08:57:26 -0800 Subject: [PATCH 054/830] Synchronizing with code of conduct in rust-www This is propagated from rust-lang/rust-www#1062. --- CODE_OF_CONDUCT.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index e9b39717c700..d70b2b52aca1 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -11,9 +11,9 @@ A version of this document [can be found online](https://www.rust-lang.org/condu * Please be kind and courteous. There's no need to be mean or rude. * Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. * Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. -* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behaviour. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. +* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the Citizen Code of Conduct; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. * Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. -* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome. +* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. ## Moderation From cb5be1bb4ce8bdf3cfac5910f11966c7d3b4fcd4 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Thu, 8 Mar 2018 03:05:58 +0900 Subject: [PATCH 055/830] Fix test --- src/test/ui/codemap_tests/issue-28308.rs | 1 + src/test/ui/codemap_tests/issue-28308.stderr | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/ui/codemap_tests/issue-28308.rs b/src/test/ui/codemap_tests/issue-28308.rs index e3a4920d951f..c71c28ed6252 100644 --- a/src/test/ui/codemap_tests/issue-28308.rs +++ b/src/test/ui/codemap_tests/issue-28308.rs @@ -10,4 +10,5 @@ fn main() { assert!("foo"); + //~^ ERROR cannot apply unary operator `!` } diff --git a/src/test/ui/codemap_tests/issue-28308.stderr b/src/test/ui/codemap_tests/issue-28308.stderr index 947c8142e31f..d7f71fd12b3b 100644 --- a/src/test/ui/codemap_tests/issue-28308.stderr +++ b/src/test/ui/codemap_tests/issue-28308.stderr @@ -3,8 +3,6 @@ error[E0600]: cannot apply unary operator `!` to type `&'static str` | LL | assert!("foo"); | ^^^^^^^^^^^^^^^ - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error From 55a2fdf2cf5408edba890ad1702462414899f40b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 6 Mar 2018 14:37:08 -0800 Subject: [PATCH 056/830] travis: Upgrade OSX builders This upgrades the OSX builders to the `xcode9.3-moar` image which has 3 cores as opposed to the 2 that our builders currently have. Should help make those OSX builds a bit speedier! --- .travis.yml | 4 +- .../debuginfo/lexical-scope-with-macro.rs | 1 + .../long-linker-command-lines/Makefile | 2 +- src/test/run-make/reproducible-build/Makefile | 28 +++++----- .../run-make/reproducible-build/linker.rs | 54 +++++++++++++++++++ 5 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 src/test/run-make/reproducible-build/linker.rs diff --git a/.travis.yml b/.travis.yml index 4738f91665db..074149cf1711 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 os: osx - osx_image: xcode9.2 + osx_image: xcode9.3-moar if: branch = auto - env: > @@ -70,7 +70,7 @@ matrix: NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1 os: osx - osx_image: xcode9.2 + osx_image: xcode9.3-moar if: branch = auto # OSX builders producing releases. These do not run the full test suite and diff --git a/src/test/debuginfo/lexical-scope-with-macro.rs b/src/test/debuginfo/lexical-scope-with-macro.rs index eb5798dc7cc4..32d775168692 100644 --- a/src/test/debuginfo/lexical-scope-with-macro.rs +++ b/src/test/debuginfo/lexical-scope-with-macro.rs @@ -9,6 +9,7 @@ // except according to those terms. // min-lldb-version: 310 +// ignore-macos FIXME #48807 // compile-flags:-g -Zdebug-macros diff --git a/src/test/run-make/long-linker-command-lines/Makefile b/src/test/run-make/long-linker-command-lines/Makefile index 309a27fe503a..5876fbc94bc9 100644 --- a/src/test/run-make/long-linker-command-lines/Makefile +++ b/src/test/run-make/long-linker-command-lines/Makefile @@ -1,5 +1,5 @@ -include ../tools.mk all: - $(RUSTC) foo.rs -g + $(RUSTC) foo.rs -g -O RUSTC="$(RUSTC_ORIGINAL)" $(call RUN,foo) diff --git a/src/test/run-make/reproducible-build/Makefile b/src/test/run-make/reproducible-build/Makefile index 629e61850512..ca76a5e5d77b 100644 --- a/src/test/run-make/reproducible-build/Makefile +++ b/src/test/run-make/reproducible-build/Makefile @@ -10,31 +10,27 @@ all: \ smoke: rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) linker.rs -O $(RUSTC) reproducible-build-aux.rs - $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" - $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" - $(B2) - nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1.nm" - nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2.nm" - cmp "$(TMPDIR)/reproducible-build1.nm" "$(TMPDIR)/reproducible-build2.nm" || exit 1 + $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) + $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) + diff -u "$(TMPDIR)/linker-arguments1" "$(TMPDIR)/linker-arguments2" debug: rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) linker.rs -O $(RUSTC) reproducible-build-aux.rs -g - $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" -g - $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" -g - nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1-debug.nm" - nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2-debug.nm" - cmp "$(TMPDIR)/reproducible-build1-debug.nm" "$(TMPDIR)/reproducible-build2-debug.nm" || exit 1 + $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -g + $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -g + diff -u "$(TMPDIR)/linker-arguments1" "$(TMPDIR)/linker-arguments2" opt: rm -rf $(TMPDIR) && mkdir $(TMPDIR) + $(RUSTC) linker.rs -O $(RUSTC) reproducible-build-aux.rs -O - $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build1" -O - $(RUSTC) reproducible-build.rs -o"$(TMPDIR)/reproducible-build2" -O - nm "$(TMPDIR)/reproducible-build1" | sort > "$(TMPDIR)/reproducible-build1-opt.nm" - nm "$(TMPDIR)/reproducible-build2" | sort > "$(TMPDIR)/reproducible-build2-opt.nm" - cmp "$(TMPDIR)/reproducible-build1-opt.nm" "$(TMPDIR)/reproducible-build2-opt.nm" || exit 1 + $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -O + $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -O + diff -u "$(TMPDIR)/linker-arguments1" "$(TMPDIR)/linker-arguments2" link_paths: rm -rf $(TMPDIR) && mkdir $(TMPDIR) diff --git a/src/test/run-make/reproducible-build/linker.rs b/src/test/run-make/reproducible-build/linker.rs new file mode 100644 index 000000000000..fd8946708bff --- /dev/null +++ b/src/test/run-make/reproducible-build/linker.rs @@ -0,0 +1,54 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::env; +use std::path::Path; +use std::fs::File; +use std::io::{Read, Write}; + +fn main() { + let mut dst = env::current_exe().unwrap(); + dst.pop(); + dst.push("linker-arguments1"); + if dst.exists() { + dst.pop(); + dst.push("linker-arguments2"); + assert!(!dst.exists()); + } + + let mut out = String::new(); + for arg in env::args().skip(1) { + let path = Path::new(&arg); + if !path.is_file() { + out.push_str(&arg); + out.push_str("\n"); + continue + } + + let mut contents = Vec::new(); + File::open(path).unwrap().read_to_end(&mut contents).unwrap(); + + out.push_str(&format!("{}: {}\n", arg, hash(&contents))); + } + + File::create(dst).unwrap().write_all(out.as_bytes()).unwrap(); +} + +// fnv hash for now +fn hash(contents: &[u8]) -> u64 { + let mut hash = 0xcbf29ce484222325; + + for byte in contents { + hash = hash ^ (*byte as u64); + hash = hash.wrapping_mul(0x100000001b3); + } + + hash +} From 69035f20b92870a7ad5dbc22c65aee971d8f8698 Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Sat, 24 Feb 2018 19:11:06 -0800 Subject: [PATCH 057/830] check stability of macro invocations --- src/librustc_plugin/registry.rs | 7 ++- src/libsyntax/ext/base.rs | 4 ++ src/libsyntax/ext/expand.rs | 56 +++++++++++++------ src/libsyntax/ext/tt/macro_rules.rs | 13 ++++- src/libsyntax_ext/lib.rs | 2 + .../compile-fail/auxiliary/unstable-macros.rs | 16 ++++++ src/test/compile-fail/macro-stability.rs | 22 ++++++++ .../auxiliary/plugin_args.rs | 1 + .../run-pass/auxiliary/unstable-macros.rs | 16 ++++++ src/test/run-pass/macro-stability.rs | 23 ++++++++ 10 files changed, 141 insertions(+), 19 deletions(-) create mode 100644 src/test/compile-fail/auxiliary/unstable-macros.rs create mode 100644 src/test/compile-fail/macro-stability.rs create mode 100644 src/test/run-pass/auxiliary/unstable-macros.rs create mode 100644 src/test/run-pass/macro-stability.rs diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 3f74093241d2..ebfd8785a0a0 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -106,14 +106,16 @@ impl<'a> Registry<'a> { expander, def_info: _, allow_internal_unstable, - allow_internal_unsafe + allow_internal_unsafe, + unstable_feature } => { let nid = ast::CRATE_NODE_ID; NormalTT { expander, def_info: Some((nid, self.krate_span)), allow_internal_unstable, - allow_internal_unsafe + allow_internal_unsafe, + unstable_feature } } IdentTT(ext, _, allow_internal_unstable) => { @@ -149,6 +151,7 @@ impl<'a> Registry<'a> { def_info: None, allow_internal_unstable: false, allow_internal_unsafe: false, + unstable_feature: None, }); } diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 7b333270d041..23c42972912a 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -555,6 +555,8 @@ pub enum SyntaxExtension { /// Whether the contents of the macro can use `unsafe` /// without triggering the `unsafe_code` lint. allow_internal_unsafe: bool, + /// The macro's feature name if it is unstable, and the stability feature + unstable_feature: Option<(Symbol, u32)>, }, /// A function-like syntax extension that has an extra ident before @@ -670,6 +672,7 @@ pub struct ExpansionData { pub depth: usize, pub module: Rc, pub directory_ownership: DirectoryOwnership, + pub crate_span: Option, } /// One of these is made during expansion and incrementally updated as we go; @@ -701,6 +704,7 @@ impl<'a> ExtCtxt<'a> { depth: 0, module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), directory_ownership: DirectoryOwnership::Owned { relative: None }, + crate_span: None, }, expansions: HashMap::new(), } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 377f47a3ea5a..2cca37a3c939 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -18,7 +18,7 @@ use ext::base::*; use ext::derive::{add_derived_markers, collect_derives}; use ext::hygiene::{Mark, SyntaxContext}; use ext::placeholders::{placeholder, PlaceholderExpander}; -use feature_gate::{self, Features, is_builtin_attr}; +use feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err}; use fold; use fold::*; use parse::{DirectoryOwnership, PResult}; @@ -229,6 +229,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { module.directory.pop(); self.cx.root_path = module.directory.clone(); self.cx.current_expansion.module = Rc::new(module); + self.cx.current_expansion.crate_span = Some(krate.span); let orig_mod_span = krate.module.inner; @@ -531,11 +532,36 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let path = &mac.node.path; let ident = ident.unwrap_or_else(|| keywords::Invalid.ident()); - let validate_and_set_expn_info = |def_site_span, + let validate_and_set_expn_info = |this: &mut Self, // arg instead of capture + def_site_span: Option, allow_internal_unstable, - allow_internal_unsafe| { + allow_internal_unsafe, + // can't infer this type + unstable_feature: Option<(Symbol, u32)>| { + + // feature-gate the macro invocation + if let Some((feature, issue)) = unstable_feature { + let crate_span = this.cx.current_expansion.crate_span.unwrap(); + // don't stability-check macros in the same crate + // (the only time this is null is for syntax extensions registered as macros) + if def_site_span.map_or(false, |def_span| !crate_span.contains(def_span)) + && !span.allows_unstable() && this.cx.ecfg.features.map_or(true, |feats| { + // macro features will count as lib features + !feats.declared_lib_features.iter().any(|&(feat, _)| feat == feature) + }) { + let explain = format!("macro {}! is unstable", path); + emit_feature_err(this.cx.parse_sess, &*feature.as_str(), span, + GateIssue::Library(Some(issue)), &explain); + this.cx.trace_macros_diag(); + return Err(kind.dummy(span)); + } + } + if ident.name != keywords::Invalid.name() { - return Err(format!("macro {}! expects no ident argument, given '{}'", path, ident)); + let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); + this.cx.span_err(path.span, &msg); + this.cx.trace_macros_diag(); + return Err(kind.dummy(span)); } mark.set_expn_info(ExpnInfo { call_site: span, @@ -551,11 +577,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let opt_expanded = match *ext { DeclMacro(ref expand, def_span) => { - if let Err(msg) = validate_and_set_expn_info(def_span.map(|(_, s)| s), - false, false) { - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) + if let Err(dummy_span) = validate_and_set_expn_info(self, def_span.map(|(_, s)| s), + false, false, None) { + dummy_span } else { kind.make_from(expand.expand(self.cx, span, mac.node.stream())) } @@ -565,14 +589,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ref expander, def_info, allow_internal_unstable, - allow_internal_unsafe + allow_internal_unsafe, + unstable_feature, } => { - if let Err(msg) = validate_and_set_expn_info(def_info.map(|(_, s)| s), - allow_internal_unstable, - allow_internal_unsafe) { - self.cx.span_err(path.span, &msg); - self.cx.trace_macros_diag(); - kind.dummy(span) + if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), + allow_internal_unstable, + allow_internal_unsafe, + unstable_feature) { + dummy_span } else { kind.make_from(expander.expand(self.cx, span, mac.node.stream())) } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 728b3e4076d1..3b0d1d498994 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -284,11 +284,22 @@ pub fn compile(sess: &ParseSess, features: &RefCell, def: &ast::Item) if body.legacy { let allow_internal_unstable = attr::contains_name(&def.attrs, "allow_internal_unstable"); let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe"); + + let unstable_feature = attr::find_stability(&sess.span_diagnostic, + &def.attrs, def.span).and_then(|stability| { + if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { + Some((stability.feature, issue)) + } else { + None + } + }); + NormalTT { expander, def_info: Some((def.id, def.span)), allow_internal_unstable, - allow_internal_unsafe + allow_internal_unsafe, + unstable_feature } } else { SyntaxExtension::DeclMacro(expander, Some((def.id, def.span))) diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 772dec72ab98..5b078535852f 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -67,6 +67,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, def_info: None, allow_internal_unstable: false, allow_internal_unsafe: false, + unstable_feature: None, }); )* } } @@ -120,6 +121,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, def_info: None, allow_internal_unstable: true, allow_internal_unsafe: false, + unstable_feature: None }); for (name, ext) in user_exts { diff --git a/src/test/compile-fail/auxiliary/unstable-macros.rs b/src/test/compile-fail/auxiliary/unstable-macros.rs new file mode 100644 index 000000000000..6462c11af481 --- /dev/null +++ b/src/test/compile-fail/auxiliary/unstable-macros.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(staged_api)] +#![stable(feature = "unit_test", since = "0.0.0")] + +#[unstable(feature = "unstable_macros", issue = "0")] +#[macro_export] +macro_rules! unstable_macro{ () => () } diff --git a/src/test/compile-fail/macro-stability.rs b/src/test/compile-fail/macro-stability.rs new file mode 100644 index 000000000000..a4b922c0fe19 --- /dev/null +++ b/src/test/compile-fail/macro-stability.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:unstable-macros.rs + +#![feature(staged_api)] +#[macro_use] extern crate unstable_macros; + +#[unstable(feature = "local_unstable", issue = "0")] +macro_rules! local_unstable { () => () } + +fn main() { + local_unstable!(); + unstable_macro!(); //~ ERROR: macro unstable_macro! is unstable +} diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs index 8da2ae8b29ab..231ed2898f1d 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs @@ -53,5 +53,6 @@ pub fn plugin_registrar(reg: &mut Registry) { def_info: None, allow_internal_unstable: false, allow_internal_unsafe: false, + unstable_feature: None, }); } diff --git a/src/test/run-pass/auxiliary/unstable-macros.rs b/src/test/run-pass/auxiliary/unstable-macros.rs new file mode 100644 index 000000000000..6462c11af481 --- /dev/null +++ b/src/test/run-pass/auxiliary/unstable-macros.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(staged_api)] +#![stable(feature = "unit_test", since = "0.0.0")] + +#[unstable(feature = "unstable_macros", issue = "0")] +#[macro_export] +macro_rules! unstable_macro{ () => () } diff --git a/src/test/run-pass/macro-stability.rs b/src/test/run-pass/macro-stability.rs new file mode 100644 index 000000000000..9afcd51aa85a --- /dev/null +++ b/src/test/run-pass/macro-stability.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:unstable-macros.rs + +#![feature(unstable_macros)] + +#[macro_use] extern crate unstable_macros; + +#[unstable(feature = "local_unstable", issue = "0")] +macro_rules! local_unstable { () => () } + +fn main() { + unstable_macro!(); + local_unstable!(); +} From d14f07e08916d3dbb3ff77b756bde324aeb05190 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Sat, 17 Feb 2018 09:54:11 +0100 Subject: [PATCH 058/830] bootstrap: pass datadir to rust-installer Signed-off-by: Marc-Antoine Perennou --- src/bootstrap/config.rs | 4 +++- src/bootstrap/install.rs | 9 +++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index f15d4d358583..a4193ea8b8f3 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -127,6 +127,7 @@ pub struct Config { pub musl_root: Option, pub prefix: Option, pub sysconfdir: Option, + pub datadir: Option, pub docdir: Option, pub bindir: Option, pub libdir: Option, @@ -212,13 +213,13 @@ struct Build { struct Install { prefix: Option, sysconfdir: Option, + datadir: Option, docdir: Option, bindir: Option, libdir: Option, mandir: Option, // standard paths, currently unused - datadir: Option, infodir: Option, localstatedir: Option, } @@ -419,6 +420,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.datadir = install.datadir.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); diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 20f7d379a696..540c07748b9a 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -67,18 +67,21 @@ fn install_sh( let prefix_default = PathBuf::from("/usr/local"); let sysconfdir_default = PathBuf::from("/etc"); - let docdir_default = PathBuf::from("share/doc/rust"); + let datadir_default = PathBuf::from("share"); + let docdir_default = datadir_default.join("doc/rust"); let bindir_default = PathBuf::from("bin"); let libdir_default = PathBuf::from("lib"); - let mandir_default = PathBuf::from("share/man"); + let mandir_default = datadir_default.join("man"); let prefix = build.config.prefix.as_ref().unwrap_or(&prefix_default); let sysconfdir = build.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default); + let datadir = build.config.datadir.as_ref().unwrap_or(&datadir_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 datadir = prefix.join(datadir); let docdir = prefix.join(docdir); let bindir = prefix.join(bindir); let libdir = prefix.join(libdir); @@ -88,6 +91,7 @@ fn install_sh( let prefix = add_destdir(&prefix, &destdir); let sysconfdir = add_destdir(&sysconfdir, &destdir); + let datadir = add_destdir(&datadir, &destdir); let docdir = add_destdir(&docdir, &destdir); let bindir = add_destdir(&bindir, &destdir); let libdir = add_destdir(&libdir, &destdir); @@ -107,6 +111,7 @@ fn install_sh( .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!("--datadir={}", sanitize_sh(&datadir))) .arg(format!("--docdir={}", sanitize_sh(&docdir))) .arg(format!("--bindir={}", sanitize_sh(&bindir))) .arg(format!("--libdir={}", sanitize_sh(&libdir))) From 2bc3f5b05352d1a046dc159db52505a25f1f2540 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Tue, 23 Jan 2018 16:49:08 +0000 Subject: [PATCH 059/830] borrowck-asm: enable on mips --- src/test/compile-fail/borrowck/borrowck-asm.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/compile-fail/borrowck/borrowck-asm.rs b/src/test/compile-fail/borrowck/borrowck-asm.rs index 6bccc8386809..9ad3a8f9fc86 100644 --- a/src/test/compile-fail/borrowck/borrowck-asm.rs +++ b/src/test/compile-fail/borrowck/borrowck-asm.rs @@ -21,7 +21,9 @@ #[cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm", - target_arch = "aarch64"))] + target_arch = "aarch64", + target_arch = "mips", + target_arch = "mips64"))] mod test_cases { fn is_move() { let y: &mut isize; From f53f2fa2e894c4709d7b09995331f30c596d0724 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Thu, 8 Mar 2018 11:52:41 +0000 Subject: [PATCH 060/830] librustc_back: bump ISA level of mipsel targets to mips32r2 --- src/librustc_back/target/mipsel_unknown_linux_gnu.rs | 4 ++-- src/librustc_back/target/mipsel_unknown_linux_musl.rs | 4 ++-- src/librustc_back/target/mipsel_unknown_linux_uclibc.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs index 2c38444d050f..94f82adfacde 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs @@ -25,8 +25,8 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - cpu: "mips32".to_string(), - features: "+mips32".to_string(), + cpu: "mips32r2".to_string(), + features: "+mips32r2".to_string(), max_atomic_width: Some(32), // see #36994 diff --git a/src/librustc_back/target/mipsel_unknown_linux_musl.rs b/src/librustc_back/target/mipsel_unknown_linux_musl.rs index b09d96eb9cbc..6bef2fe2ea71 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_musl.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_musl.rs @@ -13,8 +13,8 @@ use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); - base.cpu = "mips32".to_string(); - base.features = "+mips32,+soft-float".to_string(); + base.cpu = "mips32r2".to_string(); + base.features = "+mips32r2,+soft-float".to_string(); base.max_atomic_width = Some(32); // see #36994 base.exe_allocation_crate = None; diff --git a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs index 5d2ba548769f..a5dbdd111835 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs @@ -25,8 +25,8 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - cpu: "mips32".to_string(), - features: "+mips32,+soft-float".to_string(), + cpu: "mips32r2".to_string(), + features: "+mips32r2,+soft-float".to_string(), max_atomic_width: Some(32), // see #36994 From fccaf252df7d5426ae5b0d8b8359357fe526fc58 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Thu, 8 Mar 2018 11:53:19 +0000 Subject: [PATCH 061/830] librustc_back: enable fpxx on 32-bit hardfloat mips targets See this page for details about FPXX: https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking Using FPXX is the most compatible floating point mode available and allows the generated code to work in both FR0 and FR1 modes of the processor. Using MSA (MIPS SIMD) requires FR1, so to use any MSA code we need a compatible floating point mode. This commit also sets nooddspreg (disabling the use of odd numbered single precision float registers) as recommended when enabling FPXX. --- src/librustc_back/target/mips_unknown_linux_gnu.rs | 2 +- src/librustc_back/target/mipsel_unknown_linux_gnu.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_back/target/mips_unknown_linux_gnu.rs b/src/librustc_back/target/mips_unknown_linux_gnu.rs index 5a43e1c4c7a0..cffd1daed99f 100644 --- a/src/librustc_back/target/mips_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mips_unknown_linux_gnu.rs @@ -25,7 +25,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32r2".to_string(), - features: "+mips32r2".to_string(), + features: "+mips32r2,+fpxx,+nooddspreg".to_string(), max_atomic_width: Some(32), // see #36994 diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs index 94f82adfacde..555855b8f815 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs @@ -26,7 +26,7 @@ pub fn target() -> TargetResult { options: TargetOptions { cpu: "mips32r2".to_string(), - features: "+mips32r2".to_string(), + features: "+mips32r2,+fpxx,+nooddspreg".to_string(), max_atomic_width: Some(32), // see #36994 From 0711a7a72f5828825357a4eb5db70aedb2dabef4 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Thu, 8 Mar 2018 12:04:09 +0000 Subject: [PATCH 062/830] librustc_trans: add fp64 to mips features whitelist On 32-bit MIPS, enabling MSA requires also enabling the 64-bit FPU. --- src/librustc_trans/llvm_util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 45445a48e233..afe32f3f6693 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -104,7 +104,7 @@ const POWERPC_WHITELIST: &'static [&'static str] = &["altivec", "power8-vector", "power9-vector", "vsx"]; -const MIPS_WHITELIST: &'static [&'static str] = &["msa"]; +const MIPS_WHITELIST: &'static [&'static str] = &["fp64", "msa"]; pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { let arch = if sess.target.target.arch == "x86_64" { From 1376bf8b01f8d121b04902ac3ed6a248c5137720 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Thu, 25 Jan 2018 13:25:37 +0000 Subject: [PATCH 063/830] tools/compiletest: add mips64 to ARCH_LIST Don't bother distinguishing between big end little endian targets. There are currently no tests which need this. --- src/tools/compiletest/src/util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index cf63cb2e5d90..0e3fa25b13ce 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -40,6 +40,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("i386", "x86"), ("i586", "x86"), ("i686", "x86"), + ("mips64", "mips64"), ("mips", "mips"), ("msp430", "msp430"), ("powerpc", "powerpc"), From 6f55819a1e6af80a4bec25dacf9391d81cc78652 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Thu, 25 Jan 2018 13:26:33 +0000 Subject: [PATCH 064/830] test: remove useless ignore-mips*el headers --- src/test/codegen/fastcall-inreg.rs | 2 -- src/test/codegen/global_asm.rs | 2 -- src/test/codegen/global_asm_include.rs | 2 -- src/test/codegen/global_asm_x2.rs | 2 -- 4 files changed, 8 deletions(-) diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs index b24899cc363a..9bfe47d0a1f2 100644 --- a/src/test/codegen/fastcall-inreg.rs +++ b/src/test/codegen/fastcall-inreg.rs @@ -21,9 +21,7 @@ // ignore-bpfeb // ignore-hexagon // ignore-mips -// ignore-mipsel // ignore-mips64 -// ignore-mips64el // ignore-msp430 // ignore-powerpc // ignore-r600 diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs index 5661592d0c7b..94b69a6cab58 100644 --- a/src/test/codegen/global_asm.rs +++ b/src/test/codegen/global_asm.rs @@ -17,9 +17,7 @@ // ignore-bpfeb // ignore-hexagon // ignore-mips -// ignore-mipsel // ignore-mips64 -// ignore-mips64el // ignore-msp430 // ignore-powerpc // ignore-r600 diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs index d8b5db12404a..c3688077f221 100644 --- a/src/test/codegen/global_asm_include.rs +++ b/src/test/codegen/global_asm_include.rs @@ -17,9 +17,7 @@ // ignore-bpfeb // ignore-hexagon // ignore-mips -// ignore-mipsel // ignore-mips64 -// ignore-mips64el // ignore-msp430 // ignore-powerpc // ignore-r600 diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs index caa0506550dd..3b8fe43fa048 100644 --- a/src/test/codegen/global_asm_x2.rs +++ b/src/test/codegen/global_asm_x2.rs @@ -17,9 +17,7 @@ // ignore-bpfeb // ignore-hexagon // ignore-mips -// ignore-mipsel // ignore-mips64 -// ignore-mips64el // ignore-msp430 // ignore-powerpc // ignore-r600 From dcc438d633f4f82467ce6408d05404959bb5dc43 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Thu, 25 Jan 2018 13:28:17 +0000 Subject: [PATCH 065/830] test: ignore mips64 in abi-main-signature-16bit-c-int.rs --- src/test/codegen/abi-main-signature-16bit-c-int.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/codegen/abi-main-signature-16bit-c-int.rs b/src/test/codegen/abi-main-signature-16bit-c-int.rs index 1e02fe4befdf..707531bf376a 100644 --- a/src/test/codegen/abi-main-signature-16bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-16bit-c-int.rs @@ -17,6 +17,7 @@ // ignore-asmjs // ignore-hexagon // ignore-mips +// ignore-mips64 // ignore-powerpc // ignore-s390x // ignore-sparc From fe557eee7de236e767a81a123c5de9b52d5e9a2a Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Thu, 8 Mar 2018 23:15:39 +0200 Subject: [PATCH 066/830] another rewrite based on @nikomatsakis texthg --- src/libcore/cell.rs | 46 ++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 8accbc204c1d..61b0aead22f2 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1161,27 +1161,43 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// The `UnsafeCell` type is the only legal way to obtain aliasable data that is considered /// mutable. In general, transmuting an `&T` type into an `&mut T` is considered undefined behavior. /// -/// The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or -/// mutated, and that `&mut T` is unique. When building abstractions like `Cell`, `RefCell`, -/// `Mutex`, etc, you need to turn these optimizations off. `UnsafeCell` is the only legal way -/// to do this. When `UnsafeCell` itself is immutably aliased, it is still safe to obtain -/// a mutable reference to its interior and/or to mutate the interior. However, the abstraction -/// designer must ensure that any active mutable references to the interior obtained this way does -/// not co-exist with other active references to the interior, either mutable or not. This is often -/// done via runtime checks. Naturally, several active immutable references to the interior can -/// co-exits with each other (but not with a mutable reference). +/// If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are +/// immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably +/// aliased or mutated, and that `&mut T` is unique. `UnsafeCel` is the only core language +/// feature to work around this restriction. All other types that allow internal mutability, such as +/// `Cell` and `RefCell` use `UnsafeCell` to wrap their internal data. /// -/// To put it in other words, if a mutable reference to the contents is active, no other references -/// can be active at the same time, and if an immutable reference to the contents is active, then -/// only other immutable reference may be active. +/// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to +/// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly. +/// +/// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious: +/// +/// - If you create a safe reference with lifetime `'a` (either a `&T` or `&mut T` reference) that +/// is accessible by safe code (for example, because you returned it), then you must not access +/// the data in any way that contradicts that reference for the remainder of `'a`. For example, that +/// means that if you take the `*mut T` from an `UnsafeCell` and case it to an `&T`, then until +/// that reference's lifetime expires, the data in `T` must remain immutable (modulo any +/// `UnsafeCell` data found within `T`, of course). Similarly, if you create an `&mut T` reference +/// that is released to safe code, then you must not access the data within the `UnsafeCell` until +/// that reference expires. +/// +/// - At all times, you must avoid data races, meaning that if multiple threads have access to +/// the same `UnsafeCell`, then any writes must have a proper happens-before relation to all other +/// accesses (or use atomics). +/// +/// To assist with proper design, the following scenarios are explicitly declared legal +/// for single-threaded code: +/// +/// 1. A `&T` reference can be released to safe code and there it can co-exit with other `&T` +/// references, but not with a `&mut T` +/// +/// 2. A `&mut T` reference may be released to safe code, provided neither other `&mut T` nor `&T` +/// co-exist with it. A `&mut T` must always be unique. /// /// Note that while mutating or mutably aliasing the contents of an `& UnsafeCell` is /// okay (provided you enforce the invariants some other way), it is still undefined behavior /// to have multiple `&mut UnsafeCell` aliases. /// -/// -/// Types like `Cell` and `RefCell` use this type to wrap their internal data. -/// /// # Examples /// /// ``` From fbcd2f5a6a23c48416e6a948d8733f1c225acab3 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Thu, 8 Mar 2018 23:16:31 +0200 Subject: [PATCH 067/830] tidy. Again --- src/libcore/cell.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 61b0aead22f2..98f08676722e 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1167,7 +1167,7 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// feature to work around this restriction. All other types that allow internal mutability, such as /// `Cell` and `RefCell` use `UnsafeCell` to wrap their internal data. /// -/// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to +/// The `UnsafeCell` API itself is technically very simple: it gives you a raw pointer `*mut T` to /// its contents. It is up to _you_ as the abstraction designer to use that raw pointer correctly. /// /// The precise Rust aliasing rules are somewhat in flux, but the main points are not contentious: @@ -1182,7 +1182,7 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// that reference expires. /// /// - At all times, you must avoid data races, meaning that if multiple threads have access to -/// the same `UnsafeCell`, then any writes must have a proper happens-before relation to all other +/// the same `UnsafeCell`, then any writes must have a proper happens-before relation to all other /// accesses (or use atomics). /// /// To assist with proper design, the following scenarios are explicitly declared legal From 55be28367413e01262e4fb72d4af36cee368b65d Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Thu, 8 Mar 2018 23:26:27 +0200 Subject: [PATCH 068/830] and again :( --- src/libcore/cell.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 98f08676722e..4cfc34b86d09 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1176,10 +1176,10 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// is accessible by safe code (for example, because you returned it), then you must not access /// the data in any way that contradicts that reference for the remainder of `'a`. For example, that /// means that if you take the `*mut T` from an `UnsafeCell` and case it to an `&T`, then until -/// that reference's lifetime expires, the data in `T` must remain immutable (modulo any +/// that reference's lifetime expires, the data in `T` must remain immutable (modulo any /// `UnsafeCell` data found within `T`, of course). Similarly, if you create an `&mut T` reference /// that is released to safe code, then you must not access the data within the `UnsafeCell` until -/// that reference expires. +/// that reference expires. /// /// - At all times, you must avoid data races, meaning that if multiple threads have access to /// the same `UnsafeCell`, then any writes must have a proper happens-before relation to all other @@ -1189,7 +1189,7 @@ impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> { /// for single-threaded code: /// /// 1. A `&T` reference can be released to safe code and there it can co-exit with other `&T` -/// references, but not with a `&mut T` +/// references, but not with a `&mut T` /// /// 2. A `&mut T` reference may be released to safe code, provided neither other `&mut T` nor `&T` /// co-exist with it. A `&mut T` must always be unique. From 11915108810250f74e0d30ac6f12948a7e94e648 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 11 Feb 2018 15:39:09 -0700 Subject: [PATCH 069/830] Remove ONLY_BUILD_TARGETS. All cases where it is used can be replaced by substituing run.host for run.builder.build.build; that is its only effect. As such, it is removable. --- src/bootstrap/builder.rs | 7 +------ src/bootstrap/dist.rs | 21 +++------------------ src/bootstrap/install.rs | 3 +-- 3 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 22656e5a9da4..1e15d5393829 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -60,9 +60,6 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash { /// Run this rule for all hosts without cross compiling. const ONLY_HOSTS: bool = false; - /// Run this rule for all targets, but only with the native host. - const ONLY_BUILD_TARGETS: bool = false; - /// Only run this step with the build triple as host and target. const ONLY_BUILD: bool = false; @@ -101,7 +98,6 @@ pub struct RunConfig<'a> { struct StepDescription { default: bool, only_hosts: bool, - only_build_targets: bool, only_build: bool, should_run: fn(ShouldRun) -> ShouldRun, make_run: fn(RunConfig), @@ -138,7 +134,6 @@ impl StepDescription { StepDescription { default: S::DEFAULT, only_hosts: S::ONLY_HOSTS, - only_build_targets: S::ONLY_BUILD_TARGETS, only_build: S::ONLY_BUILD, should_run: S::should_run, make_run: S::make_run, @@ -155,7 +150,7 @@ impl StepDescription { self.name, builder.config.exclude); } let build = builder.build; - let hosts = if self.only_build_targets || self.only_build { + let hosts = if self.only_build { build.build_triple() } else { &build.hosts diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index aa0a7c52246b..c3d8c9f8c010 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -70,7 +70,6 @@ pub struct Docs { impl Step for Docs { type Output = PathBuf; const DEFAULT: bool = true; - const ONLY_BUILD_TARGETS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.path("src/doc") @@ -271,7 +270,6 @@ pub struct Mingw { impl Step for Mingw { type Output = Option; const DEFAULT: bool = true; - const ONLY_BUILD_TARGETS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.never() @@ -331,7 +329,6 @@ impl Step for Rustc { type Output = PathBuf; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; - const ONLY_BUILD_TARGETS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.path("src/librustc") @@ -561,7 +558,6 @@ pub struct Std { impl Step for Std { type Output = PathBuf; const DEFAULT: bool = true; - const ONLY_BUILD_TARGETS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.path("src/libstd") @@ -569,7 +565,7 @@ impl Step for Std { fn make_run(run: RunConfig) { run.builder.ensure(Std { - compiler: run.builder.compiler(run.builder.top_stage, run.host), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), target: run.target, }); } @@ -638,7 +634,6 @@ pub struct Analysis { impl Step for Analysis { type Output = PathBuf; const DEFAULT: bool = true; - const ONLY_BUILD_TARGETS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { let builder = run.builder; @@ -647,7 +642,7 @@ impl Step for Analysis { fn make_run(run: RunConfig) { run.builder.ensure(Analysis { - compiler: run.builder.compiler(run.builder.top_stage, run.host), + compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), target: run.target, }); } @@ -755,8 +750,6 @@ impl Step for Src { type Output = PathBuf; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; - const ONLY_BUILD_TARGETS: bool = true; - const ONLY_BUILD: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.path("src") @@ -851,8 +844,6 @@ impl Step for PlainSourceTarball { type Output = PathBuf; const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; - const ONLY_BUILD_TARGETS: bool = true; - const ONLY_BUILD: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { let builder = run.builder; @@ -1007,7 +998,6 @@ pub struct Cargo { impl Step for Cargo { type Output = PathBuf; - const ONLY_BUILD_TARGETS: bool = true; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { @@ -1095,7 +1085,6 @@ pub struct Rls { impl Step for Rls { type Output = Option; - const ONLY_BUILD_TARGETS: bool = true; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { @@ -1177,7 +1166,6 @@ pub struct Rustfmt { impl Step for Rustfmt { type Output = Option; - const ONLY_BUILD_TARGETS: bool = true; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { @@ -1263,7 +1251,6 @@ pub struct Extended { impl Step for Extended { type Output = (); const DEFAULT: bool = true; - const ONLY_BUILD_TARGETS: bool = true; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { @@ -1274,7 +1261,7 @@ impl Step for Extended { fn make_run(run: RunConfig) { run.builder.ensure(Extended { stage: run.builder.top_stage, - host: run.host, + host: run.builder.build.build, target: run.target, }); } @@ -1692,9 +1679,7 @@ pub struct HashSign; impl Step for HashSign { type Output = (); - const ONLY_BUILD_TARGETS: bool = true; const ONLY_HOSTS: bool = true; - const ONLY_BUILD: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.path("hash-and-sign") diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 20f7d379a696..fa48902d5589 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -161,7 +161,6 @@ macro_rules! install { impl Step for $name { type Output = (); const DEFAULT: bool = true; - const ONLY_BUILD_TARGETS: bool = true; const ONLY_HOSTS: bool = $only_hosts; $(const $c: bool = true;)* @@ -174,7 +173,7 @@ macro_rules! install { run.builder.ensure($name { stage: run.builder.top_stage, target: run.target, - host: run.host, + host: run.builder.build.build, }); } From 1c8f3b011cacdc2e5c614f9b05c509db4a4217db Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 11 Feb 2018 15:41:06 -0700 Subject: [PATCH 070/830] Remove ONLY_BUILD. All uses are replaced with not accessing run.target/run.host, and instead directly using run.builder.build.build. --- src/bootstrap/builder.rs | 13 +------------ src/bootstrap/install.rs | 33 +++++++++++++++++++++++++++++---- src/bootstrap/test.rs | 16 ++++------------ 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 1e15d5393829..7da88bffa4b4 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -60,9 +60,6 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash { /// Run this rule for all hosts without cross compiling. const ONLY_HOSTS: bool = false; - /// Only run this step with the build triple as host and target. - const ONLY_BUILD: bool = false; - /// Primary function to execute this rule. Can call `builder.ensure(...)` /// with other steps to run those. fn run(self, builder: &Builder) -> Self::Output; @@ -98,7 +95,6 @@ pub struct RunConfig<'a> { struct StepDescription { default: bool, only_hosts: bool, - only_build: bool, should_run: fn(ShouldRun) -> ShouldRun, make_run: fn(RunConfig), name: &'static str, @@ -134,7 +130,6 @@ impl StepDescription { StepDescription { default: S::DEFAULT, only_hosts: S::ONLY_HOSTS, - only_build: S::ONLY_BUILD, should_run: S::should_run, make_run: S::make_run, name: unsafe { ::std::intrinsics::type_name::() }, @@ -150,18 +145,12 @@ impl StepDescription { self.name, builder.config.exclude); } let build = builder.build; - let hosts = if self.only_build { - build.build_triple() - } else { - &build.hosts - }; + let hosts = &build.hosts; // Determine the targets participating in this rule. let targets = if self.only_hosts { if build.config.run_host_only { &[] - } else if self.only_build { - build.build_triple() } else { &build.hosts } diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index fa48902d5589..17900fc35e09 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -225,10 +225,6 @@ install!((self, builder, _config), }); install_analysis(builder, self.stage, self.target); }; - Src, "src", Self::should_build(_config) , only_hosts: true, { - builder.ensure(dist::Src); - install_src(builder, self.stage); - }, ONLY_BUILD; Rustc, "src/librustc", true, only_hosts: true, { builder.ensure(dist::Rustc { compiler: builder.compiler(self.stage, self.target), @@ -236,3 +232,32 @@ install!((self, builder, _config), install_rustc(builder, self.stage, self.target); }; ); + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Src { + pub stage: u32, +} + +impl Step for Src { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + let config = &run.builder.config; + let cond = config.extended && + config.tools.as_ref().map_or(true, |t| t.contains("src")); + run.path("src").default_condition(cond) + } + + fn make_run(run: RunConfig) { + run.builder.ensure(Src { + stage: run.builder.top_stage, + }); + } + + fn run(self, builder: &Builder) { + builder.ensure(dist::Src); + install_src(builder, self.stage); + } +} diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 48490493525f..7054c8005060 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -505,27 +505,23 @@ impl Step for RustdocJS { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct Tidy { - host: Interned, -} +pub struct Tidy; impl Step for Tidy { type Output = (); const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; - const ONLY_BUILD: bool = true; - /// Runs the `tidy` tool as compiled in `stage` by the `host` compiler. + /// Runs the `tidy` tool. /// /// This tool in `src/tools` checks up on various bits and pieces of style and /// otherwise just implements a few lint-like checks that are specific to the /// compiler itself. fn run(self, builder: &Builder) { let build = builder.build; - let host = self.host; let _folder = build.fold_output(|| "tidy"); - println!("tidy check ({})", host); + println!("tidy check"); let mut cmd = builder.tool_cmd(Tool::Tidy); cmd.arg(build.src.join("src")); cmd.arg(&build.initial_cargo); @@ -543,9 +539,7 @@ impl Step for Tidy { } fn make_run(run: RunConfig) { - run.builder.ensure(Tidy { - host: run.builder.build.build, - }); + run.builder.ensure(Tidy); } } @@ -1607,7 +1601,6 @@ pub struct Distcheck; impl Step for Distcheck { type Output = (); - const ONLY_BUILD: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.path("distcheck") @@ -1673,7 +1666,6 @@ impl Step for Bootstrap { type Output = (); const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; - const ONLY_BUILD: bool = true; /// Test the build system itself fn run(self, builder: &Builder) { From c8edb3652096bc3d294593375a5333503e6e86b1 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Wed, 14 Feb 2018 18:50:11 -0700 Subject: [PATCH 071/830] Print out the sysroot and libdir on verbose builds. --- src/bootstrap/bin/rustc.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 6c3c48aba72f..40e2ef41144f 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -95,7 +95,7 @@ fn main() { let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); let mut dylib_path = bootstrap::util::dylib_path(); - dylib_path.insert(0, PathBuf::from(libdir)); + dylib_path.insert(0, PathBuf::from(&libdir)); let mut cmd = Command::new(rustc); cmd.args(&args) @@ -107,7 +107,7 @@ fn main() { if let Some(target) = target { // The stage0 compiler has a special sysroot distinct from what we // actually downloaded, so we just always pass the `--sysroot` option. - cmd.arg("--sysroot").arg(sysroot); + cmd.arg("--sysroot").arg(&sysroot); // When we build Rust dylibs they're all intended for intermediate // usage, so make sure we pass the -Cprefer-dynamic flag instead of @@ -280,6 +280,8 @@ fn main() { if verbose > 1 { eprintln!("rustc command: {:?}", cmd); + eprintln!("sysroot: {:?}", sysroot); + eprintln!("libdir: {:?}", libdir); } // Actually run the compiler! From 9cfc73cd3ff9aa845b699eb6d66e76cd4e0cdef0 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Thu, 15 Feb 2018 18:31:17 -0700 Subject: [PATCH 072/830] Deny warnings --- src/bootstrap/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f3d9246c6fc6..5cba65f7f0ad 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -113,7 +113,7 @@ //! More documentation can be found in each respective module below, and you can //! also check out the `src/bootstrap/README.md` file for more information. -//#![deny(warnings)] +#![deny(warnings)] #![feature(core_intrinsics)] #[macro_use] From 29a852970bf6ac9abee1a637727ed03d1888d582 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 11 Feb 2018 15:42:05 -0700 Subject: [PATCH 073/830] Refactor run_host_only to have the proper effect. Previously it was set to true when we didn't run HOSTS steps. --- src/bootstrap/builder.rs | 4 ++-- src/bootstrap/config.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 7da88bffa4b4..74b9978a8373 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -149,8 +149,8 @@ impl StepDescription { // Determine the targets participating in this rule. let targets = if self.only_hosts { - if build.config.run_host_only { - &[] + if !build.config.run_host_only { + return; // don't run anything } else { &build.hosts } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index f15d4d358583..eeafa6891cc8 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -347,7 +347,7 @@ impl Config { config.keep_stage = flags.keep_stage; // If --target was specified but --host wasn't specified, don't run any host-only tests. - config.run_host_only = flags.host.is_empty() && !flags.target.is_empty(); + config.run_host_only = !(flags.host.is_empty() && !flags.target.is_empty()); let toml = file.map(|file| { let mut f = t!(File::open(&file)); From 679e410b11848ef3d9544c08bdb942ae3bc15a46 Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Thu, 8 Mar 2018 22:55:54 -0500 Subject: [PATCH 074/830] declare ascii test module in core --- src/libcore/tests/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 0049ed66a102..939afdcb982a 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -52,6 +52,7 @@ extern crate test; mod any; mod array; +mod ascii; mod atomic; mod cell; mod char; From 184fd32a0334a81315e7ad2cfc8139e2c7341a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 3 Dec 2017 14:21:23 +0100 Subject: [PATCH 075/830] Move PROFQ_CHAN to a Session field --- src/librustc/dep_graph/graph.rs | 37 ++++---- src/librustc/ich/hcx.rs | 32 +++++-- src/librustc/ich/mod.rs | 2 +- src/librustc/session/mod.rs | 8 +- src/librustc/ty/maps/plumbing.rs | 4 +- src/librustc/util/common.rs | 62 ++++++------- src/librustc_data_structures/stable_hasher.rs | 23 ----- src/librustc_driver/driver.rs | 86 +++++++++---------- src/librustc_driver/lib.rs | 2 +- src/librustc_driver/profile/mod.rs | 9 +- src/librustc_incremental/persist/load.rs | 8 +- src/librustc_incremental/persist/save.rs | 4 +- src/librustc_trans/back/link.rs | 4 +- src/librustc_trans/back/lto.rs | 8 +- src/librustc_trans/back/write.rs | 21 +++-- src/librustc_trans/base.rs | 13 ++- src/librustc_trans/lib.rs | 4 +- src/librustc_typeck/lib.rs | 18 ++-- 18 files changed, 175 insertions(+), 170 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 07c6c85b89da..210bdd8d5ddc 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -9,8 +9,7 @@ // except according to those terms. use errors::DiagnosticBuilder; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHashingContextProvider}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::sync::Lrc; @@ -20,7 +19,7 @@ use std::hash::Hash; use ty::TyCtxt; use util::common::{ProfileQueriesMsg, profq_msg}; -use ich::Fingerprint; +use ich::{StableHashingContext, StableHashingContextProvider, Fingerprint}; use super::debug::EdgeFilter; use super::dep_node::{DepNode, DepKind, WorkProductId}; @@ -189,21 +188,21 @@ impl DepGraph { /// `arg` parameter. /// /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/incremental-compilation.html - pub fn with_task(&self, + pub fn with_task<'gcx, C, A, R>(&self, key: DepNode, cx: C, arg: A, task: fn(C, A) -> R) -> (R, DepNodeIndex) - where C: DepGraphSafe + StableHashingContextProvider, - R: HashStable, + where C: DepGraphSafe + StableHashingContextProvider<'gcx>, + R: HashStable>, { self.with_task_impl(key, cx, arg, task, |data, key| data.borrow_mut().push_task(key), |data, key| data.borrow_mut().pop_task(key)) } - fn with_task_impl(&self, + fn with_task_impl<'gcx, C, A, R>(&self, key: DepNode, cx: C, arg: A, @@ -211,25 +210,27 @@ impl DepGraph { push: fn(&RefCell, DepNode), pop: fn(&RefCell, DepNode) -> DepNodeIndex) -> (R, DepNodeIndex) - where C: DepGraphSafe + StableHashingContextProvider, - R: HashStable, + where C: DepGraphSafe + StableHashingContextProvider<'gcx>, + R: HashStable>, { if let Some(ref data) = self.data { push(&data.current, key); - if cfg!(debug_assertions) { - profq_msg(ProfileQueriesMsg::TaskBegin(key.clone())) - }; // In incremental mode, hash the result of the task. We don't // do anything with the hash yet, but we are computing it // anyway so that // - we make sure that the infrastructure works and // - we can get an idea of the runtime cost. - let mut hcx = cx.create_stable_hashing_context(); + let mut hcx = cx.get_stable_hashing_context(); + + if cfg!(debug_assertions) { + profq_msg(hcx.sess(), ProfileQueriesMsg::TaskBegin(key.clone())) + }; let result = task(cx, arg); + if cfg!(debug_assertions) { - profq_msg(ProfileQueriesMsg::TaskEnd) + profq_msg(hcx.sess(), ProfileQueriesMsg::TaskEnd) }; let dep_node_index = pop(&data.current, key); @@ -274,7 +275,7 @@ impl DepGraph { (result, dep_node_index) } else { if key.kind.fingerprint_needed_for_crate_hash() { - let mut hcx = cx.create_stable_hashing_context(); + let mut hcx = cx.get_stable_hashing_context(); let result = task(cx, arg); let mut stable_hasher = StableHasher::new(); result.hash_stable(&mut hcx, &mut stable_hasher); @@ -314,14 +315,14 @@ impl DepGraph { /// Execute something within an "eval-always" task which is a task // that runs whenever anything changes. - pub fn with_eval_always_task(&self, + pub fn with_eval_always_task<'gcx, C, A, R>(&self, key: DepNode, cx: C, arg: A, task: fn(C, A) -> R) -> (R, DepNodeIndex) - where C: DepGraphSafe + StableHashingContextProvider, - R: HashStable, + where C: DepGraphSafe + StableHashingContextProvider<'gcx>, + R: HashStable>, { self.with_task_impl(key, cx, arg, task, |data, key| data.borrow_mut().push_eval_always_task(key), diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 6ae588b2a07b..33e0d0e69449 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -30,7 +30,7 @@ use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; use syntax_pos::hygiene; -use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvider, +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult, ToStableHashKey}; use rustc_data_structures::accumulate_vec::AccumulateVec; @@ -192,17 +192,33 @@ impl<'a> StableHashingContext<'a> { } } -impl<'a, 'gcx, 'lcx> StableHashingContextProvider for TyCtxt<'a, 'gcx, 'lcx> { - type ContextType = StableHashingContext<'a>; - fn create_stable_hashing_context(&self) -> Self::ContextType { +/// Something that can provide a stable hashing context. +pub trait StableHashingContextProvider<'a> { + fn get_stable_hashing_context(&self) -> StableHashingContext<'a>; +} + +impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> +for &'b T { + fn get_stable_hashing_context(&self) -> StableHashingContext<'a> { + (**self).get_stable_hashing_context() + } +} + +impl<'a, 'b, T: StableHashingContextProvider<'a>> StableHashingContextProvider<'a> +for &'b mut T { + fn get_stable_hashing_context(&self) -> StableHashingContext<'a> { + (**self).get_stable_hashing_context() + } +} + +impl<'a, 'gcx, 'lcx> StableHashingContextProvider<'a> for TyCtxt<'a, 'gcx, 'lcx> { + fn get_stable_hashing_context(&self) -> StableHashingContext<'a> { (*self).create_stable_hashing_context() } } - -impl<'a> StableHashingContextProvider for StableHashingContext<'a> { - type ContextType = StableHashingContext<'a>; - fn create_stable_hashing_context(&self) -> Self::ContextType { +impl<'a> StableHashingContextProvider<'a> for StableHashingContext<'a> { + fn get_stable_hashing_context(&self) -> StableHashingContext<'a> { self.clone() } } diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index ce1bd07b14ce..1b77a2e7c82b 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -12,7 +12,7 @@ pub use self::fingerprint::Fingerprint; pub use self::caching_codemap_view::CachingCodemapView; -pub use self::hcx::{StableHashingContext, NodeIdHashingMode, +pub use self::hcx::{StableHashingContextProvider, StableHashingContext, NodeIdHashingMode, hash_stable_trait_impls, compute_ignored_attr_names}; mod fingerprint; mod caching_codemap_view; diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index cdbbcf6a8dd1..01e1037b6222 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -24,8 +24,9 @@ use session::config::{DebugInfoLevel, OutputType}; use ty::tls; use util::nodemap::{FxHashMap, FxHashSet}; use util::common::{duration_to_secs_str, ErrorReported}; +use util::common::ProfileQueriesMsg; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Lock}; use syntax::ast::NodeId; use errors::{self, DiagnosticBuilder, DiagnosticId}; @@ -53,6 +54,7 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::sync::{Once, ONCE_INIT}; use std::time::Duration; +use std::sync::mpsc; mod code_stats; pub mod config; @@ -126,6 +128,9 @@ pub struct Session { /// A cache of attributes ignored by StableHashingContext pub ignored_attr_names: FxHashSet, + /// Used by -Z profile-queries in util::common + pub profile_channel: Lock>>, + /// Some measurements that are being gathered during compilation. pub perf_stats: PerfStats, @@ -1131,6 +1136,7 @@ pub fn build_session_( imported_macro_spans: RefCell::new(HashMap::new()), incr_comp_session: RefCell::new(IncrCompSession::NotInitialized), ignored_attr_names: ich::compute_ignored_attr_names(), + profile_channel: Lock::new(None), perf_stats: PerfStats { svh_time: Cell::new(Duration::from_secs(0)), incr_comp_hashes_time: Cell::new(Duration::from_secs(0)), diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index fcc69f3b2c39..68d108889020 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -164,8 +164,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { macro_rules! profq_msg { ($tcx:expr, $msg:expr) => { if cfg!(debug_assertions) { - if $tcx.sess.profile_queries() { - profq_msg($msg) + if $tcx.sess.profile_queries() { + profq_msg($tcx.sess, $msg) } } } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index bdb120ea59c8..e1ae41f24721 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -26,6 +26,7 @@ use ty::maps::{QueryMsg}; use dep_graph::{DepNode}; use proc_macro; use lazy_static; +use session::Session; // The name of the associated type for `Fn` return types pub const FN_OUTPUT_NAME: &'static str = "Output"; @@ -55,9 +56,6 @@ pub fn install_panic_hook() { lazy_static::initialize(&DEFAULT_HOOK); } -/// Initialized for -Z profile-queries -thread_local!(static PROFQ_CHAN: RefCell>> = RefCell::new(None)); - /// Parameters to the `Dump` variant of type `ProfileQueriesMsg`. #[derive(Clone,Debug)] pub struct ProfQDumpParams { @@ -97,29 +95,23 @@ pub enum ProfileQueriesMsg { } /// If enabled, send a message to the profile-queries thread -pub fn profq_msg(msg: ProfileQueriesMsg) { - PROFQ_CHAN.with(|sender|{ - if let Some(s) = sender.borrow().as_ref() { - s.send(msg).unwrap() - } else { - // Do nothing. - // - // FIXME(matthewhammer): Multi-threaded translation phase triggers the panic below. - // From backtrace: rustc_trans::back::write::spawn_work::{{closure}}. - // - // panic!("no channel on which to send profq_msg: {:?}", msg) - } - }) +pub fn profq_msg(sess: &Session, msg: ProfileQueriesMsg) { + if let Some(s) = sess.profile_channel.borrow().as_ref() { + s.send(msg).unwrap() + } else { + // Do nothing + } } /// Set channel for profile queries channel -pub fn profq_set_chan(s: Sender) -> bool { - PROFQ_CHAN.with(|chan|{ - if chan.borrow().is_none() { - *chan.borrow_mut() = Some(s); - true - } else { false } - }) +pub fn profq_set_chan(sess: &Session, s: Sender) -> bool { + let mut channel = sess.profile_channel.borrow_mut(); + if channel.is_none() { + *channel = Some(s); + true + } else { + false + } } /// Read the current depth of `time()` calls. This is used to @@ -135,7 +127,13 @@ pub fn set_time_depth(depth: usize) { TIME_DEPTH.with(|slot| slot.set(depth)); } -pub fn time(do_it: bool, what: &str, f: F) -> T where +pub fn time(sess: &Session, what: &str, f: F) -> T where + F: FnOnce() -> T, +{ + time_ext(sess.time_passes(), Some(sess), what, f) +} + +pub fn time_ext(do_it: bool, sess: Option<&Session>, what: &str, f: F) -> T where F: FnOnce() -> T, { if !do_it { return f(); } @@ -146,15 +144,19 @@ pub fn time(do_it: bool, what: &str, f: F) -> T where r }); - if cfg!(debug_assertions) { - profq_msg(ProfileQueriesMsg::TimeBegin(what.to_string())) - }; + if let Some(sess) = sess { + if cfg!(debug_assertions) { + profq_msg(sess, ProfileQueriesMsg::TimeBegin(what.to_string())) + } + } let start = Instant::now(); let rv = f(); let dur = start.elapsed(); - if cfg!(debug_assertions) { - profq_msg(ProfileQueriesMsg::TimeEnd) - }; + if let Some(sess) = sess { + if cfg!(debug_assertions) { + profq_msg(sess, ProfileQueriesMsg::TimeEnd) + } + } print_time_passes_entry_internal(what, dur); diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 70733bc6aeda..a8f689e5c81a 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -165,29 +165,6 @@ impl Hasher for StableHasher { } } - -/// Something that can provide a stable hashing context. -pub trait StableHashingContextProvider { - type ContextType; - fn create_stable_hashing_context(&self) -> Self::ContextType; -} - -impl<'a, T: StableHashingContextProvider> StableHashingContextProvider for &'a T { - type ContextType = T::ContextType; - - fn create_stable_hashing_context(&self) -> Self::ContextType { - (**self).create_stable_hashing_context() - } -} - -impl<'a, T: StableHashingContextProvider> StableHashingContextProvider for &'a mut T { - type ContextType = T::ContextType; - - fn create_stable_hashing_context(&self) -> Self::ContextType { - (**self).create_stable_hashing_context() - } -} - /// Something that implements `HashStable` can be hashed in a way that is /// stable across multiple compilation sessions. pub trait HashStable { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f020f86b6860..485ee1130d30 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -89,7 +89,7 @@ pub fn compile_input(trans: Box, } if sess.profile_queries() { - profile::begin(); + profile::begin(sess); } // We need nested scopes here, because the intermediate results can keep @@ -181,7 +181,7 @@ pub fn compile_input(trans: Box, let arenas = AllArenas::new(); // Construct the HIR map - let hir_map = time(sess.time_passes(), + let hir_map = time(sess, "indexing hir", || hir_map::map_crate(sess, cstore, &mut hir_forest, &defs)); @@ -517,10 +517,10 @@ pub fn phase_1_parse_input<'a>(control: &CompileController, sess.diagnostic().set_continue_after_error(control.continue_parse_after_error); if sess.profile_queries() { - profile::begin(); + profile::begin(sess); } - let krate = time(sess.time_passes(), "parsing", || { + let krate = time(sess, "parsing", || { match *input { Input::File(ref file) => { parse::parse_crate_from_file(file, &sess.parse_sess) @@ -645,8 +645,6 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, -> Result, CompileIncomplete> where F: FnOnce(&ast::Crate) -> CompileResult, { - let time_passes = sess.time_passes(); - let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess, sess.opts.test, sess.opts.debugging_opts.epoch); @@ -664,7 +662,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, ); if sess.opts.incremental.is_some() { - time(time_passes, "garbage collect incremental cache directory", || { + time(sess, "garbage collect incremental cache directory", || { if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) { warn!("Error while trying to garbage collect incremental \ compilation cache directory: {}", e); @@ -674,22 +672,22 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, // If necessary, compute the dependency graph (in the background). let future_dep_graph = if sess.opts.build_dep_graph() { - Some(rustc_incremental::load_dep_graph(sess, time_passes)) + Some(rustc_incremental::load_dep_graph(sess)) } else { None }; - time(time_passes, "recursion limit", || { + time(sess, "recursion limit", || { middle::recursion_limit::update_limits(sess, &krate); }); - krate = time(time_passes, "crate injection", || { + krate = time(sess, "crate injection", || { let alt_std_name = sess.opts.alt_std_name.clone(); syntax::std_inject::maybe_inject_crates_ref(krate, alt_std_name) }); let mut addl_plugins = Some(addl_plugins); - let registrars = time(time_passes, "plugin loading", || { + let registrars = time(sess, "plugin loading", || { plugin::load::load_plugins(sess, &cstore, &krate, @@ -699,7 +697,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, let mut registry = registry.unwrap_or(Registry::new(sess, krate.span)); - time(time_passes, "plugin registration", || { + time(sess, "plugin registration", || { if sess.features_untracked().rustc_diagnostic_macros { registry.register_macro("__diagnostic_used", diagnostics::plugin::expand_diagnostic_used); @@ -752,7 +750,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, resolver.whitelisted_legacy_custom_derives = whitelisted_legacy_custom_derives; syntax_ext::register_builtins(&mut resolver, syntax_exts, sess.features_untracked().quote); - krate = time(time_passes, "expansion", || { + krate = time(sess, "expansion", || { // Windows dlls do not have rpaths, so they don't know how to find their // dependencies. It's up to us to tell the system where to find all the // dependent dlls. Note that this uses cfg!(windows) as opposed to @@ -814,7 +812,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, krate }); - krate = time(time_passes, "maybe building test harness", || { + krate = time(sess, "maybe building test harness", || { syntax::test::modify_for_testing(&sess.parse_sess, &mut resolver, sess.opts.test, @@ -833,7 +831,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, // bunch of checks in the `modify` function below. For now just skip this // step entirely if we're rustdoc as it's not too useful anyway. if !sess.opts.actually_rustdoc { - krate = time(time_passes, "maybe creating a macro crate", || { + krate = time(sess, "maybe creating a macro crate", || { let crate_types = sess.crate_types.borrow(); let num_crate_types = crate_types.len(); let is_proc_macro_crate = crate_types.contains(&config::CrateTypeProcMacro); @@ -848,7 +846,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, }); } - krate = time(time_passes, "creating allocators", || { + krate = time(sess, "creating allocators", || { allocator::expand::modify(&sess.parse_sess, &mut resolver, krate, @@ -869,11 +867,11 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, println!("{}", json::as_json(&krate)); } - time(time_passes, + time(sess, "AST validation", || ast_validation::check_crate(sess, &krate)); - time(time_passes, "name resolution", || -> CompileResult { + time(sess, "name resolution", || -> CompileResult { resolver.resolve_crate(&krate); Ok(()) })?; @@ -883,7 +881,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, } // Needs to go *after* expansion to be able to check the results of macro expansion. - time(time_passes, "complete gated feature checking", || { + time(sess, "complete gated feature checking", || { sess.track_errors(|| { syntax::feature_gate::check_crate(&krate, &sess.parse_sess, @@ -898,7 +896,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, let dep_graph = match future_dep_graph { None => DepGraph::new_disabled(), Some(future) => { - let prev_graph = time(time_passes, "blocked while dep-graph loading finishes", || { + let prev_graph = time(sess, "blocked while dep-graph loading finishes", || { future.open() .expect("Could not join with background dep_graph thread") .open(sess) @@ -906,7 +904,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, DepGraph::new(prev_graph) } }; - let hir_forest = time(time_passes, "lowering ast -> hir", || { + let hir_forest = time(sess, "lowering ast -> hir", || { let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, &mut resolver); if sess.opts.debugging_opts.hir_stats { @@ -916,7 +914,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, hir_map::Forest::new(hir_crate, &dep_graph) }); - time(time_passes, + time(sess, "early lint checks", || lint::check_ast_crate(sess, &krate)); @@ -973,22 +971,20 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, mpsc::Receiver>, CompileResult) -> R { - let time_passes = sess.time_passes(); - - let query_result_on_disk_cache = time(time_passes, + let query_result_on_disk_cache = time(sess, "load query result cache", || rustc_incremental::load_query_result_cache(sess)); - time(time_passes, + time(sess, "looking for entry point", || middle::entry::find_entry_point(sess, &hir_map)); - sess.plugin_registrar_fn.set(time(time_passes, "looking for plugin registrar", || { + sess.plugin_registrar_fn.set(time(sess, "looking for plugin registrar", || { plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map) })); sess.derive_registrar_fn.set(derive_registrar::find(&hir_map)); - time(time_passes, + time(sess, "loop checking", || loops::check_crate(sess, &hir_map)); @@ -1020,11 +1016,11 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, // tcx available. rustc_incremental::dep_graph_tcx_init(tcx); - time(sess.time_passes(), "attribute checking", || { + time(sess, "attribute checking", || { hir::check_attr::check_crate(tcx) }); - time(time_passes, + time(sess, "stability checking", || stability::check_unstable_api_usage(tcx)); @@ -1037,18 +1033,18 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, } } - time(time_passes, + time(sess, "rvalue promotion", || rvalue_promotion::check_crate(tcx)); analysis.access_levels = - time(time_passes, "privacy checking", || rustc_privacy::check_crate(tcx)); + time(sess, "privacy checking", || rustc_privacy::check_crate(tcx)); - time(time_passes, + time(sess, "intrinsic checking", || middle::intrinsicck::check_crate(tcx)); - time(time_passes, + time(sess, "match checking", || mir::matchck_crate(tcx)); @@ -1056,19 +1052,19 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, // "not all control paths return a value" is reported here. // // maybe move the check to a MIR pass? - time(time_passes, + time(sess, "liveness checking", || middle::liveness::check_crate(tcx)); - time(time_passes, + time(sess, "borrow checking", || borrowck::check_crate(tcx)); - time(time_passes, + time(sess, "MIR borrow checking", || for def_id in tcx.body_owners() { tcx.mir_borrowck(def_id); }); - time(time_passes, + time(sess, "MIR effect checking", || for def_id in tcx.body_owners() { mir::transform::check_unsafety::check_unsafety(tcx, def_id) @@ -1083,13 +1079,13 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, return Ok(f(tcx, analysis, rx, sess.compile_status())); } - time(time_passes, "death checking", || middle::dead::check_crate(tcx)); + time(sess, "death checking", || middle::dead::check_crate(tcx)); - time(time_passes, "unused lib feature checking", || { + time(sess, "unused lib feature checking", || { stability::check_unused_or_stable_features(tcx) }); - time(time_passes, "lint checking", || lint::check_crate(tcx)); + time(sess, "lint checking", || lint::check_crate(tcx)); return Ok(f(tcx, analysis, rx, tcx.sess.compile_status())); }) @@ -1101,18 +1097,16 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(trans: &TransCrate, tcx: TyCtxt<'a, 'tcx, 'tcx>, rx: mpsc::Receiver>) -> Box { - let time_passes = tcx.sess.time_passes(); - - time(time_passes, + time(tcx.sess, "resolving dependency formats", || ::rustc::middle::dependency_format::calculate(tcx)); let translation = - time(time_passes, "translation", move || { + time(tcx.sess, "translation", move || { trans.trans_crate(tcx, rx) }); if tcx.sess.profile_queries() { - profile::dump("profile_queries".to_string()) + profile::dump(&tcx.sess, "profile_queries".to_string()) } translation diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8c0e89716cff..f6aa58213fc9 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -914,7 +914,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { pub fn enable_save_analysis(control: &mut CompileController) { control.keep_ast = true; control.after_analysis.callback = box |state| { - time(state.session.time_passes(), "save analysis", || { + time(state.session, "save analysis", || { save::process_crate(state.tcx.unwrap(), state.expanded_crate.unwrap(), state.analysis.unwrap(), diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs index 061077d05a43..a362556717bd 100644 --- a/src/librustc_driver/profile/mod.rs +++ b/src/librustc_driver/profile/mod.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc::session::Session; use rustc::util::common::{ProfQDumpParams, ProfileQueriesMsg, profq_msg, profq_set_chan}; use std::sync::mpsc::{Receiver}; use std::io::{Write}; @@ -17,11 +18,11 @@ use std::time::{Duration, Instant}; pub mod trace; /// begin a profile thread, if not already running -pub fn begin() { +pub fn begin(sess: &Session) { use std::thread; use std::sync::mpsc::{channel}; let (tx, rx) = channel(); - if profq_set_chan(tx) { + if profq_set_chan(sess, tx) { thread::spawn(move||profile_queries_thread(rx)); } } @@ -30,7 +31,7 @@ pub fn begin() { /// wait for this dump to complete. /// /// wraps the RPC (send/recv channel logic) of requesting a dump. -pub fn dump(path:String) { +pub fn dump(sess: &Session, path: String) { use std::sync::mpsc::{channel}; let (tx, rx) = channel(); let params = ProfQDumpParams{ @@ -39,7 +40,7 @@ pub fn dump(path:String) { // is written; false for now dump_profq_msg_log:true, }; - profq_msg(ProfileQueriesMsg::Dump(params)); + profq_msg(sess, ProfileQueriesMsg::Dump(params)); let _ = rx.recv().unwrap(); } diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 0e6d328d947b..38468e29427b 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -14,7 +14,7 @@ use rustc::dep_graph::{PreviousDepGraph, SerializedDepGraph}; use rustc::session::Session; use rustc::ty::TyCtxt; use rustc::ty::maps::OnDiskCache; -use rustc::util::common::time; +use rustc::util::common::time_ext; use rustc_serialize::Decodable as RustcDecodable; use rustc_serialize::opaque::Decoder; use std::path::Path; @@ -147,12 +147,14 @@ impl MaybeAsync { } /// Launch a thread and load the dependency graph in the background. -pub fn load_dep_graph(sess: &Session, time_passes: bool) -> +pub fn load_dep_graph(sess: &Session) -> MaybeAsync> { // Since `sess` isn't `Sync`, we perform all accesses to `sess` // before we fire the background thread. + let time_passes = sess.time_passes(); + if sess.opts.incremental.is_none() { // No incremental compilation. return MaybeAsync::Sync(LoadResult::Ok { @@ -167,7 +169,7 @@ pub fn load_dep_graph(sess: &Session, time_passes: bool) -> let expected_hash = sess.opts.dep_tracking_hash(); MaybeAsync::Async(std::thread::spawn(move || { - time(time_passes, "background load prev dep-graph", move || { + time_ext(time_passes, None, "background load prev dep-graph", move || { match load_data(report_incremental_info, &path) { LoadResult::DataOutOfDate => LoadResult::DataOutOfDate, LoadResult::Error { message } => LoadResult::Error { message }, diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index d44d1d6f2602..ca1e3563089d 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -33,14 +33,14 @@ pub fn save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { return; } - time(sess.time_passes(), "persist query result cache", || { + time(sess, "persist query result cache", || { save_in(sess, query_cache_path(sess), |e| encode_query_cache(tcx, e)); }); if tcx.sess.opts.debugging_opts.incremental_queries { - time(sess.time_passes(), "persist dep-graph", || { + time(sess, "persist dep-graph", || { save_in(sess, dep_graph_path(sess), |e| encode_dep_graph(tcx, e)); diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 636b3984117d..8984a6bfd60e 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -690,7 +690,7 @@ fn link_natively(sess: &Session, let mut i = 0; loop { i += 1; - prog = time(sess.time_passes(), "running linker", || { + prog = time(sess, "running linker", || { exec_linker(sess, &mut cmd, tmpdir) }); let output = match prog { @@ -1317,7 +1317,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, let name = cratepath.file_name().unwrap().to_str().unwrap(); let name = &name[3..name.len() - 5]; // chop off lib/.rlib - time(sess.time_passes(), &format!("altering {}.rlib", name), || { + time(sess, &format!("altering {}.rlib", name), || { let cfg = archive_config(sess, &dst, Some(cratepath)); let mut archive = ArchiveBuilder::new(cfg); archive.update_symbols(); diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs index f79651cef3ec..2a473f1ecbcc 100644 --- a/src/librustc_trans/back/lto.rs +++ b/src/librustc_trans/back/lto.rs @@ -19,7 +19,7 @@ use llvm; use rustc::hir::def_id::LOCAL_CRATE; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config::{self, Lto}; -use rustc::util::common::time; +use rustc::util::common::time_ext; use time_graph::Timeline; use {ModuleTranslation, ModuleLlvm, ModuleKind, ModuleSource}; @@ -172,7 +172,7 @@ pub(crate) fn run(cgcx: &CodegenContext, info!("adding bytecode {}", name); let bc_encoded = data.data(); - let (bc, id) = time(cgcx.time_passes, &format!("decode {}", name), || { + let (bc, id) = time_ext(cgcx.time_passes, None, &format!("decode {}", name), || { match DecodedBytecode::new(bc_encoded) { Ok(b) => Ok((b.bytecode(), b.identifier().to_string())), Err(e) => Err(diag_handler.fatal(&e)), @@ -253,7 +253,7 @@ fn fat_lto(cgcx: &CodegenContext, let mut linker = Linker::new(llmod); for (bc_decoded, name) in serialized_modules { info!("linking {:?}", name); - time(cgcx.time_passes, &format!("ll link {:?}", name), || { + time_ext(cgcx.time_passes, None, &format!("ll link {:?}", name), || { let data = bc_decoded.data(); linker.add(&data).map_err(|()| { let msg = format!("failed to load bc of {:?}", name); @@ -498,7 +498,7 @@ fn run_pass_manager(cgcx: &CodegenContext, assert!(!pass.is_null()); llvm::LLVMRustAddPass(pm, pass); - time(cgcx.time_passes, "LTO passes", || + time_ext(cgcx.time_passes, None, "LTO passes", || llvm::LLVMRunPassManager(pm, llmod)); llvm::LLVMDisposePassManager(pm); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index c0561ff0c173..7651a8e748e3 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -31,7 +31,8 @@ use {CrateTranslation, ModuleSource, ModuleTranslation, CompiledModule, ModuleKi use CrateInfo; use rustc::hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc::ty::TyCtxt; -use rustc::util::common::{time, time_depth, set_time_depth, path2cstr, print_time_passes_entry}; +use rustc::util::common::{time_ext, time_depth, set_time_depth, print_time_passes_entry}; +use rustc::util::common::path2cstr; use rustc::util::fs::{link_or_copy}; use errors::{self, Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId}; use errors::emitter::{Emitter}; @@ -563,11 +564,19 @@ unsafe fn optimize(cgcx: &CodegenContext, diag_handler.abort_if_errors(); // Finally, run the actual optimization passes - time(config.time_passes, &format!("llvm function passes [{}]", module_name.unwrap()), || - llvm::LLVMRustRunFunctionPassManager(fpm, llmod)); + time_ext(config.time_passes, + None, + &format!("llvm function passes [{}]", module_name.unwrap()), + || { + llvm::LLVMRustRunFunctionPassManager(fpm, llmod) + }); timeline.record("fpm"); - time(config.time_passes, &format!("llvm module passes [{}]", module_name.unwrap()), || - llvm::LLVMRunPassManager(mpm, llmod)); + time_ext(config.time_passes, + None, + &format!("llvm module passes [{}]", module_name.unwrap()), + || { + llvm::LLVMRunPassManager(mpm, llmod) + }); // Deallocate managers that we're now done with llvm::LLVMDisposePassManager(fpm); @@ -682,7 +691,7 @@ unsafe fn codegen(cgcx: &CodegenContext, } } - time(config.time_passes, &format!("codegen passes [{}]", module_name.unwrap()), + time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()), || -> Result<(), FatalError> { if config.emit_ir { let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 49a5b7ac8b90..76e05ae7dcb8 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -712,7 +712,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Translate the metadata. let llmod_id = "metadata"; let (metadata_llcx, metadata_llmod, metadata) = - time(tcx.sess.time_passes(), "write metadata", || { + time(tcx.sess, "write metadata", || { write_metadata(tcx, llmod_id, &link_meta) }); @@ -790,7 +790,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, llcx, tm: create_target_machine(tcx.sess), }; - time(tcx.sess.time_passes(), "write allocator module", || { + time(tcx.sess, "write allocator module", || { allocator::trans(tcx, &modules, kind) }); @@ -924,11 +924,11 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn assert_and_save_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - time(tcx.sess.time_passes(), + time(tcx.sess, "assert dep graph", || rustc_incremental::assert_dep_graph(tcx)); - time(tcx.sess.time_passes(), + time(tcx.sess, "serialize dep graph", || rustc_incremental::save_dep_graph(tcx)); } @@ -939,7 +939,6 @@ fn collect_and_partition_translation_items<'a, 'tcx>( ) -> (Arc, Arc>>>) { assert_eq!(cnum, LOCAL_CRATE); - let time_passes = tcx.sess.time_passes(); let collection_mode = match tcx.sess.opts.debugging_opts.print_trans_items { Some(ref s) => { @@ -968,7 +967,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>( }; let (items, inlining_map) = - time(time_passes, "translation item collection", || { + time(tcx.sess, "translation item collection", || { collector::collect_crate_mono_items(tcx, collection_mode) }); @@ -982,7 +981,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>( PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units()) }; - let codegen_units = time(time_passes, "codegen unit partitioning", || { + let codegen_units = time(tcx.sess, "codegen unit partitioning", || { partitioning::partition(tcx, items.iter().cloned(), strategy, diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 74df5127269a..39eb38658fee 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -238,7 +238,7 @@ impl TransCrate for LlvmTransCrate { back::write::dump_incremental_data(&trans); } - time(sess.time_passes(), + time(sess, "serialize work products", move || rustc_incremental::save_work_products(sess, &dep_graph)); @@ -251,7 +251,7 @@ impl TransCrate for LlvmTransCrate { // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. - time(sess.time_passes(), "linking", || { + time(sess, "linking", || { back::link::link_binary(sess, &trans, outputs, &trans.crate_name.as_str()); }); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 40385cabf566..49a23f14338b 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -315,41 +315,39 @@ pub fn provide(providers: &mut Providers) { pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Result<(), CompileIncomplete> { - let time_passes = tcx.sess.time_passes(); - // this ensures that later parts of type checking can assume that items // have valid types and not error tcx.sess.track_errors(|| { - time(time_passes, "type collecting", || + time(tcx.sess, "type collecting", || collect::collect_item_types(tcx)); })?; tcx.sess.track_errors(|| { - time(time_passes, "outlives testing", || + time(tcx.sess, "outlives testing", || outlives::test::test_inferred_outlives(tcx)); })?; tcx.sess.track_errors(|| { - time(time_passes, "impl wf inference", || + time(tcx.sess, "impl wf inference", || impl_wf_check::impl_wf_check(tcx)); })?; tcx.sess.track_errors(|| { - time(time_passes, "coherence checking", || + time(tcx.sess, "coherence checking", || coherence::check_coherence(tcx)); })?; tcx.sess.track_errors(|| { - time(time_passes, "variance testing", || + time(tcx.sess, "variance testing", || variance::test::test_variance(tcx)); })?; - time(time_passes, "wf checking", || check::check_wf_new(tcx))?; + time(tcx.sess, "wf checking", || check::check_wf_new(tcx))?; - time(time_passes, "item-types checking", || check::check_item_types(tcx))?; + time(tcx.sess, "item-types checking", || check::check_item_types(tcx))?; - time(time_passes, "item-bodies checking", || check::check_item_bodies(tcx))?; + time(tcx.sess, "item-bodies checking", || check::check_item_bodies(tcx))?; check_unused::check_crate(tcx); check_for_entry_fn(tcx); From 59199ebe51d44e120dfd3f75dbcaf154afb70e13 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 9 Mar 2018 10:04:27 +0000 Subject: [PATCH 076/830] test: remove duplicate ignore-aarch64 from stack-probes test --- src/test/codegen/stack-probes.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs index 4a489f1edb3b..45bcedd866f9 100644 --- a/src/test/codegen/stack-probes.rs +++ b/src/test/codegen/stack-probes.rs @@ -11,7 +11,6 @@ // ignore-arm // ignore-aarch64 // ignore-powerpc -// ignore-aarch64 // ignore-wasm // ignore-emscripten // ignore-windows From bceb94e8b7ba7efbeed95e080a753826cb18e89b Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 9 Mar 2018 10:05:05 +0000 Subject: [PATCH 077/830] test: ignore stack probe tests on mips* --- src/test/codegen/stack-probes.rs | 2 ++ src/test/run-pass/stack-probes-lto.rs | 2 ++ src/test/run-pass/stack-probes.rs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs index 45bcedd866f9..af400ff3bcbd 100644 --- a/src/test/codegen/stack-probes.rs +++ b/src/test/codegen/stack-probes.rs @@ -10,6 +10,8 @@ // ignore-arm // ignore-aarch64 +// ignore-mips +// ignore-mips64 // ignore-powerpc // ignore-wasm // ignore-emscripten diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/run-pass/stack-probes-lto.rs index 4deced1297bd..e7fa3bc0a75c 100644 --- a/src/test/run-pass/stack-probes-lto.rs +++ b/src/test/run-pass/stack-probes-lto.rs @@ -10,6 +10,8 @@ // ignore-arm // ignore-aarch64 +// ignore-mips +// ignore-mips64 // ignore-wasm // ignore-cloudabi no processes // ignore-emscripten no processes diff --git a/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs index 4224a65ffd7c..67b3962ee5fb 100644 --- a/src/test/run-pass/stack-probes.rs +++ b/src/test/run-pass/stack-probes.rs @@ -10,6 +10,8 @@ // ignore-arm // ignore-aarch64 +// ignore-mips +// ignore-mips64 // ignore-wasm // ignore-cloudabi no processes // ignore-emscripten no processes From e0863c5155138abeb2cae8d2b7bbd60dc700eef6 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 9 Mar 2018 10:14:33 +0000 Subject: [PATCH 078/830] test: ignore mips* in x86_mmx test --- src/test/codegen/x86_mmx.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/codegen/x86_mmx.rs b/src/test/codegen/x86_mmx.rs index dc9f63c35db2..30777c6214ec 100644 --- a/src/test/codegen/x86_mmx.rs +++ b/src/test/codegen/x86_mmx.rs @@ -11,6 +11,8 @@ // ignore-arm // ignore-aarch64 // ignore-emscripten +// ignore-mips +// ignore-mips64 // compile-flags: -O #![feature(repr_simd)] From 54467ae319de2d23819df897d1813e267e4a3097 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 9 Mar 2018 10:15:45 +0000 Subject: [PATCH 079/830] test: ignore asm tests on mips* which won't work "mov" is not a valid assembly mnemonic on mips. --- src/test/compile-fail/asm-bad-clobber.rs | 2 ++ src/test/compile-fail/asm-in-bad-modifier.rs | 2 ++ src/test/compile-fail/asm-misplaced-option.rs | 2 ++ src/test/compile-fail/asm-out-no-modifier.rs | 2 ++ src/test/compile-fail/asm-out-read-uninit.rs | 2 ++ 5 files changed, 10 insertions(+) diff --git a/src/test/compile-fail/asm-bad-clobber.rs b/src/test/compile-fail/asm-bad-clobber.rs index b863e90a3b71..aa77e7f46e50 100644 --- a/src/test/compile-fail/asm-bad-clobber.rs +++ b/src/test/compile-fail/asm-bad-clobber.rs @@ -15,6 +15,8 @@ // ignore-emscripten // ignore-powerpc // ignore-sparc +// ignore-mips +// ignore-mips64 #![feature(asm, rustc_attrs)] diff --git a/src/test/compile-fail/asm-in-bad-modifier.rs b/src/test/compile-fail/asm-in-bad-modifier.rs index cae41332795d..5e9278c7c35f 100644 --- a/src/test/compile-fail/asm-in-bad-modifier.rs +++ b/src/test/compile-fail/asm-in-bad-modifier.rs @@ -12,6 +12,8 @@ // ignore-emscripten // ignore-powerpc // ignore-sparc +// ignore-mips +// ignore-mips64 #![feature(asm)] diff --git a/src/test/compile-fail/asm-misplaced-option.rs b/src/test/compile-fail/asm-misplaced-option.rs index e634238c6e17..abd55ea10118 100644 --- a/src/test/compile-fail/asm-misplaced-option.rs +++ b/src/test/compile-fail/asm-misplaced-option.rs @@ -15,6 +15,8 @@ // ignore-emscripten // ignore-powerpc // ignore-sparc +// ignore-mips +// ignore-mips64 #![feature(asm, rustc_attrs)] diff --git a/src/test/compile-fail/asm-out-no-modifier.rs b/src/test/compile-fail/asm-out-no-modifier.rs index 2e843ddac822..55d8970008f9 100644 --- a/src/test/compile-fail/asm-out-no-modifier.rs +++ b/src/test/compile-fail/asm-out-no-modifier.rs @@ -12,6 +12,8 @@ // ignore-emscripten // ignore-powerpc // ignore-sparc +// ignore-mips +// ignore-mips64 #![feature(asm)] diff --git a/src/test/compile-fail/asm-out-read-uninit.rs b/src/test/compile-fail/asm-out-read-uninit.rs index 02462bf1be7d..c606c5a80e58 100644 --- a/src/test/compile-fail/asm-out-read-uninit.rs +++ b/src/test/compile-fail/asm-out-read-uninit.rs @@ -12,6 +12,8 @@ // ignore-emscripten // ignore-powerpc // ignore-sparc +// ignore-mips +// ignore-mips64 // revisions: ast mir //[mir]compile-flags: -Z borrowck=mir From fb806fd9db4012e0697d7d30cd034458e17e9fa0 Mon Sep 17 00:00:00 2001 From: James Cowgill Date: Fri, 9 Mar 2018 10:18:19 +0000 Subject: [PATCH 080/830] test: fix repr-transparent-aggregates test on mips64 Since #47964 was merged, 64-bit mips started passing all structures using 64-bit chunks regardless of their contents. The repr-transparent-aggregates tests needs updating to cope with this. --- .../codegen/repr-transparent-aggregates-2.rs | 1 + .../codegen/repr-transparent-aggregates-3.rs | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/test/codegen/repr-transparent-aggregates-3.rs diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs index e6374928a5cb..9605ded569ef 100644 --- a/src/test/codegen/repr-transparent-aggregates-2.rs +++ b/src/test/codegen/repr-transparent-aggregates-2.rs @@ -12,6 +12,7 @@ // ignore-aarch64 // ignore-asmjs +// ignore-mips64 // ignore-s390x // ignore-wasm // ignore-x86 diff --git a/src/test/codegen/repr-transparent-aggregates-3.rs b/src/test/codegen/repr-transparent-aggregates-3.rs new file mode 100644 index 000000000000..0c90239c9de8 --- /dev/null +++ b/src/test/codegen/repr-transparent-aggregates-3.rs @@ -0,0 +1,49 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +// only-mips64 +// See repr-transparent.rs + +#![crate_type="lib"] +#![feature(repr_transparent)] + + +#[repr(C)] +pub struct Big([u32; 16]); + +#[repr(transparent)] +pub struct BigW(Big); + +// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [8 x i64] +#[no_mangle] +pub extern fn test_Big(_: Big) -> Big { loop {} } + +// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [8 x i64] +#[no_mangle] +pub extern fn test_BigW(_: BigW) -> BigW { loop {} } + + +#[repr(C)] +pub union BigU { + foo: [u32; 16], +} + +#[repr(transparent)] +pub struct BigUw(BigU); + +// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [8 x i64] +#[no_mangle] +pub extern fn test_BigU(_: BigU) -> BigU { loop {} } + +// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [8 x i64] +#[no_mangle] +pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} } From a63bf3bb10117af94cc8189e9f228a81da5b432d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 9 Mar 2018 14:08:59 +0100 Subject: [PATCH 081/830] Add missing urls --- src/liballoc/vec.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 2f57c53a6d83..1bb2bed463b0 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1212,8 +1212,9 @@ impl Vec { /// difference, with each additional slot filled with `value`. /// 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`]. + /// This method requires [`Clone`] to be able clone the passed value. If + /// you'd rather create a value with [`Default`] instead, see + /// [`resize_default`]. /// /// # Examples /// @@ -1227,6 +1228,8 @@ impl Vec { /// assert_eq!(vec, [1, 2]); /// ``` /// + /// [`Clone`]: ../../std/clone/trait.Clone.html + /// [`Default`]: ../../std/default/trait.Default.html /// [`resize_default`]: #method.resize_default #[stable(feature = "vec_resize", since = "1.5.0")] pub fn resize(&mut self, new_len: usize, value: T) { @@ -1244,7 +1247,7 @@ impl Vec { /// Iterates over the slice `other`, clones each element, and then appends /// it to this `Vec`. The `other` vector is traversed in-order. /// - /// Note that this function is same as `extend` except that it is + /// Note that this function is same as [`extend`] except that it is /// specialized to work with slices instead. If and when Rust gets /// specialization this function will likely be deprecated (but still /// available). @@ -1256,6 +1259,8 @@ impl Vec { /// vec.extend_from_slice(&[2, 3, 4]); /// assert_eq!(vec, [1, 2, 3, 4]); /// ``` + /// + /// [`extend`]: #method.extend #[stable(feature = "vec_extend_from_slice", since = "1.6.0")] pub fn extend_from_slice(&mut self, other: &[T]) { self.spec_extend(other.iter()) @@ -1266,12 +1271,11 @@ 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()`. + /// 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`]. - /// + /// This method uses [`Default`] to create new values on every push. If + /// you'd rather [`Clone`] a given value, use [`resize`]. /// /// # Examples /// @@ -1288,6 +1292,9 @@ impl Vec { /// ``` /// /// [`resize`]: #method.resize + /// [`Default::default()`]: ../../std/default/trait.Default.html#tymethod.default + /// [`Default`]: ../../std/default/trait.Default.html + /// [`Clone`]: ../../std/clone/trait.Clone.html #[unstable(feature = "vec_resize_default", issue = "41758")] pub fn resize_default(&mut self, new_len: usize) { let len = self.len(); From 1dbce4b0afb8f76eb7cd7aad0e3c34d4f7fc2274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= Date: Fri, 9 Mar 2018 14:53:15 +0100 Subject: [PATCH 082/830] Make the default relro level be doing nothing at all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johannes Löthberg --- src/librustc_back/lib.rs | 4 ++++ src/librustc_back/target/mod.rs | 2 +- src/librustc_trans/back/link.rs | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 9de56cca3394..9baee2677099 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -131,6 +131,7 @@ pub enum RelroLevel { Full, Partial, Off, + None, } impl RelroLevel { @@ -139,6 +140,7 @@ impl RelroLevel { RelroLevel::Full => "full", RelroLevel::Partial => "partial", RelroLevel::Off => "off", + RelroLevel::None => "none", } } } @@ -151,6 +153,7 @@ impl FromStr for RelroLevel { "full" => Ok(RelroLevel::Full), "partial" => Ok(RelroLevel::Partial), "off" => Ok(RelroLevel::Off), + "none" => Ok(RelroLevel::None), _ => Err(()), } } @@ -162,6 +165,7 @@ impl ToJson for RelroLevel { RelroLevel::Full => "full".to_json(), RelroLevel::Partial => "partial".to_json(), RelroLevel::Off => "off".to_json(), + RelroLevel::None => "None".to_json(), } } } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 0a3e1826f3a1..250d85d45203 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -514,7 +514,7 @@ impl Default for TargetOptions { has_rpath: false, no_default_libraries: true, position_independent_executables: false, - relro_level: RelroLevel::Off, + relro_level: RelroLevel::None, pre_link_objects_exe: Vec::new(), pre_link_objects_dll: Vec::new(), post_link_objects: Vec::new(), diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 56b845c30493..235a95f63e4c 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1017,6 +1017,8 @@ fn link_args(cmd: &mut Linker, RelroLevel::Off => { cmd.no_relro(); }, + RelroLevel::None => { + }, } // Pass optimization flags down to the linker. From c1a73d2f4a8ef0003b93c4307930438be4aae9a5 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 9 Mar 2018 17:11:06 +0300 Subject: [PATCH 083/830] tidy: Add a check for stray `.stderr` and `.stdout` files in UI test directories --- .../ex3-both-anon-regions-4.stderr | 19 ------ .../propagate-approximated-to-empty.stderr | 45 -------------- src/test/ui/resolve-error.stderr | 62 ------------------- src/test/ui/span/loan-extend.stderr | 14 ----- src/tools/tidy/src/lib.rs | 1 + src/tools/tidy/src/main.rs | 1 + src/tools/tidy/src/ui_tests.rs | 26 ++++++++ 7 files changed, 28 insertions(+), 140 deletions(-) delete mode 100644 src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr delete mode 100644 src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr delete mode 100644 src/test/ui/resolve-error.stderr delete mode 100644 src/test/ui/span/loan-extend.stderr create mode 100644 src/tools/tidy/src/ui_tests.rs diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr deleted file mode 100644 index 19339800a7a9..000000000000 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-4.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0623]: lifetime mismatch - --> $DIR/ex3-both-anon-regions-4.rs:12:13 - | -11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { - | --- --- these references are declared with different lifetimes... -12 | z.push((x,y)); - | ^ ...but data flows into `z` here - -error[E0623]: lifetime mismatch - --> $DIR/ex3-both-anon-regions-4.rs:12:15 - | -11 | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { - | --- --- these references are declared with different lifetimes... -12 | z.push((x,y)); - | ^ ...but data flows into `z` here - -error: aborting due to 2 previous errors - -If you want more information on this error, try using "rustc --explain E0623" diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr deleted file mode 100644 index 502b344c89e4..000000000000 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-to-empty.stderr +++ /dev/null @@ -1,45 +0,0 @@ -warning: not reporting region error due to -Znll - --> $DIR/propagate-approximated-to-empty.rs:41:9 - | -41 | demand_y(x, y, x.get()) - | ^^^^^^^^^^^^^^^^^^^^^^^ - -error: free region `'_#6r` does not outlive free region `'_#4r` - --> $DIR/propagate-approximated-to-empty.rs:41:18 - | -41 | demand_y(x, y, x.get()) - | ^ - -note: No external requirements - --> $DIR/propagate-approximated-to-empty.rs:39:47 - | -39 | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | _______________________________________________^ -40 | | // Only works if 'x: 'y: -41 | | demand_y(x, y, x.get()) -42 | | //~^ WARN not reporting region error due to -Znll -43 | | //~| ERROR free region `'_#6r` does not outlive free region `'_#4r` -44 | | }); - | |_____^ - | - = note: defining type: DefId(0/1:18 ~ propagate_approximated_to_empty[317d]::supply[0]::{{closure}}[0]) with closure substs [ - i16, - for<'r, 's, 't0, 't1, 't2> extern "rust-call" fn((&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 'r)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) &'_#1r u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't0)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't1)) u32>, &ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 't2)) std::cell::Cell<&ReLateBound(DebruijnIndex { depth: 1 }, BrNamed(crate0:DefIndex(0:0), 's)) u32>)) - ] - -note: No external requirements - --> $DIR/propagate-approximated-to-empty.rs:38:1 - | -38 | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { -39 | | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { -40 | | // Only works if 'x: 'y: -41 | | demand_y(x, y, x.get()) -... | -44 | | }); -45 | | } - | |_^ - | - = note: defining type: DefId(0/0:6 ~ propagate_approximated_to_empty[317d]::supply[0]) with substs [] - -error: aborting due to previous error - diff --git a/src/test/ui/resolve-error.stderr b/src/test/ui/resolve-error.stderr deleted file mode 100644 index 27f93939246c..000000000000 --- a/src/test/ui/resolve-error.stderr +++ /dev/null @@ -1,62 +0,0 @@ -error: cannot find derive macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:37:10 - | -37 | #[derive(FooWithLongNan)] - | ^^^^^^^^^^^^^^ help: try: `FooWithLongName` - -error: cannot find attribute macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:40:3 - | -40 | #[attr_proc_macra] - | ^^^^^^^^^^^^^^^ help: try: `attr_proc_macro` - -error: cannot find attribute macro `FooWithLongNan` in this scope - --> $DIR/resolve-error.rs:43:3 - | -43 | #[FooWithLongNan] - | ^^^^^^^^^^^^^^ - -error: cannot find derive macro `Dlone` in this scope - --> $DIR/resolve-error.rs:46:10 - | -46 | #[derive(Dlone)] - | ^^^^^ help: try: `Clone` - -error: cannot find derive macro `Dlona` in this scope - --> $DIR/resolve-error.rs:49:10 - | -49 | #[derive(Dlona)] - | ^^^^^ help: try: `Clona` - -error: cannot find derive macro `attr_proc_macra` in this scope - --> $DIR/resolve-error.rs:52:10 - | -52 | #[derive(attr_proc_macra)] - | ^^^^^^^^^^^^^^^ - -error: cannot find macro `FooWithLongNama!` in this scope - --> $DIR/resolve-error.rs:56:5 - | -56 | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam!` - -error: cannot find macro `attr_proc_macra!` in this scope - --> $DIR/resolve-error.rs:58:5 - | -58 | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac!` - -error: cannot find macro `Dlona!` in this scope - --> $DIR/resolve-error.rs:60:5 - | -60 | Dlona!(); - | ^^^^^ - -error: cannot find macro `bang_proc_macrp!` in this scope - --> $DIR/resolve-error.rs:62:5 - | -62 | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro!` - -error: aborting due to previous error(s) - diff --git a/src/test/ui/span/loan-extend.stderr b/src/test/ui/span/loan-extend.stderr deleted file mode 100644 index af498129fc44..000000000000 --- a/src/test/ui/span/loan-extend.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0597]: `short` does not live long enough - --> $DIR/loan-extend.rs:21:1 - | -19 | long = borrow(&mut short); - | ----- borrow occurs here -20 | -21 | } - | ^ `short` dropped here while still borrowed - | - = note: values in a scope are dropped in the opposite order they are created - -error: aborting due to previous error - -If you want more information on this error, try using "rustc --explain E0597" diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index c927ff19b279..06eb055f68e0 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -51,6 +51,7 @@ pub mod features; pub mod cargo; pub mod pal; pub mod deps; +pub mod ui_tests; pub mod unstable_book; fn filter_dirs(path: &Path) -> bool { diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index afa3ebd19831..249741927956 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -45,6 +45,7 @@ fn main() { deps::check(&path, &mut bad); } deps::check_whitelist(&path, &cargo, &mut bad); + ui_tests::check(&path, &mut bad); if bad { eprintln!("some tidy checks failed"); diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs new file mode 100644 index 000000000000..f7fec2e667ab --- /dev/null +++ b/src/tools/tidy/src/ui_tests.rs @@ -0,0 +1,26 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Tidy check to ensure that there are no stray `.stderr` files in UI test directories. + +use std::path::Path; + +pub fn check(path: &Path, bad: &mut bool) { + super::walk_many(&[&path.join("test/ui"), &path.join("test/ui-fulldeps")], + &mut |_| false, + &mut |file_path| { + if let Some(ext) = file_path.extension() { + if (ext == "stderr" || ext == "stdout") && !file_path.with_extension("rs").exists() { + println!("Stray file with UI testing output: {:?}", file_path); + *bad = true; + } + } + }); +} From 580467d3065c5520dbe6c8318a1a0e3519b01a3a Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Sun, 4 Mar 2018 21:47:39 -0500 Subject: [PATCH 084/830] Rename BorrowData::location to BorrowData::reserve_location in preparation for rewritting two phase borrow support --- src/librustc_mir/borrow_check/error_reporting.rs | 6 +++--- src/librustc_mir/dataflow/impls/borrows.rs | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 77a3f138fe59..a47ced010e60 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -250,7 +250,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let new_closure_span = self.find_closure_span(span, context.loc); let span = new_closure_span.map(|(args, _)| args).unwrap_or(span); - let old_closure_span = self.find_closure_span(issued_span, issued_borrow.location); + let old_closure_span = self.find_closure_span(issued_span, issued_borrow.reserve_location); let issued_span = old_closure_span .map(|(args, _)| args) .unwrap_or(issued_span); @@ -380,7 +380,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { .last() .unwrap(); - let borrow_span = self.mir.source_info(borrow.location).span; + let borrow_span = self.mir.source_info(borrow.reserve_location).span; let proper_span = match *root_place { Place::Local(local) => self.mir.local_decls[local].source_info.span, _ => drop_span, @@ -817,7 +817,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // Retrieve span of given borrow from the current MIR representation pub fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span { - self.mir.source_info(borrow.location).span + self.mir.source_info(borrow.reserve_location).span } // Retrieve type of a place for the current MIR representation diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index a150335a1ae4..859618d27b33 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -111,7 +111,9 @@ impl<'a, 'gcx, 'tcx> ActiveBorrows<'a, 'gcx, 'tcx> { #[allow(dead_code)] #[derive(Debug)] pub struct BorrowData<'tcx> { - pub(crate) location: Location, + /// Location where the borrow reservation starts. + /// In many cases, this will be equal to the activation location but not always. + pub(crate) reserve_location: Location, pub(crate) kind: mir::BorrowKind, pub(crate) region: Region<'tcx>, pub(crate) borrowed_place: mir::Place<'tcx>, @@ -209,7 +211,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { if is_unsafe_place(self.tcx, self.mir, borrowed_place) { return; } let borrow = BorrowData { - location, kind, region, + reserve_location: location, + kind, region, borrowed_place: borrowed_place.clone(), assigned_place: assigned_place.clone(), }; @@ -245,7 +248,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { let mut found_it = false; for idx in &self.region_map[region] { let bd = &self.idx_vec[*idx]; - if bd.location == location && + if bd.reserve_location == location && bd.kind == kind && bd.region == region && bd.borrowed_place == *place @@ -277,7 +280,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { pub fn scope_tree(&self) -> &Lrc { &self.scope_tree } pub fn location(&self, idx: BorrowIndex) -> &Location { - &self.borrows[idx].location + &self.borrows[idx].reserve_location } /// Add all borrows to the kill set, if those borrows are out of scope at `location`. From 138365368a71a04ff9539704f478b014379b7ee5 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Mon, 5 Mar 2018 02:44:10 -0500 Subject: [PATCH 085/830] Finally start down the right path --- .../borrow_check/error_reporting.rs | 6 +- src/librustc_mir/borrow_check/flows.rs | 7 +- src/librustc_mir/borrow_check/mod.rs | 53 +- src/librustc_mir/dataflow/impls/borrows.rs | 716 +++++++++--------- src/librustc_mir/dataflow/mod.rs | 41 +- ...o-phase-activation-sharing-interference.rs | 4 +- ...o-phase-allow-access-during-reservation.rs | 6 +- .../borrowck/two-phase-nonrecv-autoref.rs | 16 +- ...-phase-reservation-sharing-interference.rs | 9 +- 9 files changed, 427 insertions(+), 431 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index a47ced010e60..7ab52e98a0ee 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -18,7 +18,7 @@ use rustc_data_structures::sync::Lrc; use super::{Context, MirBorrowckCtxt}; use super::{InitializationRequiringAction, PrefixSet}; -use dataflow::{ActiveBorrows, BorrowData, FlowAtLocation, MovingOutStatements}; +use dataflow::{Borrows, BorrowData, FlowAtLocation, MovingOutStatements}; use dataflow::move_paths::MovePathIndex; use util::borrowck_errors::{BorrowckErrors, Origin}; @@ -372,10 +372,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { context: Context, borrow: &BorrowData<'tcx>, drop_span: Span, - borrows: &ActiveBorrows<'cx, 'gcx, 'tcx>, + borrows: &Borrows<'cx, 'gcx, 'tcx> ) { let end_span = borrows.opt_region_end_span(&borrow.region); - let scope_tree = borrows.0.scope_tree(); + let scope_tree = borrows.scope_tree(); let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All) .last() .unwrap(); diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs index ba966c9d4e31..ceff380c594e 100644 --- a/src/librustc_mir/borrow_check/flows.rs +++ b/src/librustc_mir/borrow_check/flows.rs @@ -17,13 +17,14 @@ use rustc::mir::{BasicBlock, Location}; use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use dataflow::{EverInitializedPlaces, MovingOutStatements}; -use dataflow::{ActiveBorrows, FlowAtLocation, FlowsAtLocation}; +use dataflow::{Borrows}; +use dataflow::{FlowAtLocation, FlowsAtLocation}; use dataflow::move_paths::HasMoveData; use std::fmt; // (forced to be `pub` due to its use as an associated type below.) pub(crate) struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> { - pub borrows: FlowAtLocation>, + pub borrows: FlowAtLocation>, pub inits: FlowAtLocation>, pub uninits: FlowAtLocation>, pub move_outs: FlowAtLocation>, @@ -32,7 +33,7 @@ pub(crate) struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> { impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> { pub fn new( - borrows: FlowAtLocation>, + borrows: FlowAtLocation>, inits: FlowAtLocation>, uninits: FlowAtLocation>, move_outs: FlowAtLocation>, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index e51b16a37361..3f111ebcb780 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -34,11 +34,10 @@ use syntax_pos::Span; use dataflow::{do_dataflow, DebugFormatted}; use dataflow::FlowAtLocation; use dataflow::MoveDataParamEnv; -use dataflow::{DataflowAnalysis, DataflowResultsConsumer}; +use dataflow::{DataflowResultsConsumer}; use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use dataflow::{EverInitializedPlaces, MovingOutStatements}; use dataflow::{BorrowData, Borrows, ReserveOrActivateIndex}; -use dataflow::{ActiveBorrows, Reservations}; use dataflow::indexes::BorrowIndex; use dataflow::move_paths::{IllegalMoveOriginKind, MoveError}; use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex}; @@ -54,8 +53,6 @@ mod error_reporting; mod flows; mod prefixes; -use std::borrow::Cow; - pub(crate) mod nll; pub fn provide(providers: &mut Providers) { @@ -209,6 +206,18 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( }; let flow_inits = flow_inits; // remove mut + let flow_borrows = FlowAtLocation::new(do_dataflow( + tcx, + mir, + id, + &attributes, + &dead_unwinds, + Borrows::new(tcx, mir, opt_regioncx.clone(), def_id, body_id), + |rs, i| { + DebugFormatted::new(&(i.kind(), rs.location(i.borrow_index()))) + } + )); + let movable_generator = !match tcx.hir.get(id) { hir::map::Node::NodeExpr(&hir::Expr { node: hir::ExprClosure(.., Some(hir::GeneratorMovability::Static)), @@ -230,44 +239,12 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( }, access_place_error_reported: FxHashSet(), reservation_error_reported: FxHashSet(), - nonlexical_regioncx: opt_regioncx.clone(), + nonlexical_regioncx: opt_regioncx, nonlexical_cause_info: None, }; - let borrows = Borrows::new(tcx, mir, opt_regioncx, def_id, body_id); - let flow_reservations = do_dataflow( - tcx, - mir, - id, - &attributes, - &dead_unwinds, - Reservations::new(borrows), - |rs, i| { - // In principle we could make the dataflow ensure that - // only reservation bits show up, and assert so here. - // - // In practice it is easier to be looser; in particular, - // it is okay for the kill-sets to hold activation bits. - DebugFormatted::new(&(i.kind(), rs.location(i))) - }, - ); - let flow_active_borrows = { - let reservations_on_entry = flow_reservations.0.sets.entry_set_state(); - let reservations = flow_reservations.0.operator; - let a = DataflowAnalysis::new_with_entry_sets( - mir, - &dead_unwinds, - Cow::Borrowed(reservations_on_entry), - ActiveBorrows::new(reservations), - ); - let results = a.run(tcx, id, &attributes, |ab, i| { - DebugFormatted::new(&(i.kind(), ab.location(i))) - }); - FlowAtLocation::new(results) - }; - let mut state = Flows::new( - flow_active_borrows, + flow_borrows, flow_inits, flow_uninits, flow_move_outs, diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 859618d27b33..4b63d8e2ff78 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -63,48 +63,27 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> { /// to its borrow-indexes. assigned_map: FxHashMap, FxHashSet>, + /// Locations which activate borrows. + /// NOTE: A given location may activate more than one borrow in the future + /// when more general two-phase borrow support is introduced, but for now we + /// only need to store one borrow index + activation_map: FxHashMap, + /// Every borrow has a region; this maps each such regions back to /// its borrow-indexes. region_map: FxHashMap, FxHashSet>, + + /// Map from local to all the borrows on that local local_map: FxHashMap>, + + /// Maps regions to their corresponding source spans + /// Only contains ReScope()s as keys region_span_map: FxHashMap, + + /// NLL region inference context with which NLL queries should be resolved nonlexical_regioncx: Option>>, } -// Two-phase borrows actually requires two flow analyses; they need -// to be separate because the final results of the first are used to -// construct the gen+kill sets for the second. (The dataflow system -// is not designed to allow the gen/kill sets to change during the -// fixed-point iteration.) - -/// The `Reservations` analysis is the first of the two flow analyses -/// tracking (phased) borrows. It computes where a borrow is reserved; -/// i.e. where it can reach in the control flow starting from its -/// initial `assigned = &'rgn borrowed` statement, and ending -/// wherever `'rgn` itself ends. -pub(crate) struct Reservations<'a, 'gcx: 'tcx, 'tcx: 'a>(pub(crate) Borrows<'a, 'gcx, 'tcx>); - -/// The `ActiveBorrows` analysis is the second of the two flow -/// analyses tracking (phased) borrows. It computes where any given -/// borrow `&assigned = &'rgn borrowed` is *active*, which starts at -/// the first use of `assigned` after the reservation has started, and -/// ends wherever `'rgn` itself ends. -pub(crate) struct ActiveBorrows<'a, 'gcx: 'tcx, 'tcx: 'a>(pub(crate) Borrows<'a, 'gcx, 'tcx>); - -impl<'a, 'gcx, 'tcx> Reservations<'a, 'gcx, 'tcx> { - pub(crate) fn new(b: Borrows<'a, 'gcx, 'tcx>) -> Self { Reservations(b) } - pub(crate) fn location(&self, idx: ReserveOrActivateIndex) -> &Location { - self.0.location(idx.borrow_index()) - } -} - -impl<'a, 'gcx, 'tcx> ActiveBorrows<'a, 'gcx, 'tcx> { - pub(crate) fn new(r: Reservations<'a, 'gcx, 'tcx>) -> Self { ActiveBorrows(r.0) } - pub(crate) fn location(&self, idx: ReserveOrActivateIndex) -> &Location { - self.0.location(idx.borrow_index()) - } -} - // temporarily allow some dead fields: `kind` and `region` will be // needed by borrowck; `borrowed_place` will probably be a MovePathIndex when // that is extended to include borrowed data paths. @@ -114,9 +93,15 @@ pub struct BorrowData<'tcx> { /// Location where the borrow reservation starts. /// In many cases, this will be equal to the activation location but not always. pub(crate) reserve_location: Location, + /// Point where the borrow is activated. + pub(crate) activate_location: Location, + /// What kind of borrow this is pub(crate) kind: mir::BorrowKind, + /// The region for which this borrow is live pub(crate) region: Region<'tcx>, + /// Place from which we are borrowing pub(crate) borrowed_place: mir::Place<'tcx>, + /// Place to which the borrow was stored pub(crate) assigned_place: mir::Place<'tcx>, } @@ -165,9 +150,11 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { idx_vec: IndexVec::new(), location_map: FxHashMap(), assigned_map: FxHashMap(), + activation_map: FxHashMap(), region_map: FxHashMap(), local_map: FxHashMap(), - region_span_map: FxHashMap() + region_span_map: FxHashMap(), + nonlexical_regioncx: nonlexical_regioncx.clone() }; visitor.visit_mir(mir); return Borrows { tcx: tcx, @@ -177,6 +164,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { root_scope, location_map: visitor.location_map, assigned_map: visitor.assigned_map, + activation_map: visitor.activation_map, region_map: visitor.region_map, local_map: visitor.local_map, region_span_map: visitor.region_span_map, @@ -188,9 +176,11 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { idx_vec: IndexVec>, location_map: FxHashMap, assigned_map: FxHashMap, FxHashSet>, + activation_map: FxHashMap, region_map: FxHashMap, FxHashSet>, local_map: FxHashMap>, region_span_map: FxHashMap, + nonlexical_regioncx: Option>>, } impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { @@ -210,15 +200,25 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue { if is_unsafe_place(self.tcx, self.mir, borrowed_place) { return; } + let activate_location = self.compute_activation_location(location, + &assigned_place, + region, + kind); let borrow = BorrowData { + activate_location, kind, region, reserve_location: location, - kind, region, borrowed_place: borrowed_place.clone(), assigned_place: assigned_place.clone(), }; let idx = self.idx_vec.push(borrow); self.location_map.insert(location, idx); + // This assert is a good sanity check until more general 2-phase borrow + // support is introduced. See NOTE on the activation_map field for more + assert!(!self.activation_map.contains_key(&activate_location), + "More than one activation introduced at the same location."); + self.activation_map.insert(activate_location, idx); + insert(&mut self.assigned_map, assigned_place, idx); insert(&mut self.region_map, ®ion, idx); if let Some(local) = root_local(borrowed_place) { @@ -273,6 +273,246 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { return self.super_statement(block, statement, location); } } + + /// Represents what kind of usage we've seen. + enum PlaceUsageType { + /// No usage seen + None, + /// Has been seen as the argument to a StorageDead statement. This is required to + /// gracefully handle cases where user code has an unneeded + StorageKilled, + /// Has been used in borrow-activating context + BorrowActivateUsage + } + + /// A MIR visitor that determines if a specific place is used in a two-phase activating + /// manner in a given chunk of MIR. + struct ContainsUseOfPlace<'b, 'tcx: 'b> { + target: &'b Place<'tcx>, + use_found: bool, + } + + impl<'b, 'tcx: 'b> ContainsUseOfPlace<'b, 'tcx> { + fn new(place: &'b Place<'tcx>) -> Self { + Self { target: place, use_found: false } + } + + /// return whether `context` should be considered a "use" of a + /// place found in that context. "Uses" activate associated + /// borrows (at least when such uses occur while the borrow also + /// has a reservation at the time). + fn is_potential_use(context: PlaceContext) -> bool { + match context { + // storage effects on a place do not activate it + PlaceContext::StorageLive | PlaceContext::StorageDead => false, + + // validation effects do not activate a place + // + // FIXME: Should they? Is it just another read? Or can we + // guarantee it won't dereference the stored address? How + // "deep" does validation go? + PlaceContext::Validate => false, + + // FIXME: This is here to not change behaviour from before + // AsmOutput existed, but it's not necessarily a pure overwrite. + // so it's possible this should activate the place. + PlaceContext::AsmOutput | + // pure overwrites of a place do not activate it. (note + // PlaceContext::Call is solely about dest place) + PlaceContext::Store | PlaceContext::Call => false, + + // reads of a place *do* activate it + PlaceContext::Move | + PlaceContext::Copy | + PlaceContext::Drop | + PlaceContext::Inspect | + PlaceContext::Borrow { .. } | + PlaceContext::Projection(..) => true, + } + } + } + + impl<'b, 'tcx: 'b> Visitor<'tcx> for ContainsUseOfPlace<'b, 'tcx> { + fn visit_place(&mut self, + place: &mir::Place<'tcx>, + context: PlaceContext<'tcx>, + location: Location) { + if Self::is_potential_use(context) && place == self.target { + self.use_found = true; + return; + // There is no need to keep checking the statement, we already found a use + } + + self.super_place(place, context, location); + } + + /* + fn visit_statement(&mut self, + block: BasicBlock, + statement: &mir::Statement<'tcx>, + location: Location) { + if let mir::StatementKind::StorageDead(loc) = *statement { + } + + self.super_statement(block, statement, location); + } + */ + } + + impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> { + /// Returns true if the borrow represented by `kind` is + /// allowed to be split into separate Reservation and + /// Activation phases. + fn allow_two_phase_borrow(&self, kind: mir::BorrowKind) -> bool { + self.tcx.sess.two_phase_borrows() && + (kind.allows_two_phase_borrow() || + self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref) + } + + /// Returns true if the given location contains an NLL-activating use of the given place + fn location_contains_use(&self, location: Location, place: &Place) -> bool { + let mut use_checker = ContainsUseOfPlace::new(place); + let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| { + panic!("could not find block at location {:?}", location); + }); + if location.statement_index != block.statements.len() { + // This is a statement + let stmt = block.statements.get(location.statement_index).unwrap_or_else(|| { + panic!("could not find statement at location {:?}"); + }); + use_checker.visit_statement(location.block, stmt, location); + } else { + // This is a terminator + match block.terminator { + Some(ref term) => { + use_checker.visit_terminator(location.block, term, location); + } + None => { + // There is no way for Place to be used by the terminator if there is no + // terminator + } + } + } + + use_checker.use_found + } + + /// Determines if the provided region is terminated after the provided location. + /// EndRegion statements terminate their enclosed region::Scope. + /// We also consult with the NLL region inference engine, should one be available + fn region_terminated_after(&self, region: Region<'tcx>, location: Location) -> bool { + let block_data = &self.mir[location.block]; + if location.statement_index != block_data.statements.len() { + let stmt = &block_data.statements[location.statement_index]; + if let mir::StatementKind::EndRegion(region_scope) = stmt.kind { + if &ReScope(region_scope) == region { + // We encountered an EndRegion statement that terminates the provided region + return true; + } + } + } + if let Some(ref regioncx) = self.nonlexical_regioncx { + if !regioncx.region_contains_point(region, location) { + // NLL says the region has ended already + return true; + } + } + + false + } + + /// Computes the activation location of a borrow. + /// The general idea is to start at the beginning of the region and perform a DFS + /// until we exit the region, either via an explicit EndRegion or because NLL tells + /// us so. If we find more than one valid activation point, we currently panic the + /// compiler since two-phase borrows are only currently supported for compiler- + /// generated code. More precisely, we only allow two-phase borrows for: + /// - Function calls (fn some_func(&mut self, ....)) + /// - *Assign operators (a += b -> fn add_assign(&mut self, other: Self)) + /// See + /// - https://github.com/rust-lang/rust/issues/48431 + /// for detailed design notes. + /// See the TODO in the body of the function for notes on extending support to more + /// general two-phased borrows. + fn compute_activation_location(&self, + start_location: Location, + assigned_place: &mir::Place<'tcx>, + region: Region<'tcx>, + kind: mir::BorrowKind) -> Location { + debug!("Borrows::compute_activation_location({:?}, {:?}, {:?})", + start_location, + assigned_place, + region); + if !self.allow_two_phase_borrow(kind) { + debug!(" -> {:?}", start_location); + return start_location; + } + + // Perform the DFS. + // `stack` is the stack of locations still under consideration + // `found_use` is an Option that becomes Some when we find a use + let mut stack = vec![start_location]; + let mut found_use = None; + while let Some(curr_loc) = stack.pop() { + let block_data = &self.mir.basic_blocks() + .get(curr_loc.block) + .unwrap_or_else(|| { + panic!("could not find block at location {:?}", curr_loc); + }); + + if self.region_terminated_after(region, curr_loc) { + // No need to process this statement. + // It's either an EndRegion (and thus couldn't use assigned_place) or not + // contained in the NLL region and thus a use would be invalid + continue; + } + + if self.location_contains_use(curr_loc, assigned_place) { + // TODO: Handle this case a little more gracefully. Perhaps collect + // all uses in a vector, and find the point in the CFG that dominates + // all of them? + // Right now this is sufficient though since there should only be exactly + // one borrow-activating use of the borrow. + assert!(found_use.is_none(), "Found secondary use of place"); + found_use = Some(curr_loc); + } + + // Push the points we should consider next. + if curr_loc.statement_index < block_data.statements.len() { + stack.push(curr_loc.successor_within_block()); + } else { + stack.extend(block_data.terminator().successors().iter().map( + |&basic_block| { + Location { + statement_index: 0, + block: basic_block + } + } + )) + } + } + + let found_use = found_use.expect("Did not find use of two-phase place"); + debug!(" -> {:?}", found_use); + found_use + } + } + } + + /// Returns the span for the "end point" given region. This will + /// return `None` if NLL is enabled, since that concept has no + /// meaning there. Otherwise, return region span if it exists and + /// span for end of the function if it doesn't exist. + pub(crate) fn opt_region_end_span(&self, region: &Region) -> Option { + match self.nonlexical_regioncx { + Some(_) => None, + None => { + match self.region_span_map.get(region) { + Some(span) => Some(self.tcx.sess.codemap().end_point(*span)), + None => Some(self.tcx.sess.codemap().end_point(self.mir.span)) + } + } + } } pub fn borrows(&self) -> &IndexVec> { &self.borrows } @@ -284,18 +524,24 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { } /// Add all borrows to the kill set, if those borrows are out of scope at `location`. - /// - /// `is_activations` tracks whether we are in the Reservations or - /// the ActiveBorrows flow analysis, and does not set the - /// activation kill bits in the former case. (Technically, we - /// could set those kill bits without such a guard, since they are - /// never gen'ed by Reservations in the first place. But it makes - /// the instrumentation and graph renderings nicer to leave - /// activations out when of the Reservations kill sets.) + /// That means either they went out of either a nonlexical scope, if we care about those + /// at the moment, or the location represents a lexical EndRegion fn kill_loans_out_of_scope_at_location(&self, sets: &mut BlockSets, - location: Location, - is_activations: bool) { + location: Location) { + /* + XXX: bob_twinkles reintroduce this + let block_data = &self.mir[location.block]; + if location.statement_index != block_data.statements.len() { + let statement = &block_data.statements[location.statement_index]; + if let mir::StatementKind::EndRegion(region_scope) = statement.kind { + for &borrow_index in &self.region_map[&ReScope(region_scope)] { + sets.kill(&ReserveOrActivateIndex::reserved(borrow_index)); + sets.kill(&ReserveOrActivateIndex::active(borrow_index)); + } + } + } + */ if let Some(ref regioncx) = self.nonlexical_regioncx { // NOTE: The state associated with a given `location` // reflects the dataflow on entry to the statement. If it @@ -312,21 +558,46 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { let borrow_region = borrow_data.region.to_region_vid(); if !regioncx.region_contains_point(borrow_region, location) { sets.kill(&ReserveOrActivateIndex::reserved(borrow_index)); - if is_activations { - sets.kill(&ReserveOrActivateIndex::active(borrow_index)); - } + sets.kill(&ReserveOrActivateIndex::active(borrow_index)); } } } } - /// Models statement effect in Reservations and ActiveBorrows flow - /// analyses; `is activations` tells us if we are in the latter - /// case. - fn statement_effect_on_borrows(&self, - sets: &mut BlockSets, - location: Location, - is_activations: bool) { + fn kill_borrows_on_local(&self, + sets: &mut BlockSets, + local: &rustc::mir::Local) + { + if let Some(borrow_indexes) = self.local_map.get(local) { + sets.kill_all(borrow_indexes.iter() + .map(|b| ReserveOrActivateIndex::reserved(*b))); + sets.kill_all(borrow_indexes.iter() + .map(|b| ReserveOrActivateIndex::active(*b))); + } + } +} + +impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { + type Idx = ReserveOrActivateIndex; + fn name() -> &'static str { "borrows" } + fn bits_per_block(&self) -> usize { + self.borrows.len() * 2 + } + + fn start_block_effect(&self, _entry_set: &mut IdxSet) { + // no borrows of code region_scopes have been taken prior to + // function execution, so this method has no effect on + // `_sets`. + } + + fn before_statement_effect(&self, sets: &mut BlockSets, location: Location) { + debug!("Borrows::before_statement_effect sets: {:?} location: {:?}", sets, location); + self.kill_loans_out_of_scope_at_location(sets, location); + } + + fn statement_effect(&self, sets: &mut BlockSets, location: Location) { + debug!("Borrows::statement_effect sets: {:?} location: {:?}", sets, location); + let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| { panic!("could not find block at location {:?}", location); }); @@ -334,20 +605,12 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { panic!("could not find statement at location {:?}"); }); - // Do kills introduced by NLL before setting up any potential - // gens. (See NOTE in kill_loans_out_of_scope_at_location.) - self.kill_loans_out_of_scope_at_location(sets, location, is_activations); - - if is_activations { - // INVARIANT: `sets.on_entry` accurately captures - // reservations on entry to statement (b/c - // accumulates_intrablock_state is overridden for - // ActiveBorrows). - // - // Now compute the activations generated by uses within - // the statement based on that reservation state. - let mut find = FindPlaceUses { sets, assigned_map: &self.assigned_map }; - find.visit_statement(location.block, stmt, location); + // Handle activations + match self.activation_map.get(&location) { + Some(&activated) => { + sets.gen(&ReserveOrActivateIndex::active(activated)) + } + None => {} } match stmt.kind { @@ -357,9 +620,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { assert!(self.nonlexical_regioncx.is_none()); for idx in borrow_indexes { sets.kill(&ReserveOrActivateIndex::reserved(*idx)); - if is_activations { - sets.kill(&ReserveOrActivateIndex::active(*idx)); - } + sets.kill(&ReserveOrActivateIndex::active(*idx)); } } else { // (if there is no entry, then there are no borrows to be tracked) @@ -372,7 +633,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { if let Place::Local(ref local) = *lhs { // FIXME: Handle the case in which we're assigning over // a projection (`foo.bar`). - self.kill_borrows_on_local(sets, local, is_activations); + self.kill_borrows_on_local(sets, local); } // NOTE: if/when the Assign case is revised to inspect @@ -396,18 +657,17 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { }).contains(&index)); sets.gen(&ReserveOrActivateIndex::reserved(*index)); - if is_activations { - // Issue #46746: Two-phase borrows handles - // stmts of form `Tmp = &mut Borrow` ... - match lhs { - Place::Local(..) | Place::Static(..) => {} // okay - Place::Projection(..) => { - // ... can assign into projections, - // e.g. `box (&mut _)`. Current - // conservative solution: force - // immediate activation here. - sets.gen(&ReserveOrActivateIndex::active(*index)); - } + // Issue #46746: Two-phase borrows handles + // stmts of form `Tmp = &mut Borrow` ... + // XXX bob_twinkles experiment with removing this + match lhs { + Place::Local(..) | Place::Static(..) => {} // okay + Place::Projection(..) => { + // ... can assign into projections, + // e.g. `box (&mut _)`. Current + // conservative solution: force + // immediate activation here. + sets.gen(&ReserveOrActivateIndex::active(*index)); } } } @@ -416,7 +676,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { mir::StatementKind::StorageDead(local) => { // Make sure there are no remaining borrows for locals that // are gone out of scope. - self.kill_borrows_on_local(sets, &local, is_activations) + self.kill_borrows_on_local(sets, &local) } mir::StatementKind::InlineAsm { ref outputs, ref asm, .. } => { @@ -427,7 +687,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { if let Place::Local(ref local) = *output { // FIXME: Handle the case in which we're assigning over // a projection (`foo.bar`). - self.kill_borrows_on_local(sets, local, is_activations); + self.kill_borrows_on_local(sets, local); } } } @@ -441,47 +701,26 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { } } - fn kill_borrows_on_local(&self, - sets: &mut BlockSets, - local: &rustc::mir::Local, - is_activations: bool) - { - if let Some(borrow_indexes) = self.local_map.get(local) { - sets.kill_all(borrow_indexes.iter() - .map(|b| ReserveOrActivateIndex::reserved(*b))); - if is_activations { - sets.kill_all(borrow_indexes.iter() - .map(|b| ReserveOrActivateIndex::active(*b))); - } - } + fn before_terminator_effect(&self, sets: &mut BlockSets, location: Location) { + debug!("Borrows::before_terminator_effect sets: {:?} location: {:?}", sets, location); + self.kill_loans_out_of_scope_at_location(sets, location); } - /// Models terminator effect in Reservations and ActiveBorrows - /// flow analyses; `is activations` tells us if we are in the - /// latter case. - fn terminator_effect_on_borrows(&self, - sets: &mut BlockSets, - location: Location, - is_activations: bool) { + fn terminator_effect(&self, sets: &mut BlockSets, location: Location) { + debug!("Borrows::terminator_effect sets: {:?} location: {:?}", sets, location); + let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| { panic!("could not find block at location {:?}", location); }); - // Do kills introduced by NLL before setting up any potential - // gens. (See NOTE in kill_loans_out_of_scope_at_location.) - self.kill_loans_out_of_scope_at_location(sets, location, is_activations); - let term = block.terminator(); - if is_activations { - // INVARIANT: `sets.on_entry` accurately captures - // reservations on entry to terminator (b/c - // accumulates_intrablock_state is overridden for - // ActiveBorrows). - // - // Now compute effect of the terminator on the activations - // themselves in the ActiveBorrows state. - let mut find = FindPlaceUses { sets, assigned_map: &self.assigned_map }; - find.visit_terminator(location.block, term, location); + + // Handle activations + match self.activation_map.get(&location) { + Some(&activated) => { + sets.gen(&ReserveOrActivateIndex::active(activated)) + } + None => {} } match term.kind { @@ -504,9 +743,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { self.scope_tree.is_subscope_of(*scope, root_scope) { sets.kill(&ReserveOrActivateIndex::reserved(borrow_index)); - if is_activations { - sets.kill(&ReserveOrActivateIndex::active(borrow_index)); - } + sets.kill(&ReserveOrActivateIndex::active(borrow_index)); } } } @@ -525,161 +762,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { mir::TerminatorKind::Unreachable => {} } } -} - -impl<'a, 'gcx, 'tcx> ActiveBorrows<'a, 'gcx, 'tcx> { - pub(crate) fn borrows(&self) -> &IndexVec> { - self.0.borrows() - } - - /// Returns the span for the "end point" given region. This will - /// return `None` if NLL is enabled, since that concept has no - /// meaning there. Otherwise, return region span if it exists and - /// span for end of the function if it doesn't exist. - pub(crate) fn opt_region_end_span(&self, region: &Region) -> Option { - match self.0.nonlexical_regioncx { - Some(_) => None, - None => { - match self.0.region_span_map.get(region) { - Some(span) => Some(self.0.tcx.sess.codemap().end_point(*span)), - None => Some(self.0.tcx.sess.codemap().end_point(self.0.mir.span)) - } - } - } - } -} - -/// `FindPlaceUses` is a MIR visitor that updates `self.sets` for all -/// of the borrows activated by a given statement or terminator. -/// -/// ---- -/// -/// The `ActiveBorrows` flow analysis, when inspecting any given -/// statement or terminator, needs to "generate" (i.e. set to 1) all -/// of the bits for the borrows that are activated by that -/// statement/terminator. -/// -/// This struct will seek out all places that are assignment-targets -/// for borrows (gathered in `self.assigned_map`; see also the -/// `assigned_map` in `struct Borrows`), and set the corresponding -/// gen-bits for activations of those borrows in `self.sets` -struct FindPlaceUses<'a, 'b: 'a, 'tcx: 'a> { - assigned_map: &'a FxHashMap, FxHashSet>, - sets: &'a mut BlockSets<'b, ReserveOrActivateIndex>, -} - -impl<'a, 'b, 'tcx> FindPlaceUses<'a, 'b, 'tcx> { - fn has_been_reserved(&self, b: &BorrowIndex) -> bool { - self.sets.on_entry.contains(&ReserveOrActivateIndex::reserved(*b)) - } - - /// return whether `context` should be considered a "use" of a - /// place found in that context. "Uses" activate associated - /// borrows (at least when such uses occur while the borrow also - /// has a reservation at the time). - fn is_potential_use(context: PlaceContext) -> bool { - match context { - // storage effects on a place do not activate it - PlaceContext::StorageLive | PlaceContext::StorageDead => false, - - // validation effects do not activate a place - // - // FIXME: Should they? Is it just another read? Or can we - // guarantee it won't dereference the stored address? How - // "deep" does validation go? - PlaceContext::Validate => false, - - // FIXME: This is here to not change behaviour from before - // AsmOutput existed, but it's not necessarily a pure overwrite. - // so it's possible this should activate the place. - PlaceContext::AsmOutput | - // pure overwrites of a place do not activate it. (note - // PlaceContext::Call is solely about dest place) - PlaceContext::Store | PlaceContext::Call => false, - - // reads of a place *do* activate it - PlaceContext::Move | - PlaceContext::Copy | - PlaceContext::Drop | - PlaceContext::Inspect | - PlaceContext::Borrow { .. } | - PlaceContext::Projection(..) => true, - } - } -} - -impl<'a, 'b, 'tcx> Visitor<'tcx> for FindPlaceUses<'a, 'b, 'tcx> { - fn visit_place(&mut self, - place: &mir::Place<'tcx>, - context: PlaceContext<'tcx>, - location: Location) { - debug!("FindPlaceUses place: {:?} assigned from borrows: {:?} \ - used in context: {:?} at location: {:?}", - place, self.assigned_map.get(place), context, location); - if Self::is_potential_use(context) { - if let Some(borrows) = self.assigned_map.get(place) { - for borrow_idx in borrows { - debug!("checking if index {:?} for {:?} is reserved ({}) \ - and thus needs active gen-bit set in sets {:?}", - borrow_idx, place, self.has_been_reserved(&borrow_idx), self.sets); - if self.has_been_reserved(&borrow_idx) { - self.sets.gen(&ReserveOrActivateIndex::active(*borrow_idx)); - } else { - // (This can certainly happen in valid code. I - // just want to know about it in the short - // term.) - debug!("encountered use of Place {:?} of borrow_idx {:?} \ - at location {:?} outside of reservation", - place, borrow_idx, location); - } - } - } - } - - self.super_place(place, context, location); - } -} - - -impl<'a, 'gcx, 'tcx> BitDenotation for Reservations<'a, 'gcx, 'tcx> { - type Idx = ReserveOrActivateIndex; - fn name() -> &'static str { "reservations" } - fn bits_per_block(&self) -> usize { - self.0.borrows.len() * 2 - } - fn start_block_effect(&self, _entry_set: &mut IdxSet) { - // no borrows of code region_scopes have been taken prior to - // function execution, so this method has no effect on - // `_sets`. - } - - fn before_statement_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("Reservations::before_statement_effect sets: {:?} location: {:?}", sets, location); - self.0.kill_loans_out_of_scope_at_location(sets, location, false); - } - - fn statement_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("Reservations::statement_effect sets: {:?} location: {:?}", sets, location); - self.0.statement_effect_on_borrows(sets, location, false); - } - - fn before_terminator_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("Reservations::before_terminator_effect sets: {:?} location: {:?}", sets, location); - self.0.kill_loans_out_of_scope_at_location(sets, location, false); - } - - fn terminator_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("Reservations::terminator_effect sets: {:?} location: {:?}", sets, location); - self.0.terminator_effect_on_borrows(sets, location, false); - } fn propagate_call_return(&self, _in_out: &mut IdxSet, @@ -694,85 +776,17 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Reservations<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> BitDenotation for ActiveBorrows<'a, 'gcx, 'tcx> { - type Idx = ReserveOrActivateIndex; - fn name() -> &'static str { "active_borrows" } - - /// Overriding this method; `ActiveBorrows` uses the intrablock - /// state in `on_entry` to track the current reservations (which - /// then affect the construction of the gen/kill sets for - /// activations). - fn accumulates_intrablock_state() -> bool { true } - - fn bits_per_block(&self) -> usize { - self.0.borrows.len() * 2 - } - - fn start_block_effect(&self, _entry_sets: &mut IdxSet) { - // no borrows of code region_scopes have been taken prior to - // function execution, so this method has no effect on - // `_sets`. - } - - fn before_statement_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("ActiveBorrows::before_statement_effect sets: {:?} location: {:?}", sets, location); - self.0.kill_loans_out_of_scope_at_location(sets, location, true); - } - - fn statement_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("ActiveBorrows::statement_effect sets: {:?} location: {:?}", sets, location); - self.0.statement_effect_on_borrows(sets, location, true); - } - - fn before_terminator_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("ActiveBorrows::before_terminator_effect sets: {:?} location: {:?}", sets, location); - self.0.kill_loans_out_of_scope_at_location(sets, location, true); - } - - fn terminator_effect(&self, - sets: &mut BlockSets, - location: Location) { - debug!("ActiveBorrows::terminator_effect sets: {:?} location: {:?}", sets, location); - self.0.terminator_effect_on_borrows(sets, location, true); - } - - fn propagate_call_return(&self, - _in_out: &mut IdxSet, - _call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - _dest_place: &mir::Place) { - // there are no effects on borrows from method call return... - // - // ... but If overwriting a place can affect flow state, then - // latter is not true; see NOTE on Assign case in - // statement_effect_on_borrows. - } -} - -impl<'a, 'gcx, 'tcx> BitwiseOperator for Reservations<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> BitwiseOperator for Borrows<'a, 'gcx, 'tcx> { #[inline] fn join(&self, pred1: usize, pred2: usize) -> usize { pred1 | pred2 // union effects of preds when computing reservations } } -impl<'a, 'gcx, 'tcx> BitwiseOperator for ActiveBorrows<'a, 'gcx, 'tcx> { - #[inline] - fn join(&self, pred1: usize, pred2: usize) -> usize { - pred1 | pred2 // union effects of preds when computing activations - } -} - -impl<'a, 'gcx, 'tcx> InitialFlow for Reservations<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> InitialFlow for Borrows<'a, 'gcx, 'tcx> { #[inline] fn bottom_value() -> bool { - false // bottom = no Rvalue::Refs are reserved by default + false // bottom = nothing is reserved or activated yet } } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index aa7bb6f97786..f7675d611cc5 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -18,7 +18,7 @@ use rustc::ty::{self, TyCtxt}; use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator}; use rustc::session::Session; -use std::borrow::{Borrow, Cow}; +use std::borrow::Borrow; use std::fmt; use std::io; use std::mem; @@ -31,7 +31,7 @@ pub use self::impls::{DefinitelyInitializedPlaces, MovingOutStatements}; pub use self::impls::EverInitializedPlaces; pub use self::impls::borrows::{Borrows, BorrowData}; pub use self::impls::HaveBeenBorrowedLocals; -pub(crate) use self::impls::borrows::{ActiveBorrows, Reservations, ReserveOrActivateIndex}; +pub(crate) use self::impls::borrows::{ReserveOrActivateIndex}; pub use self::at_location::{FlowAtLocation, FlowsAtLocation}; pub(crate) use self::drop_flag_effects::*; @@ -584,9 +584,6 @@ impl AllSets { pub fn on_entry_set_for(&self, block_idx: usize) -> &IdxSet { self.lookup_set_for(&self.on_entry_sets, block_idx) } - pub(crate) fn entry_set_state(&self) -> &Bits { - &self.on_entry_sets - } } /// Parameterization for the precise form of data flow that is used. @@ -739,27 +736,17 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation dead_unwinds: &'a IdxSet, denotation: D) -> Self where D: InitialFlow { let bits_per_block = denotation.bits_per_block(); + let usize_bits = mem::size_of::() * 8; + let words_per_block = (bits_per_block + usize_bits - 1) / usize_bits; let num_overall = Self::num_bits_overall(mir, bits_per_block); + + let zeroes = Bits::new(IdxSetBuf::new_empty(num_overall)); let on_entry = Bits::new(if D::bottom_value() { IdxSetBuf::new_filled(num_overall) } else { IdxSetBuf::new_empty(num_overall) }); - Self::new_with_entry_sets(mir, dead_unwinds, Cow::Owned(on_entry), denotation) - } - - pub(crate) fn new_with_entry_sets(mir: &'a Mir<'tcx>, - dead_unwinds: &'a IdxSet, - on_entry: Cow>, - denotation: D) - -> Self { - let bits_per_block = denotation.bits_per_block(); - let usize_bits = mem::size_of::() * 8; - let words_per_block = (bits_per_block + usize_bits - 1) / usize_bits; - let num_overall = Self::num_bits_overall(mir, bits_per_block); - assert_eq!(num_overall, on_entry.bits.words().len() * usize_bits); - let zeroes = Bits::new(IdxSetBuf::new_empty(num_overall)); DataflowAnalysis { mir, dead_unwinds, @@ -769,13 +756,27 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation words_per_block, gen_sets: zeroes.clone(), kill_sets: zeroes, - on_entry_sets: on_entry.into_owned(), + on_entry_sets: on_entry, }, operator: denotation, } } } + pub fn new_from_sets(mir: &'a Mir<'tcx>, + dead_unwinds: &'a IdxSet, + sets: AllSets, + denotation: D) -> Self { + DataflowAnalysis { + mir, + dead_unwinds, + flow_state: DataflowState { + sets: sets, + operator: denotation, + } + } + } + fn num_bits_overall(mir: &Mir, bits_per_block: usize) -> usize { let usize_bits = mem::size_of::() * 8; let words_per_block = (bits_per_block + usize_bits - 1) / usize_bits; diff --git a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs index 709c00ba8464..1d3d61fb3fbf 100644 --- a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs +++ b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs @@ -10,10 +10,12 @@ // ignore-tidy-linelength -// revisions: lxl_beyond nll_beyond nll_target +// revisions: nll_target +// The following revisions are disabled due to missing support from two-phase beyond autorefs //[lxl_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref //[nll_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref -Z nll + //[nll_target] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll // This is an important corner case pointed out by Niko: one is diff --git a/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs b/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs index dd174981fb1e..d2f4154433ab 100644 --- a/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs +++ b/src/test/compile-fail/borrowck/two-phase-allow-access-during-reservation.rs @@ -10,9 +10,13 @@ // ignore-tidy-linelength -// revisions: lxl_beyond nll_beyond nll_target +// revisions: nll_target + +// The following revisions are disabled due to missing support for two_phase_beyond_autoref //[lxl_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two_phase_beyond_autoref //[nll_beyond] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two_phase_beyond_autoref -Z nll + + //[nll_target] compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll // This is the second counter-example from Niko's blog post diff --git a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs index f4c36157fe98..bf8e02adb1ae 100644 --- a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs +++ b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// revisions: lxl nll g2p +// revisions: lxl nll //[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows //[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll + //[g2p]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll -Z two-phase-beyond-autoref +// the above revision is disabled until two-phase-beyond-autoref support is better // This is a test checking that when we limit two-phase borrows to // method receivers, we do not let other kinds of auto-ref to leak @@ -70,10 +72,8 @@ fn overloaded_call_traits() { fn twice_ten_sm i32>(f: &mut F) { f(f(10)); //[lxl]~^ ERROR cannot borrow `*f` as mutable more than once at a time - //[lxl]~| ERROR cannot borrow `*f` as mutable more than once at a time - //[nll]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time - //[nll]~| ERROR cannot borrow `*f` as mutable more than once at a time - //[g2p]~^^^^^ ERROR cannot borrow `*f` as mutable more than once at a time + //[nll]~^^ ERROR cannot borrow `*f` as mutable more than once at a time + //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time } fn twice_ten_si i32>(f: &mut F) { f(f(10)); @@ -88,10 +88,8 @@ fn overloaded_call_traits() { fn twice_ten_om(f: &mut FnMut(i32) -> i32) { f(f(10)); //[lxl]~^ ERROR cannot borrow `*f` as mutable more than once at a time - //[lxl]~| ERROR cannot borrow `*f` as mutable more than once at a time - //[nll]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time - //[nll]~| ERROR cannot borrow `*f` as mutable more than once at a time - //[g2p]~^^^^^ ERROR cannot borrow `*f` as mutable more than once at a time + //[nll]~^^ ERROR cannot borrow `*f` as mutable more than once at a time + //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time } fn twice_ten_oi(f: &mut Fn(i32) -> i32) { f(f(10)); diff --git a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs index b5fda4985f23..058022ad588e 100644 --- a/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs +++ b/src/test/compile-fail/borrowck/two-phase-reservation-sharing-interference.rs @@ -12,8 +12,12 @@ // revisions: lxl_beyond nll_beyond nll_target +// The following revisions are disabled due to missing support from two-phase beyond autorefs //[lxl_beyond]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref +//[lxl_beyond] should-fail //[nll_beyond]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z two-phase-beyond-autoref -Z nll +//[nll_beyond] should-fail + //[nll_target]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll // This is a corner case that the current implementation is (probably) @@ -31,10 +35,6 @@ // "nll_beyond" means the generalization of two-phase borrows to all // `&mut`-borrows (doing so makes it easier to write code for specific // corner cases). -// -// FIXME: in "nll_target", we currently see the same error reported -// twice. This is injected by `-Z two-phase-borrows`; not sure why as -// of yet. fn main() { let mut vec = vec![0, 1]; @@ -49,7 +49,6 @@ fn main() { //[lxl_beyond]~^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable //[nll_beyond]~^^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable //[nll_target]~^^^ ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable - //[nll_target]~| ERROR cannot borrow `vec` as mutable because it is also borrowed as immutable shared[0]; } From 047bec69b9ec54d400b1e255c8757bff8a5a854d Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Sat, 3 Mar 2018 17:44:06 -0500 Subject: [PATCH 086/830] mir dataflow: change graphviz output The new output format is perhaps a little more readable. As a bonus, we get labels on the outgoing edges to more easily corroborate the dataflow with the plain MIR graphviz output. --- src/libgraphviz/lib.rs | 6 + src/librustc_mir/dataflow/graphviz.rs | 297 +++++++++++++------------- 2 files changed, 155 insertions(+), 148 deletions(-) diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index cd893b9784ab..d8c366d2413d 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -711,6 +711,12 @@ impl<'a> IntoCow<'a, str> for &'a str { } } +impl<'a> IntoCow<'a, str> for Cow<'a, str> { + fn into_cow(self) -> Cow<'a, str> { + self + } +} + impl<'a, T: Clone> IntoCow<'a, [T]> for Vec { fn into_cow(self) -> Cow<'a, [T]> { Cow::Owned(self) diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index fb3cb1518cbb..0305e4c93b6a 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -20,12 +20,9 @@ use dot::IntoCow; use std::fs; use std::io; -use std::io::prelude::*; use std::marker::PhantomData; use std::path::Path; -use util; - use super::{BitDenotation, DataflowState}; use super::DataflowBuilder; use super::DebugFormatted; @@ -98,158 +95,162 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> } fn node_label(&self, n: &Node) -> dot::LabelText { - // A standard MIR label, as generated by write_node_label, is - // presented in a single column in a table. - // - // The code below does a bunch of formatting work to format a - // node (i.e. MIR basic-block) label with extra - // dataflow-enriched information. In particular, the goal is - // to add extra columns that present the three dataflow - // bitvectors, and the data those bitvectors represent. - // - // It presents it in the following format (where I am - // presenting the table rendering via ASCII art, one line per - // row of the table, and a chunk size of 3 rather than 5): - // - // ------ ----------------------- ------------ -------------------- - // [e1, e3, e4] - // [e8, e9] "= ENTRY:" - // ------ ----------------------- ------------ -------------------- - // Left - // Most - // Column - // Is - // Just - // Normal - // Series - // Of - // MIR - // Stmts - // ------ ----------------------- ------------ -------------------- - // [g1, g4, g5] "= GEN:" - // ------ ----------------------- ------------ -------------------- - // "KILL:" "=" [k1, k3, k8] - // [k9] - // ------ ----------------------- ------------ -------------------- - // - // (In addition, the added dataflow is rendered with a colored - // background just so it will stand out compared to the - // statements.) + // Node label is something like this: + // +---------+----------------------------------+------------------+------------------+ + // | ENTRY | MIR | GEN | KILL | + // +---------+----------------------------------+------------------+------------------+ + // | | 0: StorageLive(_7) | bb3[2]: reserved | bb2[0]: reserved | + // | | 1: StorageLive(_8) | bb3[2]: active | bb2[0]: active | + // | | 2: _8 = &mut _1 | | bb4[2]: reserved | + // | | | | bb4[2]: active | + // | | | | bb9[0]: reserved | + // | | | | bb9[0]: active | + // | | | | bb10[0]: reserved| + // | | | | bb10[0]: active | + // | | | | bb11[0]: reserved| + // | | | | bb11[0]: active | + // +---------+----------------------------------+------------------+------------------+ + // | [00-00] | _7 = const Foo::twiddle(move _8) | [0c-00] | [f3-0f] | + // +---------+----------------------------------+------------------+------------------+ let mut v = Vec::new(); - let i = n.index(); - let chunk_size = 5; - const BG_FLOWCONTENT: &'static str = r#"bgcolor="pink""#; - const ALIGN_RIGHT: &'static str = r#"align="right""#; - const FACE_MONOSPACE: &'static str = r#"FACE="Courier""#; - fn chunked_present_left(w: &mut W, - interpreted: &[DebugFormatted], - chunk_size: usize) - -> io::Result<()> - { - // This function may emit a sequence of 's, but it - // always finishes with an (unfinished) - // - // - // Thus, after being called, one should finish both the - // pending as well as the itself. - let mut seen_one = false; - for c in interpreted.chunks(chunk_size) { - if seen_one { - // if not the first row, finish off the previous row - write!(w, "")?; - } - write!(w, "{objs:?}", - bg = BG_FLOWCONTENT, - align = ALIGN_RIGHT, - objs = c)?; - seen_one = true; - } - if !seen_one { - write!(w, "[]", - bg = BG_FLOWCONTENT, - align = ALIGN_RIGHT)?; - } - Ok(()) - } - util::write_graphviz_node_label( - *n, self.mbcx.mir(), &mut v, 4, - |w| { - let flow = self.mbcx.flow_state(); - let entry_interp = flow.interpret_set(&flow.operator, - flow.sets.on_entry_set_for(i), - &self.render_idx); - chunked_present_left(w, &entry_interp[..], chunk_size)?; - let bits_per_block = flow.sets.bits_per_block(); - let entry = flow.sets.on_entry_set_for(i); - debug!("entry set for i={i} bits_per_block: {bpb} entry: {e:?} interp: {ei:?}", - i=i, e=entry, bpb=bits_per_block, ei=entry_interp); - write!(w, "= ENTRY:{entrybits:?}\ - ", - bg = BG_FLOWCONTENT, - face = FACE_MONOSPACE, - entrybits=bits_to_string(entry.words(), bits_per_block)) - }, - |w| { - let flow = self.mbcx.flow_state(); - let gen_interp = - flow.interpret_set(&flow.operator, flow.sets.gen_set_for(i), &self.render_idx); - let kill_interp = - flow.interpret_set(&flow.operator, flow.sets.kill_set_for(i), &self.render_idx); - chunked_present_left(w, &gen_interp[..], chunk_size)?; - let bits_per_block = flow.sets.bits_per_block(); - { - let gen = flow.sets.gen_set_for(i); - debug!("gen set for i={i} bits_per_block: {bpb} gen: {g:?} interp: {gi:?}", - i=i, g=gen, bpb=bits_per_block, gi=gen_interp); - write!(w, " = GEN:{genbits:?}\ - ", - bg = BG_FLOWCONTENT, - face = FACE_MONOSPACE, - genbits=bits_to_string(gen.words(), bits_per_block))?; - } - - { - let kill = flow.sets.kill_set_for(i); - debug!("kill set for i={i} bits_per_block: {bpb} kill: {k:?} interp: {ki:?}", - i=i, k=kill, bpb=bits_per_block, ki=kill_interp); - write!(w, "KILL:\ - {killbits:?}", - bg = BG_FLOWCONTENT, - align = ALIGN_RIGHT, - face = FACE_MONOSPACE, - killbits=bits_to_string(kill.words(), bits_per_block))?; - } - - // (chunked_present_right) - let mut seen_one = false; - for k in kill_interp.chunks(chunk_size) { - if !seen_one { - // continuation of row; this is fourth - write!(w, "= {kill:?}", - bg = BG_FLOWCONTENT, - kill=k)?; - } else { - // new row, with indent of three 's - write!(w, "{kill:?}", - bg = BG_FLOWCONTENT, - kill=k)?; - } - seen_one = true; - } - if !seen_one { - write!(w, "= []", - bg = BG_FLOWCONTENT)?; - } - - Ok(()) - }) - .unwrap(); + self.node_label_internal(n, &mut v, *n, self.mbcx.mir()).unwrap(); dot::LabelText::html(String::from_utf8(v).unwrap()) } + fn node_shape(&self, _n: &Node) -> Option { Some(dot::LabelText::label("none")) } + + fn edge_label(&'a self, e: &Edge) -> dot::LabelText<'a> { + let term = self.mbcx.mir()[e.source].terminator(); + let label = &term.kind.fmt_successor_labels()[e.index]; + dot::LabelText::label(label.clone()) + } +} + +impl<'a, 'tcx, MWF, P> Graph<'a, 'tcx, MWF, P> +where MWF: MirWithFlowState<'tcx>, + P: Fn(&MWF::BD, ::Idx) -> DebugFormatted, +{ + /// Generate the node label + fn node_label_internal(&self, + n: &Node, + w: &mut W, + block: BasicBlock, + mir: &Mir) -> io::Result<()> { + // Header rows + const HDRS: [&'static str; 4] = ["ENTRY", "MIR", "GEN", "KILL"]; + const HDR_FMT: &'static str = "bgcolor=\"grey\""; + write!(w, "")?; + for hdr in &HDRS { + write!(w, "", HDR_FMT, hdr)?; + } + write!(w, "")?; + + // Data row + self.node_label_verbose_row(n, w, block, mir)?; + self.node_label_final_row(n, w, block, mir)?; + write!(w, "
", HDRS.len())?; + write!(w, "{:?}", block.index())?; + write!(w, "
{}
")?; + + Ok(()) + } + + /// Build the verbose row: full MIR data, and detailed gen/kill/entry sets + fn node_label_verbose_row(&self, + n: &Node, + w: &mut W, + block: BasicBlock, + mir: &Mir) + -> io::Result<()> { + let i = n.index(); + + macro_rules! dump_set_for { + ($set:ident) => { + write!(w, "")?; + + let flow = self.mbcx.flow_state(); + let entry_interp = flow.interpret_set(&flow.operator, + flow.sets.$set(i), + &self.render_idx); + for e in &entry_interp { + write!(w, "{:?}
", e)?; + } + write!(w, "")?; + } + } + + write!(w, "")?; + // Entry + dump_set_for!(on_entry_set_for); + + // MIR statements + write!(w, "")?; + { + let data = &mir[block]; + for (i, statement) in data.statements.iter().enumerate() { + write!(w, "{}
", + dot::escape_html(&format!("{:3}: {:?}", i, statement)))?; + } + } + write!(w, "")?; + + // Gen + dump_set_for!(gen_set_for); + + // Kill + dump_set_for!(kill_set_for); + + write!(w, "")?; + + Ok(()) + } + + /// Build the summary row: terminator, gen/kill/entry bit sets + fn node_label_final_row(&self, + n: &Node, + w: &mut W, + block: BasicBlock, + mir: &Mir) + -> io::Result<()> { + let i = n.index(); + + macro_rules! dump_set_for { + ($set:ident) => { + let flow = self.mbcx.flow_state(); + let bits_per_block = flow.sets.bits_per_block(); + let set = flow.sets.$set(i); + write!(w, "{:?}", + dot::escape_html(&bits_to_string(set.words(), bits_per_block)))?; + } + } + + write!(w, "")?; + // Entry + dump_set_for!(on_entry_set_for); + + // Terminator + write!(w, "")?; + { + let data = &mir[block]; + let mut terminator_head = String::new(); + data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); + write!(w, "{}", dot::escape_html(&terminator_head))?; + } + write!(w, "")?; + + // Gen + dump_set_for!(gen_set_for); + + // Kill + dump_set_for!(kill_set_for); + + write!(w, "")?; + + Ok(()) + } } impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P> From 47d75afd1156fca4f3b3f414b3ca467b0e3f113f Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Mon, 5 Mar 2018 22:43:43 -0500 Subject: [PATCH 087/830] Complete re-implementation of 2-phase borrows See #48431 for discussion as to why this was necessary and what we hoped to accomplish. A brief summary: - the first implementation of 2-phase borrows was hard to limit in the way we wanted. That is, it was too good at accepting all 2-phase borrows rather than just autorefs =) - Numerous diagnostic regressions were introduced by 2-phase borrow support which were difficult to fix --- src/librustc_mir/dataflow/impls/borrows.rs | 66 +++++++++---------- ...o-phase-activation-sharing-interference.rs | 1 - 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 4b63d8e2ff78..3d50b9467c13 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -450,8 +450,10 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { // Perform the DFS. // `stack` is the stack of locations still under consideration + // `visited` is the set of points we have already visited // `found_use` is an Option that becomes Some when we find a use let mut stack = vec![start_location]; + let mut visited = FxHashSet(); let mut found_use = None; while let Some(curr_loc) = stack.pop() { let block_data = &self.mir.basic_blocks() @@ -467,6 +469,11 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { continue; } + if !visited.insert(curr_loc) { + debug!(" Already visited {:?}", curr_loc); + continue; + } + if self.location_contains_use(curr_loc, assigned_place) { // TODO: Handle this case a little more gracefully. Perhaps collect // all uses in a vector, and find the point in the CFG that dominates @@ -529,19 +536,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { fn kill_loans_out_of_scope_at_location(&self, sets: &mut BlockSets, location: Location) { - /* - XXX: bob_twinkles reintroduce this - let block_data = &self.mir[location.block]; - if location.statement_index != block_data.statements.len() { - let statement = &block_data.statements[location.statement_index]; - if let mir::StatementKind::EndRegion(region_scope) = statement.kind { - for &borrow_index in &self.region_map[&ReScope(region_scope)] { - sets.kill(&ReserveOrActivateIndex::reserved(borrow_index)); - sets.kill(&ReserveOrActivateIndex::active(borrow_index)); - } - } - } - */ if let Some(ref regioncx) = self.nonlexical_regioncx { // NOTE: The state associated with a given `location` // reflects the dataflow on entry to the statement. If it @@ -575,6 +569,20 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { .map(|b| ReserveOrActivateIndex::active(*b))); } } + + /// Performs the activations for a given location + fn perform_activations_at_location(&self, + sets: &mut BlockSets, + location: Location) { + // Handle activations + match self.activation_map.get(&location) { + Some(&activated) => { + debug!("activating borrow {:?}", activated); + sets.gen(&ReserveOrActivateIndex::active(activated)) + } + None => {} + } + } } impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { @@ -605,13 +613,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { panic!("could not find statement at location {:?}"); }); - // Handle activations - match self.activation_map.get(&location) { - Some(&activated) => { - sets.gen(&ReserveOrActivateIndex::active(activated)) - } - None => {} - } + self.perform_activations_at_location(sets, location); + self.kill_loans_out_of_scope_at_location(sets, location); match stmt.kind { // EndRegion kills any borrows (reservations and active borrows both) @@ -643,15 +646,17 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { if let mir::Rvalue::Ref(region, _, ref place) = *rhs { if is_unsafe_place(self.tcx, self.mir, place) { return; } - if let RegionKind::ReEmpty = region { - // If the borrowed value is dead, the region for it - // can be empty. Don't track the borrow in that case. - return - } - let index = self.location_map.get(&location).unwrap_or_else(|| { panic!("could not find BorrowIndex for location {:?}", location); }); + + if let RegionKind::ReEmpty = region { + // If the borrowed value dies before the borrow is used, the region for + // the borrow can be empty. Don't track the borrow in that case. + sets.kill(&ReserveOrActivateIndex::active(*index)); + return + } + assert!(self.region_map.get(region).unwrap_or_else(|| { panic!("could not find BorrowIndexs for region {:?}", region); }).contains(&index)); @@ -714,14 +719,9 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { }); let term = block.terminator(); + self.perform_activations_at_location(sets, location); + self.kill_loans_out_of_scope_at_location(sets, location); - // Handle activations - match self.activation_map.get(&location) { - Some(&activated) => { - sets.gen(&ReserveOrActivateIndex::active(activated)) - } - None => {} - } match term.kind { mir::TerminatorKind::Resume | diff --git a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs index 1d3d61fb3fbf..90933c6b31fa 100644 --- a/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs +++ b/src/test/compile-fail/borrowck/two-phase-activation-sharing-interference.rs @@ -53,7 +53,6 @@ fn not_ok() { *y += 1; //[lxl_beyond]~^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable //[nll_beyond]~^^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable - //[nll_target]~^^^ ERROR cannot borrow `x` as mutable because it is also borrowed as immutable read(z); } From e4e377f6e8dfb59ecfba014543508fedb61a9f4e Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Tue, 6 Mar 2018 00:13:29 -0500 Subject: [PATCH 088/830] Remove unused field on BorrowData --- src/librustc_mir/dataflow/impls/borrows.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 3d50b9467c13..8f1c7945339a 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -93,8 +93,6 @@ pub struct BorrowData<'tcx> { /// Location where the borrow reservation starts. /// In many cases, this will be equal to the activation location but not always. pub(crate) reserve_location: Location, - /// Point where the borrow is activated. - pub(crate) activate_location: Location, /// What kind of borrow this is pub(crate) kind: mir::BorrowKind, /// The region for which this borrow is live @@ -205,7 +203,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { region, kind); let borrow = BorrowData { - activate_location, kind, region, + kind, region, reserve_location: location, borrowed_place: borrowed_place.clone(), assigned_place: assigned_place.clone(), From 03f198fcee46b49a69845784c313433496f7cf0e Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Tue, 6 Mar 2018 03:37:21 -0500 Subject: [PATCH 089/830] Fix tests after two-phase borrow rewrite --- src/librustc_mir/dataflow/graphviz.rs | 4 +-- src/librustc_mir/dataflow/impls/borrows.rs | 27 +++++++------------ .../nll/region-ends-after-if-condition.rs | 2 +- src/test/ui/issue-45157.rs | 1 - src/test/ui/issue-45157.stderr | 13 +-------- 5 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index 0305e4c93b6a..07585c08f6a2 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -111,7 +111,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> // | | | | bb11[0]: active | // +---------+----------------------------------+------------------+------------------+ // | [00-00] | _7 = const Foo::twiddle(move _8) | [0c-00] | [f3-0f] | - // +---------+----------------------------------+------------------+------------------+ + // +---------+----------------------------------+------------------+------------------+ let mut v = Vec::new(); self.node_label_internal(n, &mut v, *n, self.mbcx.mir()).unwrap(); dot::LabelText::html(String::from_utf8(v).unwrap()) @@ -140,7 +140,7 @@ where MWF: MirWithFlowState<'tcx>, block: BasicBlock, mir: &Mir) -> io::Result<()> { // Header rows - const HDRS: [&'static str; 4] = ["ENTRY", "MIR", "GEN", "KILL"]; + const HDRS: [&'static str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"]; const HDR_FMT: &'static str = "bgcolor=\"grey\""; write!(w, "
", HDRS.len())?; write!(w, "{:?}", block.index())?; diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 8f1c7945339a..b7c95da09be9 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -272,17 +272,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { } } - /// Represents what kind of usage we've seen. - enum PlaceUsageType { - /// No usage seen - None, - /// Has been seen as the argument to a StorageDead statement. This is required to - /// gracefully handle cases where user code has an unneeded - StorageKilled, - /// Has been used in borrow-activating context - BorrowActivateUsage - } - /// A MIR visitor that determines if a specific place is used in a two-phase activating /// manner in a given chunk of MIR. struct ContainsUseOfPlace<'b, 'tcx: 'b> { @@ -404,7 +393,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { let stmt = &block_data.statements[location.statement_index]; if let mir::StatementKind::EndRegion(region_scope) = stmt.kind { if &ReScope(region_scope) == region { - // We encountered an EndRegion statement that terminates the provided region + // We encountered an EndRegion statement that terminates the provided + // region return true; } } @@ -430,7 +420,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { /// See /// - https://github.com/rust-lang/rust/issues/48431 /// for detailed design notes. - /// See the TODO in the body of the function for notes on extending support to more + /// See the FIXME in the body of the function for notes on extending support to more /// general two-phased borrows. fn compute_activation_location(&self, start_location: Location, @@ -473,7 +463,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { } if self.location_contains_use(curr_loc, assigned_place) { - // TODO: Handle this case a little more gracefully. Perhaps collect + // FIXME: Handle this case a little more gracefully. Perhaps collect // all uses in a vector, and find the point in the CFG that dominates // all of them? // Right now this is sufficient though since there should only be exactly @@ -596,7 +586,9 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { // `_sets`. } - fn before_statement_effect(&self, sets: &mut BlockSets, location: Location) { + fn before_statement_effect(&self, + sets: &mut BlockSets, + location: Location) { debug!("Borrows::before_statement_effect sets: {:?} location: {:?}", sets, location); self.kill_loans_out_of_scope_at_location(sets, location); } @@ -662,7 +654,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { // Issue #46746: Two-phase borrows handles // stmts of form `Tmp = &mut Borrow` ... - // XXX bob_twinkles experiment with removing this match lhs { Place::Local(..) | Place::Static(..) => {} // okay Place::Projection(..) => { @@ -704,7 +695,9 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { } } - fn before_terminator_effect(&self, sets: &mut BlockSets, location: Location) { + fn before_terminator_effect(&self, + sets: &mut BlockSets, + location: Location) { debug!("Borrows::before_terminator_effect sets: {:?} location: {:?}", sets, location); self.kill_loans_out_of_scope_at_location(sets, location); } diff --git a/src/test/compile-fail/nll/region-ends-after-if-condition.rs b/src/test/compile-fail/nll/region-ends-after-if-condition.rs index 1128d65af95c..da9187f43ae9 100644 --- a/src/test/compile-fail/nll/region-ends-after-if-condition.rs +++ b/src/test/compile-fail/nll/region-ends-after-if-condition.rs @@ -12,7 +12,7 @@ // in the type of `p` includes the points after `&v[0]` up to (but not // including) the call to `use_x`. The `else` branch is not included. -// compile-flags:-Zborrowck=compare -Znll +// compile-flags:-Zborrowck=compare -Znll -Ztwo-phase-borrows #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/src/test/ui/issue-45157.rs b/src/test/ui/issue-45157.rs index cff338f76c50..a906d193d995 100644 --- a/src/test/ui/issue-45157.rs +++ b/src/test/ui/issue-45157.rs @@ -37,7 +37,6 @@ fn main() { let nref = &u.z.c; //~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502] println!("{} {}", mref, nref) - //~^ ERROR cannot borrow `u.s.a` as mutable because it is also borrowed as immutable [E0502] } } diff --git a/src/test/ui/issue-45157.stderr b/src/test/ui/issue-45157.stderr index bec91f7f70de..07102f68633c 100644 --- a/src/test/ui/issue-45157.stderr +++ b/src/test/ui/issue-45157.stderr @@ -10,17 +10,6 @@ LL | //~^ ERROR cannot borrow `u.z.c` as immutable because it is also bo LL | println!("{} {}", mref, nref) | ---- borrow later used here -error[E0502]: cannot borrow `u.s.a` as mutable because it is also borrowed as immutable - --> $DIR/issue-45157.rs:39:27 - | -LL | let nref = &u.z.c; - | ------ immutable borrow occurs here -LL | //~^ ERROR cannot borrow `u.z.c` as immutable because it is also borrowed as mutable [E0502] -LL | println!("{} {}", mref, nref) - | ^^^^ ---- borrow later used here - | | - | mutable borrow occurs here - -error: aborting due to 2 previous errors +error: aborting due to previous error If you want more information on this error, try using "rustc --explain E0502" From 2ed0f516dd16c8111de0e0015d0ff42e312e2847 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Tue, 6 Mar 2018 04:19:41 -0500 Subject: [PATCH 090/830] Check for two_phase_borrows in the right place Fix a small compilation issue after I missed a critical change after rebasing yesterday (ref c933440) --- src/librustc_mir/dataflow/impls/borrows.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index b7c95da09be9..9a5221a32574 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -351,7 +351,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { /// allowed to be split into separate Reservation and /// Activation phases. fn allow_two_phase_borrow(&self, kind: mir::BorrowKind) -> bool { - self.tcx.sess.two_phase_borrows() && + self.tcx.two_phase_borrows() && (kind.allows_two_phase_borrow() || self.tcx.sess.opts.debugging_opts.two_phase_beyond_autoref) } From 7dc71ec009ffce75142b2987374401b50a3a194c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 9 Mar 2018 22:18:08 +0100 Subject: [PATCH 091/830] Remove auto trait implementation section when empty --- src/librustdoc/html/render.rs | 18 ++++++++++-------- src/test/rustdoc/empty-section.rs | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 src/test/rustdoc/empty-section.rs diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 6945a6f3724d..84f693a3be5f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3181,14 +3181,16 @@ fn render_assoc_items(w: &mut fmt::Formatter, render_impls(cx, w, concrete, containing_item)?; write!(w, "")?; - write!(w, " -

- Auto Trait Implementations -

-
- ")?; - render_impls(cx, w, synthetic, containing_item)?; - write!(w, "
")?; + if !synthetic.is_empty() { + write!(w, " +

+ Auto Trait Implementations +

+
+ ")?; + render_impls(cx, w, synthetic, containing_item)?; + write!(w, "
")?; + } } Ok(()) } diff --git a/src/test/rustdoc/empty-section.rs b/src/test/rustdoc/empty-section.rs new file mode 100644 index 000000000000..3748313593fc --- /dev/null +++ b/src/test/rustdoc/empty-section.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +#![feature(optin_builtin_traits)] + +pub struct Foo; + +// @has foo/struct.Foo.html +// @!has - '//*[@class="synthetic-implementations"]' 'Auto Trait Implementations' +impl !Send for Foo {} +impl !Sync for Foo {} From ff227c4a2d8a2fad5abf322f6f1391ae6779197f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 9 Mar 2018 13:19:00 -0800 Subject: [PATCH 092/830] rustbuild: Remove ThinLTO-related configuration This commit removes some ThinLTO/codegen unit cruft primarily only needed during the initial phase where we were adding ThinLTO support to rustc itself. The current bootstrap compiler knows about ThinLTO and has it enabled by default for multi-CGU builds which are also enabled by default. One CGU builds (aka disabling ThinLTO) can be achieved by configuring the number of codegen units to 1 for a particular builds. This also changes the defaults for our dist builders to go back to multiple CGUs. Unfortunately we're seriously bleeding for cycle time on the bots right now so we need to recover any time we can. --- src/bootstrap/bin/rustc.rs | 3 --- src/bootstrap/builder.rs | 11 ----------- src/bootstrap/config.rs | 5 ----- src/bootstrap/configure.py | 1 - src/ci/run.sh | 1 - 5 files changed, 21 deletions(-) diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 6c3c48aba72f..8ccee45f3c52 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -175,9 +175,6 @@ fn main() { if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") { cmd.arg("-C").arg(format!("codegen-units={}", s)); } - if env::var("RUSTC_THINLTO").is_ok() { - cmd.arg("-Ccodegen-units=16").arg("-Zthinlto"); - } // Emit save-analysis info. if env::var("RUSTC_SAVE_ANALYSIS") == Ok("api".to_string()) { diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 22656e5a9da4..13be709fddcf 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -792,17 +792,6 @@ impl<'a> Builder<'a> { if cmd != "bench" { cargo.arg("--release"); } - - if self.config.rust_codegen_units.is_none() && - self.build.is_rust_llvm(compiler.host) && - self.config.rust_thinlto { - cargo.env("RUSTC_THINLTO", "1"); - } else if self.config.rust_codegen_units.is_none() { - // Generally, if ThinLTO has been disabled for some reason, we - // want to set the codegen units to 1. However, we shouldn't do - // this if the option was specifically set by the user. - cargo.env("RUSTC_CODEGEN_UNITS", "1"); - } } if self.config.locked_deps { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index f15d4d358583..4bb0ae8b0b6a 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -86,7 +86,6 @@ pub struct Config { // rust codegen options pub rust_optimize: bool, pub rust_codegen_units: Option, - pub rust_thinlto: bool, pub rust_debug_assertions: bool, pub rust_debuginfo: bool, pub rust_debuginfo_lines: bool, @@ -269,7 +268,6 @@ impl Default for StringOrBool { struct Rust { optimize: Option, codegen_units: Option, - thinlto: Option, debug_assertions: Option, debuginfo: Option, debuginfo_lines: Option, @@ -427,7 +425,6 @@ impl Config { // Store off these values as options because if they're not provided // we'll infer default values for them later - let mut thinlto = None; let mut llvm_assertions = None; let mut debuginfo_lines = None; let mut debuginfo_only_std = None; @@ -471,7 +468,6 @@ impl Config { optimize = rust.optimize; ignore_git = rust.ignore_git; debug_jemalloc = rust.debug_jemalloc; - thinlto = rust.thinlto; set(&mut config.rust_optimize_tests, rust.optimize_tests); set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests); set(&mut config.codegen_tests, rust.codegen_tests); @@ -559,7 +555,6 @@ impl Config { "stable" | "beta" | "nightly" => true, _ => false, }; - config.rust_thinlto = thinlto.unwrap_or(true); config.rust_debuginfo_lines = debuginfo_lines.unwrap_or(default); config.rust_debuginfo_only_std = debuginfo_only_std.unwrap_or(default); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index e9b4a233d0af..97da7cae07f7 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -71,7 +71,6 @@ o("full-tools", None, "enable all tools") # Optimization and debugging options. These may be overridden by the release # channel, etc. o("optimize", "rust.optimize", "build optimized rust code") -o("thinlto", "rust.thinlto", "build Rust with ThinLTO enabled") o("optimize-llvm", "llvm.optimize", "build optimized LLVM") o("llvm-assertions", "llvm.assertions", "build LLVM with assertions") o("debug-assertions", "rust.debug-assertions", "build with debugging assertions") diff --git a/src/ci/run.sh b/src/ci/run.sh index 79300e08a7d3..29126e7cc9bc 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -46,7 +46,6 @@ export RUST_RELEASE_CHANNEL=nightly if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp" - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-thinlto" if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" From 8b4c623702225931811893ae21145b951358f552 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Fri, 9 Mar 2018 19:00:18 -0500 Subject: [PATCH 093/830] Remove added two-phase-borrows flag It seems whatever was causing problems has been fixed. --- src/test/compile-fail/nll/region-ends-after-if-condition.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/compile-fail/nll/region-ends-after-if-condition.rs b/src/test/compile-fail/nll/region-ends-after-if-condition.rs index da9187f43ae9..1128d65af95c 100644 --- a/src/test/compile-fail/nll/region-ends-after-if-condition.rs +++ b/src/test/compile-fail/nll/region-ends-after-if-condition.rs @@ -12,7 +12,7 @@ // in the type of `p` includes the points after `&v[0]` up to (but not // including) the call to `use_x`. The `else` branch is not included. -// compile-flags:-Zborrowck=compare -Znll -Ztwo-phase-borrows +// compile-flags:-Zborrowck=compare -Znll #![allow(warnings)] #![feature(rustc_attrs)] From 9a5d61a840b2dd3dc6d069750945759035c85286 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Fri, 9 Mar 2018 19:02:22 -0500 Subject: [PATCH 094/830] Remove some commented out code Left over from prior experimentation, no longer required. --- src/librustc_mir/dataflow/impls/borrows.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 9a5221a32574..499ed55fad41 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -332,18 +332,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { self.super_place(place, context, location); } - - /* - fn visit_statement(&mut self, - block: BasicBlock, - statement: &mir::Statement<'tcx>, - location: Location) { - if let mir::StatementKind::StorageDead(loc) = *statement { - } - - self.super_statement(block, statement, location); - } - */ } impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> { From 81130ed4b104adf28921120416dcc9db3253c996 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Mar 2018 11:22:55 +0100 Subject: [PATCH 095/830] Split param-bounds-ignored into two, it was testing two independent things Also, tweak the test for ignored type aliases such that replacing the type alias by a newtype struct leads to a well-formed type definition, and errors when used the way the type alias is used. --- ...s-ignored.rs => higher-lifetime-bounds.rs} | 26 +--------- ...d.stderr => higher-lifetime-bounds.stderr} | 48 ++++------------- src/test/ui/type-alias-bounds.rs | 51 +++++++++++++++++++ src/test/ui/type-alias-bounds.stderr | 32 ++++++++++++ 4 files changed, 95 insertions(+), 62 deletions(-) rename src/test/ui/{param-bounds-ignored.rs => higher-lifetime-bounds.rs} (77%) rename src/test/ui/{param-bounds-ignored.stderr => higher-lifetime-bounds.stderr} (61%) create mode 100644 src/test/ui/type-alias-bounds.rs create mode 100644 src/test/ui/type-alias-bounds.stderr diff --git a/src/test/ui/param-bounds-ignored.rs b/src/test/ui/higher-lifetime-bounds.rs similarity index 77% rename from src/test/ui/param-bounds-ignored.rs rename to src/test/ui/higher-lifetime-bounds.rs index 94bcdec94503..70b3b34fbd8f 100644 --- a/src/test/ui/param-bounds-ignored.rs +++ b/src/test/ui/higher-lifetime-bounds.rs @@ -10,31 +10,7 @@ #![allow(dead_code, non_camel_case_types)] -use std::rc::Rc; - -type SVec = Vec; -//~^ WARN bounds on generic parameters are ignored in type aliases -type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>; -//~^ WARN bounds on generic parameters are ignored in type aliases -type WVec<'b, T: 'b+'b> = Vec; -//~^ WARN bounds on generic parameters are ignored in type aliases -type W2Vec<'b, T> where T: 'b, T: 'b = Vec; -//~^ WARN where clauses are ignored in type aliases - -fn foo<'a>(y: &'a i32) { - // If the bounds above would matter, the code below would be rejected. - let mut x : SVec<_> = Vec::new(); - x.push(Rc::new(42)); - - let mut x : VVec<'static, 'a> = Vec::new(); - x.push(y); - - let mut x : WVec<'static, & 'a i32> = Vec::new(); - x.push(y); - - let mut x : W2Vec<'static, & 'a i32> = Vec::new(); - x.push(y); -} +// Test that bounds on higher-kinded lifetime binders are rejected. fn bar1<'a, 'b>( x: &'a i32, diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/higher-lifetime-bounds.stderr similarity index 61% rename from src/test/ui/param-bounds-ignored.stderr rename to src/test/ui/higher-lifetime-bounds.stderr index 657fec54f960..82c007474360 100644 --- a/src/test/ui/param-bounds-ignored.stderr +++ b/src/test/ui/higher-lifetime-bounds.stderr @@ -1,94 +1,68 @@ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:42:22 + --> $DIR/higher-lifetime-bounds.rs:18:22 | LL | f: for<'xa, 'xb: 'xa+'xa> fn(&'xa i32, &'xb i32) -> &'xa i32) | ^^^ ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:50:34 + --> $DIR/higher-lifetime-bounds.rs:26:34 | LL | fn bar2<'a, 'b, F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32>( | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:65:28 + --> $DIR/higher-lifetime-bounds.rs:41:28 | LL | where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32 | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:77:25 + --> $DIR/higher-lifetime-bounds.rs:53:25 | LL | where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32 | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:85:28 + --> $DIR/higher-lifetime-bounds.rs:61:28 | LL | struct S1 Fn(&'xa i32, &'xb i32) -> &'xa i32>(F); | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:87:40 + --> $DIR/higher-lifetime-bounds.rs:63:40 | LL | struct S2(F) where F: for<'xa, 'xb: 'xa> Fn(&'xa i32, &'xb i32) -> &'xa i32; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:89:37 + --> $DIR/higher-lifetime-bounds.rs:65:37 | LL | struct S3(F) where for<'xa, 'xb: 'xa> F: Fn(&'xa i32, &'xb i32) -> &'xa i32; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:92:29 + --> $DIR/higher-lifetime-bounds.rs:68:29 | LL | struct S_fnty(for<'xa, 'xb: 'xa> fn(&'xa i32, &'xb i32) -> &'xa i32); | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:95:29 + --> $DIR/higher-lifetime-bounds.rs:71:29 | LL | type T1 = Box Fn(&'xa i32, &'xb i32) -> &'xa i32>; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:99:34 + --> $DIR/higher-lifetime-bounds.rs:75:34 | LL | let _ : Option fn(&'xa i32, &'xb i32) -> &'xa i32> = None; | ^^^ error: lifetime bounds cannot be used in this context - --> $DIR/param-bounds-ignored.rs:101:38 + --> $DIR/higher-lifetime-bounds.rs:77:38 | LL | let _ : Option Fn(&'xa i32, &'xb i32) -> &'xa i32>> = None; | ^^^ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:15:14 - | -LL | type SVec = Vec; - | ^^^^ ^^^^ - | - = note: #[warn(ignored_generic_bounds)] on by default - -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:17:19 - | -LL | type VVec<'b, 'a: 'b+'b> = Vec<&'a i32>; - | ^^ ^^ - -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:19:18 - | -LL | type WVec<'b, T: 'b+'b> = Vec; - | ^^ ^^ - -warning: where clauses are ignored in type aliases - --> $DIR/param-bounds-ignored.rs:21:25 - | -LL | type W2Vec<'b, T> where T: 'b, T: 'b = Vec; - | ^^^^^ ^^^^^ - error: aborting due to 11 previous errors diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs new file mode 100644 index 000000000000..ed368e8f1500 --- /dev/null +++ b/src/test/ui/type-alias-bounds.rs @@ -0,0 +1,51 @@ +// Copyright 2014 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. + +// Test ignored_generic_bounds lint warning about bounds in type aliases + +// must-compile-successfully +#![allow(dead_code)] + +use std::rc::Rc; + +type SVec = Vec; +//~^ WARN bounds on generic parameters are ignored in type aliases +type S2Vec where T: Send = Vec; +//~^ WARN where clauses are ignored in type aliases +type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); +//~^ WARN bounds on generic parameters are ignored in type aliases +type WVec<'b, T: 'b+'b> = (&'b u32, Vec); +//~^ WARN bounds on generic parameters are ignored in type aliases +type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); +//~^ WARN where clauses are ignored in type aliases + +static STATIC : u32 = 0; + +fn foo<'a>(y: &'a i32) { + // If any of the bounds above would matter, the code below would be rejected. + // This can be seen when replacing the type aliases above by newtype structs. + // (The type aliases have no unused parameters to make that a valid transformation.) + let mut x : SVec<_> = Vec::new(); + x.push(Rc::new(42)); // is not send + + let mut x : S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not send + + let mut x : VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // 'a: 'static does not hold + + let mut x : WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // &'a i32: 'static does not hold + + let mut x : W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // &'a i32: 'static does not hold +} + +fn main() {} diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr new file mode 100644 index 000000000000..5237f3c19efc --- /dev/null +++ b/src/test/ui/type-alias-bounds.stderr @@ -0,0 +1,32 @@ +warning: bounds on generic parameters are ignored in type aliases + --> $DIR/type-alias-bounds.rs:18:14 + | +LL | type SVec = Vec; + | ^^^^ ^^^^ + | + = note: #[warn(ignored_generic_bounds)] on by default + +warning: where clauses are ignored in type aliases + --> $DIR/type-alias-bounds.rs:20:21 + | +LL | type S2Vec where T: Send = Vec; + | ^^^^^^^ + +warning: bounds on generic parameters are ignored in type aliases + --> $DIR/type-alias-bounds.rs:22:19 + | +LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); + | ^^ ^^ + +warning: bounds on generic parameters are ignored in type aliases + --> $DIR/type-alias-bounds.rs:24:18 + | +LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); + | ^^ ^^ + +warning: where clauses are ignored in type aliases + --> $DIR/type-alias-bounds.rs:26:25 + | +LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); + | ^^^^^ ^^^^^ + From 562b44d8c3dbcf7c36209774e50fe833e65a98d6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Mar 2018 11:43:51 +0100 Subject: [PATCH 096/830] Rename ignored_generic_bounds -> type_alias_bounds First of all, the lint is specific for type aliases. Second, it turns out the bounds are not entirely ignored but actually used when accessing associated types. So change the wording of the lint, and adapt its name to reality. The lint has never been on stable or beta, so renaming is safe. --- src/librustc_lint/builtin.rs | 25 +++++------ src/librustc_lint/lib.rs | 2 +- src/test/compile-fail/issue-17994.rs | 2 +- .../compile-fail/private-in-public-warn.rs | 4 +- src/test/ui/type-alias-bounds.rs | 25 ++++++++--- src/test/ui/type-alias-bounds.stderr | 43 ++++++++++++++----- 6 files changed, 68 insertions(+), 33 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c6698cbd0068..bdb36ab15b62 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1316,24 +1316,25 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { } } -/// Lint for trait and lifetime bounds that are (accidentally) accepted by the parser, but -/// ignored later. +/// Lint for trait and lifetime bounds in type aliases being mostly ignored: +/// They are relevant when using associated types, but otherwise neither checked +/// at definition site nor enforced at use site. -pub struct IgnoredGenericBounds; +pub struct TypeAliasBounds; declare_lint! { - IGNORED_GENERIC_BOUNDS, + TYPE_ALIAS_BOUNDS, Warn, - "these generic bounds are ignored" + "bounds in type aliases are not enforced" } -impl LintPass for IgnoredGenericBounds { +impl LintPass for TypeAliasBounds { fn get_lints(&self) -> LintArray { - lint_array!(IGNORED_GENERIC_BOUNDS) + lint_array!(TYPE_ALIAS_BOUNDS) } } -impl EarlyLintPass for IgnoredGenericBounds { +impl EarlyLintPass for TypeAliasBounds { fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { let type_alias_generics = match item.node { ast::ItemKind::Ty(_, ref generics) => generics, @@ -1343,8 +1344,8 @@ impl EarlyLintPass for IgnoredGenericBounds { if !type_alias_generics.where_clause.predicates.is_empty() { let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter() .map(|pred| pred.span()).collect(); - cx.span_lint(IGNORED_GENERIC_BOUNDS, spans, - "where clauses are ignored in type aliases"); + cx.span_lint(TYPE_ALIAS_BOUNDS, spans, + "where clauses are not enforced in type aliases"); } // The parameters must not have bounds for param in type_alias_generics.params.iter() { @@ -1354,9 +1355,9 @@ impl EarlyLintPass for IgnoredGenericBounds { }; if !spans.is_empty() { cx.span_lint( - IGNORED_GENERIC_BOUNDS, + TYPE_ALIAS_BOUNDS, spans, - "bounds on generic parameters are ignored in type aliases", + "bounds on generic parameters are not enforced in type aliases", ); } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 779aa3a9037c..38f7a0b6faa0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -109,7 +109,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UnusedImportBraces, AnonymousParameters, UnusedDocComment, - IgnoredGenericBounds, + TypeAliasBounds, ); add_early_builtin_with_new!(sess, diff --git a/src/test/compile-fail/issue-17994.rs b/src/test/compile-fail/issue-17994.rs index 0f30e2461cf3..7c3811e2ef28 100644 --- a/src/test/compile-fail/issue-17994.rs +++ b/src/test/compile-fail/issue-17994.rs @@ -10,5 +10,5 @@ trait Tr {} type Huh where T: Tr = isize; //~ ERROR type parameter `T` is unused - //~| WARNING where clauses are ignored in type aliases + //~| WARNING where clauses are not enforced in type aliases fn main() {} diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index cc9eed7e6542..8bd9b0a901d6 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -58,7 +58,7 @@ mod traits { pub trait PubTr {} pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING bounds on generic parameters are ignored + //~^ WARNING bounds on generic parameters are not enforced in type aliases //~| WARNING hard error pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error @@ -85,7 +85,7 @@ mod traits_where { pub type Alias where T: PrivTr = T; //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error - //~| WARNING where clauses are ignored in type aliases + //~| WARNING where clauses are not enforced in type aliases pub trait Tr2 where T: PrivTr {} //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs index ed368e8f1500..7ec3afd9c870 100644 --- a/src/test/ui/type-alias-bounds.rs +++ b/src/test/ui/type-alias-bounds.rs @@ -10,21 +10,20 @@ // Test ignored_generic_bounds lint warning about bounds in type aliases -// must-compile-successfully #![allow(dead_code)] use std::rc::Rc; type SVec = Vec; -//~^ WARN bounds on generic parameters are ignored in type aliases +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type S2Vec where T: Send = Vec; -//~^ WARN where clauses are ignored in type aliases +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); -//~^ WARN bounds on generic parameters are ignored in type aliases +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type WVec<'b, T: 'b+'b> = (&'b u32, Vec); -//~^ WARN bounds on generic parameters are ignored in type aliases +//~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); -//~^ WARN where clauses are ignored in type aliases +//~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] static STATIC : u32 = 0; @@ -48,4 +47,18 @@ fn foo<'a>(y: &'a i32) { x.1.push(y); // &'a i32: 'static does not hold } +// Bounds are not checked either, i.e. the definition is not necessarily well-formed +struct Sendable(T); +type MySendable = Sendable; // no error here! + +// However, bounds *are* taken into account when accessing associated types +trait Bound { type Assoc; } +type T1 = U::Assoc; +//~^ WARN bounds on generic parameters are not enforced in type aliases +type T2 where U: Bound = U::Assoc; +//~^ WARN where clauses are not enforced in type aliases +type T3 = U::Assoc; +//~^ ERROR associated type `Assoc` not found for `U` +type T4 = ::Assoc; + fn main() {} diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr index 5237f3c19efc..46aacd7321cc 100644 --- a/src/test/ui/type-alias-bounds.stderr +++ b/src/test/ui/type-alias-bounds.stderr @@ -1,32 +1,53 @@ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/type-alias-bounds.rs:18:14 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:17:14 | LL | type SVec = Vec; | ^^^^ ^^^^ | - = note: #[warn(ignored_generic_bounds)] on by default + = note: #[warn(type_alias_bounds)] on by default -warning: where clauses are ignored in type aliases - --> $DIR/type-alias-bounds.rs:20:21 +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:19:21 | LL | type S2Vec where T: Send = Vec; | ^^^^^^^ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/type-alias-bounds.rs:22:19 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:21:19 | LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); | ^^ ^^ -warning: bounds on generic parameters are ignored in type aliases - --> $DIR/type-alias-bounds.rs:24:18 +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:23:18 | LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); | ^^ ^^ -warning: where clauses are ignored in type aliases - --> $DIR/type-alias-bounds.rs:26:25 +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:25:25 | LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); | ^^^^^ ^^^^^ +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:56:12 + | +LL | type T1 = U::Assoc; + | ^^^^^ + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:58:18 + | +LL | type T2 where U: Bound = U::Assoc; + | ^^^^^^^^ + +error[E0220]: associated type `Assoc` not found for `U` + --> $DIR/type-alias-bounds.rs:60:14 + | +LL | type T3 = U::Assoc; + | ^^^^^^^^ associated type `Assoc` not found + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0220" From b8cd6e5d7b885d3af2832cbe4a684ce6e6cf3614 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 10 Mar 2018 18:38:27 +0800 Subject: [PATCH 097/830] Prevents the crash log printer on macOS from crashing the entire job. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4eff6337ad8c..8315cc9f90f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -275,11 +275,12 @@ after_failure: - ls -lat $HOME/Library/Logs/DiagnosticReports/ - find $HOME/Library/Logs/DiagnosticReports -type f + -name '*.crash' -not -name '*.stage2-*.crash' -not -name 'com.apple.CoreSimulator.CoreSimulatorService-*.crash' -exec printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" {} \; -exec head -750 {} \; - -exec echo travis_fold":"end:crashlog \; + -exec echo travis_fold":"end:crashlog \; || true # attempt to debug anything killed by the oom killer on linux, just to see if # it happened From c67e55338442071666da7fb310b064b8e31fbacb Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 10 Mar 2018 19:55:04 +0800 Subject: [PATCH 098/830] Print /proc/cpuinfo and /proc/meminfo before starting to build. --- src/ci/run.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ci/run.sh b/src/ci/run.sh index 79300e08a7d3..7ce50d5c2000 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -91,11 +91,19 @@ make check-bootstrap travis_fold end check-bootstrap travis_time_finish +# Display the CPU and memory information. This helps us know why the CI timing +# is fluctuating. +travis_fold start log-system-info if [ "$TRAVIS_OS_NAME" = "osx" ]; then + system_profiler SPHardwareDataType || true + sysctl hw || true ncpus=$(sysctl -n hw.ncpu) else + cat /proc/cpuinfo || true + cat /proc/meminfo || true ncpus=$(grep processor /proc/cpuinfo | wc -l) fi +travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then sh -x -c "$SCRIPT" From 0e6d40a3fb1000d1105646703c60c9201f3ed5cc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 10 Mar 2018 13:32:11 +0100 Subject: [PATCH 099/830] type_alias_bounds lint: If the type alias uses an associated type without "as", suggest to use the "as" form instead. This is necessary to get rid of the type bound, and hence silence the warning. --- src/librustc/hir/mod.rs | 19 +++++++ src/librustc_lint/builtin.rs | 83 +++++++++++++++++++++++++--- src/librustc_lint/lib.rs | 2 +- src/test/ui/type-alias-bounds.rs | 17 ++++-- src/test/ui/type-alias-bounds.stderr | 60 +++++++++++++++----- 5 files changed, 151 insertions(+), 30 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f4638c23c5f4..d4bfa7a1d308 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -395,6 +395,15 @@ pub enum TyParamBound { RegionTyParamBound(Lifetime), } +impl TyParamBound { + pub fn span(&self) -> Span { + match self { + &TraitTyParamBound(ref t, ..) => t.span, + &RegionTyParamBound(ref l) => l.span, + } + } +} + /// A modifier on a bound, currently this is only used for `?Sized`, where the /// modifier is `Maybe`. Negative bounds should also be handled here. #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -570,6 +579,16 @@ pub enum WherePredicate { EqPredicate(WhereEqPredicate), } +impl WherePredicate { + pub fn span(&self) -> Span { + match self { + &WherePredicate::BoundPredicate(ref p) => p.span, + &WherePredicate::RegionPredicate(ref p) => p.span, + &WherePredicate::EqPredicate(ref p) => p.span, + } + } +} + /// A type bound, eg `for<'c> Foo: Send+Clone+'c` #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereBoundPredicate { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index bdb36ab15b62..2ea13b2cb6d6 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -46,6 +46,7 @@ use syntax::attr; use syntax::feature_gate::{AttributeGate, AttributeType, Stability, deprecated_attributes}; use syntax_pos::{BytePos, Span, SyntaxContext}; use syntax::symbol::keywords; +use syntax::errors::DiagnosticBuilder; use rustc::hir::{self, PatKind}; use rustc::hir::intravisit::FnKind; @@ -1334,31 +1335,97 @@ impl LintPass for TypeAliasBounds { } } -impl EarlyLintPass for TypeAliasBounds { - fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { - let type_alias_generics = match item.node { - ast::ItemKind::Ty(_, ref generics) => generics, +impl TypeAliasBounds { + fn is_type_variable_assoc(qpath: &hir::QPath) -> bool { + match *qpath { + hir::QPath::TypeRelative(ref ty, _) => { + // If this is a type variable, we found a `T::Assoc`. + match ty.node { + hir::TyPath(hir::QPath::Resolved(None, ref path)) => { + match path.def { + Def::TyParam(_) => true, + _ => false + } + } + _ => false + } + } + hir::QPath::Resolved(..) => false, + } + } + + fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder) { + // Access to associates types should use `::Assoc`, which does not need a + // bound. Let's see of this type does that. + + // We use an AST visitor to walk the type. + use rustc::hir::intravisit::{self, Visitor}; + use syntax::ast::NodeId; + struct WalkAssocTypes<'a, 'db> where 'db: 'a { + err: &'a mut DiagnosticBuilder<'db> + } + impl<'a, 'db, 'v> Visitor<'v> for WalkAssocTypes<'a, 'db> { + fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> + { + intravisit::NestedVisitorMap::None + } + + fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) { + if TypeAliasBounds::is_type_variable_assoc(qpath) { + self.err.span_help(span, + "use absolute paths (i.e., ::Assoc) to refer to associated \ + types in type aliases"); + } + intravisit::walk_qpath(self, qpath, id, span) + } + } + + // Let's go for a walk! + let mut visitor = WalkAssocTypes { err }; + visitor.visit_ty(ty); + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds { + fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { + let (ty, type_alias_generics) = match item.node { + hir::ItemTy(ref ty, ref generics) => (&*ty, generics), _ => return, }; + let mut suggested_changing_assoc_types = false; // There must not be a where clause if !type_alias_generics.where_clause.predicates.is_empty() { let spans : Vec<_> = type_alias_generics.where_clause.predicates.iter() .map(|pred| pred.span()).collect(); - cx.span_lint(TYPE_ALIAS_BOUNDS, spans, + let mut err = cx.struct_span_lint(TYPE_ALIAS_BOUNDS, spans, "where clauses are not enforced in type aliases"); + err.help("the clause will not be checked when the type alias is used, \ + and should be removed"); + if !suggested_changing_assoc_types { + TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + suggested_changing_assoc_types = true; + } + err.emit(); } // The parameters must not have bounds for param in type_alias_generics.params.iter() { let spans : Vec<_> = match param { - &ast::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(), - &ast::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(), + &hir::GenericParam::Lifetime(ref l) => l.bounds.iter().map(|b| b.span).collect(), + &hir::GenericParam::Type(ref ty) => ty.bounds.iter().map(|b| b.span()).collect(), }; if !spans.is_empty() { - cx.span_lint( + let mut err = cx.struct_span_lint( TYPE_ALIAS_BOUNDS, spans, "bounds on generic parameters are not enforced in type aliases", ); + err.help("the bound will not be checked when the type alias is used, \ + and should be removed"); + if !suggested_changing_assoc_types { + TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + suggested_changing_assoc_types = true; + } + err.emit(); } } } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 38f7a0b6faa0..7237d2fd5d1c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -109,7 +109,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UnusedImportBraces, AnonymousParameters, UnusedDocComment, - TypeAliasBounds, ); add_early_builtin_with_new!(sess, @@ -139,6 +138,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { MutableTransmutes, UnionsWithDropFields, UnreachablePub, + TypeAliasBounds, ); add_builtin_with_new!(sess, diff --git a/src/test/ui/type-alias-bounds.rs b/src/test/ui/type-alias-bounds.rs index 7ec3afd9c870..c1cdeef3a463 100644 --- a/src/test/ui/type-alias-bounds.rs +++ b/src/test/ui/type-alias-bounds.rs @@ -10,6 +10,7 @@ // Test ignored_generic_bounds lint warning about bounds in type aliases +// must-compile-successfully #![allow(dead_code)] use std::rc::Rc; @@ -53,12 +54,16 @@ type MySendable = Sendable; // no error here! // However, bounds *are* taken into account when accessing associated types trait Bound { type Assoc; } -type T1 = U::Assoc; -//~^ WARN bounds on generic parameters are not enforced in type aliases -type T2 where U: Bound = U::Assoc; -//~^ WARN where clauses are not enforced in type aliases -type T3 = U::Assoc; -//~^ ERROR associated type `Assoc` not found for `U` +type T1 = U::Assoc; //~ WARN not enforced in type aliases +type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases + +// This errors +// type T3 = U::Assoc; +// Do this instead type T4 = ::Assoc; +// Make sure the help about associatd types is not shown incorrectly +type T5 = ::Assoc; //~ WARN not enforced in type aliases +type T6 = ::std::vec::Vec; //~ WARN not enforced in type aliases + fn main() {} diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr index 46aacd7321cc..5288dca79be6 100644 --- a/src/test/ui/type-alias-bounds.stderr +++ b/src/test/ui/type-alias-bounds.stderr @@ -1,53 +1,83 @@ warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:17:14 + --> $DIR/type-alias-bounds.rs:18:14 | LL | type SVec = Vec; | ^^^^ ^^^^ | = note: #[warn(type_alias_bounds)] on by default + = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:19:21 + --> $DIR/type-alias-bounds.rs:20:21 | LL | type S2Vec where T: Send = Vec; | ^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:21:19 + --> $DIR/type-alias-bounds.rs:22:19 | LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); | ^^ ^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:23:18 + --> $DIR/type-alias-bounds.rs:24:18 | LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); | ^^ ^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:25:25 + --> $DIR/type-alias-bounds.rs:26:25 | LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); | ^^^^^ ^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:56:12 + --> $DIR/type-alias-bounds.rs:57:12 | -LL | type T1 = U::Assoc; +LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed +help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:57:21 + | +LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases + | ^^^^^^^^ warning: where clauses are not enforced in type aliases --> $DIR/type-alias-bounds.rs:58:18 | -LL | type T2 where U: Bound = U::Assoc; +LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^^^^ - -error[E0220]: associated type `Assoc` not found for `U` - --> $DIR/type-alias-bounds.rs:60:14 | -LL | type T3 = U::Assoc; - | ^^^^^^^^ associated type `Assoc` not found + = help: the clause will not be checked when the type alias is used, and should be removed +help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases + --> $DIR/type-alias-bounds.rs:58:29 + | +LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases + | ^^^^^^^^ -error: aborting due to previous error +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:66:12 + | +LL | type T5 = ::Assoc; //~ WARN not enforced in type aliases + | ^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias-bounds.rs:67:12 + | +LL | type T6 = ::std::vec::Vec; //~ WARN not enforced in type aliases + | ^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed -If you want more information on this error, try using "rustc --explain E0220" From 108c56660ae111c4e2ef68b2c413963c7f09da69 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 10 Mar 2018 12:38:41 +0000 Subject: [PATCH 100/830] Merge LLVM fix for undefined bss globals This fixes #41315. --- src/llvm | 2 +- src/rustllvm/llvm-rebuild-trigger | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/llvm b/src/llvm index 0903c72cbbc3..6ceaaa4b0176 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 0903c72cbbc3dafcb5c88820e4a8a98c3a764cf3 +Subproject commit 6ceaaa4b0176a200e4bbd347d6a991ab6c776ede diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger index 63af7a0d538e..c4c0f1ab6e60 100644 --- a/src/rustllvm/llvm-rebuild-trigger +++ b/src/rustllvm/llvm-rebuild-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2018-03-06 +2018-03-10 From 933417549c0e3fab110d8f435eb8e80303c35bde Mon Sep 17 00:00:00 2001 From: Sebastian Humenda Date: Sat, 10 Mar 2018 15:00:26 +0100 Subject: [PATCH 101/830] remove linker arguments from L4Re target These change from release to release and are impossible to get right, since they are generated by Make magic. --- src/librustc_back/target/l4re_base.rs | 71 +++++-------------- .../target/x86_64_unknown_l4re_uclibc.rs | 2 +- 2 files changed, 17 insertions(+), 56 deletions(-) diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_back/target/l4re_base.rs index 7cb7f8d613de..bff91e8f9952 100644 --- a/src/librustc_back/target/l4re_base.rs +++ b/src/librustc_back/target/l4re_base.rs @@ -8,74 +8,35 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use PanicStrategy; use LinkerFlavor; +use PanicStrategy; use target::{LinkArgs, TargetOptions}; use std::default::Default; -use std::env; -use std::process::Command; +//use std::process::Command; // Use GCC to locate code for crt* libraries from the host, not from L4Re. Note // that a few files also come from L4Re, for these, the function shouldn't be // used. This uses GCC for the location of the file, but GCC is required for L4Re anyway. -fn get_path_or(filename: &str) -> String { - let child = Command::new("gcc") - .arg(format!("-print-file-name={}", filename)).output() - .expect("Failed to execute GCC"); - String::from_utf8(child.stdout) - .expect("Couldn't read path from GCC").trim().into() -} +//fn get_path_or(filename: &str) -> String { +// let child = Command::new("gcc") +// .arg(format!("-print-file-name={}", filename)).output() +// .expect("Failed to execute GCC"); +// String::from_utf8(child.stdout) +// .expect("Couldn't read path from GCC").trim().into() +//} -pub fn opts() -> Result { - let l4re_lib_path = env::var_os("L4RE_LIBDIR").ok_or("Unable to find L4Re \ - library directory: L4RE_LIBDIR not set.")?.into_string().unwrap(); - let mut pre_link_args = LinkArgs::new(); - pre_link_args.insert(LinkerFlavor::Ld, vec![ - format!("-T{}/main_stat.ld", l4re_lib_path), - "--defsym=__executable_start=0x01000000".to_string(), - "--defsym=__L4_KIP_ADDR__=0x6ffff000".to_string(), - format!("{}/crt1.o", l4re_lib_path), - format!("{}/crti.o", l4re_lib_path), - get_path_or("crtbeginT.o"), - ]); - let mut post_link_args = LinkArgs::new(); - post_link_args.insert(LinkerFlavor::Ld, vec![ - format!("{}/l4f/libpthread.a", l4re_lib_path), - format!("{}/l4f/libc_be_sig.a", l4re_lib_path), - format!("{}/l4f/libc_be_sig_noop.a", l4re_lib_path), - format!("{}/l4f/libc_be_socket_noop.a", l4re_lib_path), - format!("{}/l4f/libc_be_fs_noop.a", l4re_lib_path), - format!("{}/l4f/libc_be_sem_noop.a", l4re_lib_path), - format!("{}/l4f/libl4re-vfs.o.a", l4re_lib_path), - format!("{}/l4f/lib4re.a", l4re_lib_path), - format!("{}/l4f/lib4re-util.a", l4re_lib_path), - format!("{}/l4f/libc_support_misc.a", l4re_lib_path), - format!("{}/l4f/libsupc++.a", l4re_lib_path), - format!("{}/l4f/lib4shmc.a", l4re_lib_path), - format!("{}/l4f/lib4re-c.a", l4re_lib_path), - format!("{}/l4f/lib4re-c-util.a", l4re_lib_path), - get_path_or("libgcc_eh.a"), - format!("{}/l4f/libdl.a", l4re_lib_path), - "--start-group".to_string(), - format!("{}/l4f/libl4util.a", l4re_lib_path), - format!("{}/l4f/libc_be_l4re.a", l4re_lib_path), - format!("{}/l4f/libuc_c.a", l4re_lib_path), - format!("{}/l4f/libc_be_l4refile.a", l4re_lib_path), - "--end-group".to_string(), - format!("{}/l4f/libl4sys.a", l4re_lib_path), - "-gc-sections".to_string(), - get_path_or("crtend.o"), - format!("{}/crtn.o", l4re_lib_path), - ]); +pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![]); - Ok(TargetOptions { + TargetOptions { executables: true, has_elf_tls: false, exe_allocation_crate: None, panic_strategy: PanicStrategy::Abort, - pre_link_args, - post_link_args, + linker: "ld".to_string(), + pre_link_args: args, target_family: Some("unix".to_string()), .. Default::default() - }) + } } diff --git a/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs b/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs index 6e849f19cf20..821a77f52f51 100644 --- a/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs +++ b/src/librustc_back/target/x86_64_unknown_l4re_uclibc.rs @@ -12,7 +12,7 @@ use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { - let mut base = super::l4re_base::opts()?; + let mut base = super::l4re_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); From 9fd941e847fd02c0a74059df78e9040b8e0ada2c Mon Sep 17 00:00:00 2001 From: Sebastian Humenda Date: Sat, 10 Mar 2018 15:01:51 +0100 Subject: [PATCH 102/830] add stub for retrieving number of CPUs --- src/librustc_back/target/l4re_base.rs | 2 +- src/libtest/lib.rs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc_back/target/l4re_base.rs b/src/librustc_back/target/l4re_base.rs index bff91e8f9952..3b13ef015006 100644 --- a/src/librustc_back/target/l4re_base.rs +++ b/src/librustc_back/target/l4re_base.rs @@ -34,7 +34,7 @@ pub fn opts() -> TargetOptions { has_elf_tls: false, exe_allocation_crate: None, panic_strategy: PanicStrategy::Abort, - linker: "ld".to_string(), + linker: Some("ld".to_string()), pre_link_args: args, target_family: Some("unix".to_string()), .. Default::default() diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 82077bc4cd48..59d701dd0fbc 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1294,6 +1294,12 @@ fn get_concurrency() -> usize { // FIXME: implement 1 } + + #[cfg(target_os = "l4re")] + fn num_cpus() -> usize { + // FIXME: implement + 1 + } } pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec { From 9b599856a4b7e375e4e54eb759c250be969f5562 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Sun, 11 Mar 2018 00:04:15 -0800 Subject: [PATCH 103/830] in which some labels and notes are upgraded to structured suggestions (Meanwhile, a couple of parse-fail tests are moved to UI tests so that the reader can see the new output, and an existing UI test is given a more evocative name.) --- src/librustc_typeck/check/mod.rs | 8 ++++---- src/libsyntax/parse/parser.rs | 13 ++++++++----- ...> issue-41679-tilde-bitwise-negation-attempt.rs} | 2 +- ...ssue-41679-tilde-bitwise-negation-attempt.stderr | 8 ++++++++ src/test/ui/did_you_mean/issue-41679.stderr | 10 ---------- .../did_you_mean}/match-refactor-to-expr.rs | 2 +- .../ui/did_you_mean/match-refactor-to-expr.stderr | 13 +++++++++++++ .../did_you_mean}/pub-macro-rules.rs | 3 +-- src/test/ui/did_you_mean/pub-macro-rules.stderr | 8 ++++++++ src/test/ui/issue-11004.stderr | 8 ++------ 10 files changed, 46 insertions(+), 29 deletions(-) rename src/test/ui/did_you_mean/{issue-41679.rs => issue-41679-tilde-bitwise-negation-attempt.rs} (88%) create mode 100644 src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr delete mode 100644 src/test/ui/did_you_mean/issue-41679.stderr rename src/test/{parse-fail => ui/did_you_mean}/match-refactor-to-expr.rs (91%) create mode 100644 src/test/ui/did_you_mean/match-refactor-to-expr.stderr rename src/test/{parse-fail => ui/did_you_mean}/pub-macro-rules.rs (91%) create mode 100644 src/test/ui/did_you_mean/pub-macro-rules.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 19085ff039ec..1ea1ff1fae24 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3096,10 +3096,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; } ty::TyRawPtr(..) => { - err.note(&format!("`{0}` is a native pointer; perhaps you need to deref \ - with `(*{0}).{1}`", - self.tcx.hir.node_to_pretty_string(base.id), - field.node)); + let base = self.tcx.hir.node_to_pretty_string(base.id); + let msg = format!("`{}` is a native pointer; try dereferencing it", base); + let suggestion = format!("(*{}).{}", base, field.node); + err.span_suggestion(field.span, &msg, suggestion); } _ => {} } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f5aa01fb0345..bd0ca0e67048 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2831,9 +2831,10 @@ impl<'a> Parser<'a> { let (span, e) = self.interpolated_or_expr_span(e)?; let span_of_tilde = lo; let mut err = self.diagnostic().struct_span_err(span_of_tilde, - "`~` can not be used as a unary operator"); - err.span_label(span_of_tilde, "did you mean `!`?"); - err.help("use `!` instead of `~` if you meant to perform bitwise negation"); + "`~` cannot be used as a unary operator"); + err.span_suggestion_short(span_of_tilde, + "use `!` to perform bitwise negation", + "!".to_owned()); err.emit(); (lo.to(span), self.mk_unary(UnOp::Not, e)) } @@ -3389,7 +3390,7 @@ impl<'a> Parser<'a> { None)?; if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) { if self.token == token::Token::Semi { - e.span_note(match_span, "did you mean to remove this `match` keyword?"); + e.span_suggestion_short(match_span, "try removing this `match`", "".to_owned()); } return Err(e) } @@ -5361,7 +5362,9 @@ impl<'a> Parser<'a> { if is_macro_rules { let mut err = self.diagnostic() .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`"); - err.help("did you mean #[macro_export]?"); + err.span_suggestion(sp, + "try exporting the macro", + "#[macro_export]".to_owned()); Err(err) } else { let mut err = self.diagnostic() diff --git a/src/test/ui/did_you_mean/issue-41679.rs b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs similarity index 88% rename from src/test/ui/did_you_mean/issue-41679.rs rename to src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs index 98c909e212fd..e8fd248011cb 100644 --- a/src/test/ui/did_you_mean/issue-41679.rs +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs @@ -9,5 +9,5 @@ // except according to those terms. fn main() { - let x = ~1; //~ ERROR can not be used as a unary operator + let x = ~1; //~ ERROR cannot be used as a unary operator } diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr new file mode 100644 index 000000000000..f13f15f63771 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr @@ -0,0 +1,8 @@ +error: `~` cannot be used as a unary operator + --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:12:13 + | +LL | let x = ~1; //~ ERROR cannot be used as a unary operator + | ^ help: use `!` to perform bitwise negation + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-41679.stderr b/src/test/ui/did_you_mean/issue-41679.stderr deleted file mode 100644 index c17812fc0cb9..000000000000 --- a/src/test/ui/did_you_mean/issue-41679.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: `~` can not be used as a unary operator - --> $DIR/issue-41679.rs:12:13 - | -LL | let x = ~1; //~ ERROR can not be used as a unary operator - | ^ did you mean `!`? - | - = help: use `!` instead of `~` if you meant to perform bitwise negation - -error: aborting due to previous error - diff --git a/src/test/parse-fail/match-refactor-to-expr.rs b/src/test/ui/did_you_mean/match-refactor-to-expr.rs similarity index 91% rename from src/test/parse-fail/match-refactor-to-expr.rs rename to src/test/ui/did_you_mean/match-refactor-to-expr.rs index e2fee1d18959..3c88608697aa 100644 --- a/src/test/parse-fail/match-refactor-to-expr.rs +++ b/src/test/ui/did_you_mean/match-refactor-to-expr.rs @@ -12,7 +12,7 @@ fn main() { let foo = - match //~ NOTE did you mean to remove this `match` keyword? + match Some(4).unwrap_or_else(5) //~^ NOTE expected one of `.`, `?`, `{`, or an operator here ; //~ NOTE unexpected token diff --git a/src/test/ui/did_you_mean/match-refactor-to-expr.stderr b/src/test/ui/did_you_mean/match-refactor-to-expr.stderr new file mode 100644 index 000000000000..ecca781684ce --- /dev/null +++ b/src/test/ui/did_you_mean/match-refactor-to-expr.stderr @@ -0,0 +1,13 @@ +error: expected one of `.`, `?`, `{`, or an operator, found `;` + --> $DIR/match-refactor-to-expr.rs:18:9 + | +LL | match + | ----- help: try removing this `match` +LL | Some(4).unwrap_or_else(5) + | - expected one of `.`, `?`, `{`, or an operator here +LL | //~^ NOTE expected one of `.`, `?`, `{`, or an operator here +LL | ; //~ NOTE unexpected token + | ^ unexpected token + +error: aborting due to previous error + diff --git a/src/test/parse-fail/pub-macro-rules.rs b/src/test/ui/did_you_mean/pub-macro-rules.rs similarity index 91% rename from src/test/parse-fail/pub-macro-rules.rs rename to src/test/ui/did_you_mean/pub-macro-rules.rs index 93b992f2f8af..65a0d642cd7d 100644 --- a/src/test/parse-fail/pub-macro-rules.rs +++ b/src/test/ui/did_you_mean/pub-macro-rules.rs @@ -9,8 +9,7 @@ // except according to those terms. #[macro_use] mod bleh { - pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation with `pub` - //~^ HELP did you mean #[macro_export]? + pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation ($n:ident) => ( fn $n () -> i32 { 1 diff --git a/src/test/ui/did_you_mean/pub-macro-rules.stderr b/src/test/ui/did_you_mean/pub-macro-rules.stderr new file mode 100644 index 000000000000..dfeab75525ba --- /dev/null +++ b/src/test/ui/did_you_mean/pub-macro-rules.stderr @@ -0,0 +1,8 @@ +error: can't qualify macro_rules invocation with `pub` + --> $DIR/pub-macro-rules.rs:12:5 + | +LL | pub macro_rules! foo { //~ ERROR can't qualify macro_rules invocation + | ^^^ help: try exporting the macro: `#[macro_export]` + +error: aborting due to previous error + diff --git a/src/test/ui/issue-11004.stderr b/src/test/ui/issue-11004.stderr index 4cfc7d23bd0b..268c3cd6d2af 100644 --- a/src/test/ui/issue-11004.stderr +++ b/src/test/ui/issue-11004.stderr @@ -2,17 +2,13 @@ error[E0609]: no field `x` on type `*mut A` --> $DIR/issue-11004.rs:17:21 | LL | let x : i32 = n.x; //~ no field `x` on type `*mut A` - | ^ - | - = note: `n` is a native pointer; perhaps you need to deref with `(*n).x` + | ^ help: `n` is a native pointer; try dereferencing it: `(*n).x` error[E0609]: no field `y` on type `*mut A` --> $DIR/issue-11004.rs:18:21 | LL | let y : f64 = n.y; //~ no field `y` on type `*mut A` - | ^ - | - = note: `n` is a native pointer; perhaps you need to deref with `(*n).y` + | ^ help: `n` is a native pointer; try dereferencing it: `(*n).y` error: aborting due to 2 previous errors From 908328fca03c1bf69ce335974f4dcabd8e5d18f4 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 11 Mar 2018 07:41:13 -0400 Subject: [PATCH 104/830] Document when types have OS-dependent sizes As per issue #43601, types that can change size depending on the target operating system should say so in their documentation. I used this template when adding doc comments: The size of a(n) struct may vary depending on the target operating system, and may change between Rust releases. For enums, I used "instance" instead of "struct". --- src/libstd/io/stdio.rs | 9 +++++++++ src/libstd/net/addr.rs | 9 +++++++++ src/libstd/net/ip.rs | 9 +++++++++ src/libstd/time.rs | 6 ++++++ 4 files changed, 33 insertions(+) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 1f73054e3bee..4565b7fa0d6f 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -30,18 +30,27 @@ thread_local! { /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdin_raw` function. +/// +/// The size of a StdinRaw struct may vary depending on the target operating +/// system, and may change between Rust releases. struct StdinRaw(stdio::Stdin); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdout_raw` function. +/// +/// The size of a StdoutRaw struct may vary depending on the target operating +/// system, and may change between Rust releases. struct StdoutRaw(stdio::Stdout); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stderr_raw` function. +/// +/// The size of a StderrRaw struct may vary depending on the target operating +/// system, and may change between Rust releases. struct StderrRaw(stdio::Stderr); /// Constructs a new raw handle to the standard input of this process. diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index fa430939f058..75b050638392 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -28,6 +28,9 @@ use slice; /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and /// [`SocketAddrV6`]'s respective documentation for more details. /// +/// The size of a SocketAddr instance may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IP address]: ../../std/net/enum.IpAddr.html /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html @@ -61,6 +64,9 @@ pub enum SocketAddr { /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// +/// The size of a SocketAddrV4 struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html @@ -88,6 +94,9 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in } /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// +/// The size of a SocketAddrV6 struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 0d73a6f4fd7f..36a34e147d55 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -26,6 +26,9 @@ use sys_common::{AsInner, FromInner}; /// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their /// respective documentation for more details. /// +/// The size of an IpAddr instance may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html /// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html /// @@ -61,6 +64,9 @@ pub enum IpAddr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// +/// The size of an Ipv4Addr struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// @@ -93,6 +99,9 @@ pub struct Ipv4Addr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// +/// The size of an Ipv6Addr struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 12f2a9bb85f8..054450a51862 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -49,6 +49,9 @@ pub use core::time::Duration; /// allows measuring the duration between two instants (or comparing two /// instants). /// +/// The size of an Instant struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// Example: /// /// ```no_run @@ -88,6 +91,9 @@ pub struct Instant(time::Instant); /// fixed point in time, a `SystemTime` can be converted to a human-readable time, /// or perhaps some other string representation. /// +/// The size of a SystemTime struct may vary depending on the target operating +/// system, and may change between Rust releases. +/// /// [`Instant`]: ../../std/time/struct.Instant.html /// [`Result`]: ../../std/result/enum.Result.html /// [`Duration`]: ../../std/time/struct.Duration.html From c033c6e47c1a84e2902c75a1b5ec161362f34f18 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 11 Mar 2018 10:03:23 -0400 Subject: [PATCH 105/830] Fix hygene issue when deriving Debug The code for several of the core traits doesn't use hygenic macros. This isn't a problem, except for the Debug trait, which is the only one that uses a variable, named "builder". Variables can't share names with unit structs, so attempting to [derive(Debug)] on any type while a unit struct with the name "builder" was in scope would result in an error. This commit just changes the name of the variable to "__debug_trait_builder", because I couldn't figure out how to get a list of all unit structs in-scope from within the derive expansion function. If someone wants to have a unit struct with the exact name "__debug_trait_builder", they'll just have to do it without a [derive(Debug)]. --- src/libsyntax_ext/deriving/debug.rs | 2 +- src/test/run-pass/issue-42453.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-42453.rs diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index 82fc09fca69a..7b23de582a79 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -70,7 +70,7 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Debug)] +struct builder; + +fn main() { + +} + From f2a8556df455c37b64d7e7df1454fc156f6be342 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 9 Mar 2018 11:31:04 -0800 Subject: [PATCH 106/830] Update stdsimd module Pulls in a redesigned `std::simd` module as well as a replacement for the `is_target_feature_detected!` macro --- src/libcore/lib.rs | 2 ++ src/stdsimd | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 1efd605112dc..448e49ffebda 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -74,7 +74,9 @@ #![feature(concat_idents)] #![feature(const_fn)] #![feature(custom_attribute)] +#![feature(doc_cfg)] #![feature(doc_spotlight)] +#![feature(fn_must_use)] #![feature(fundamental)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] diff --git a/src/stdsimd b/src/stdsimd index 678cbd325c84..ab9356f2af65 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit 678cbd325c84070c9dbe4303969fbd2734c0b4ee +Subproject commit ab9356f2af650815d339d77306f0d09c44d531ad From 994bfd414138e623f315f4273841b9f006ac72ee Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 26 Feb 2018 09:07:16 -0800 Subject: [PATCH 107/830] Update Cargo submodule Required moving all fulldeps tests depending on `rand` to different locations as now there's multiple `rand` crates that can't be implicitly linked against. --- src/Cargo.lock | 712 +++++++++--------- src/bootstrap/builder.rs | 4 +- src/liballoc/Cargo.toml | 2 +- src/liballoc/tests/binary_heap.rs | 83 +- src/liballoc/tests/slice.rs | 165 ++++ src/libcore/Cargo.toml | 3 + src/libcore/tests/lib.rs | 1 + src/libcore/tests/num/flt2dec/mod.rs | 1 + .../tests/num/flt2dec/random.rs} | 11 +- src/libcore/tests/slice.rs | 71 +- src/libstd/Cargo.toml | 2 +- .../run-pass-fulldeps => libstd/tests}/env.rs | 4 - .../binary-heap-panic-safe.rs | 101 --- src/test/run-pass-fulldeps/sort-unstable.rs | 83 -- .../vector-sort-panic-safe.rs | 181 ----- src/tools/cargo | 2 +- src/tools/tidy/src/deps.rs | 2 + 17 files changed, 680 insertions(+), 748 deletions(-) rename src/{test/run-pass-fulldeps/flt2dec.rs => libcore/tests/num/flt2dec/random.rs} (98%) rename src/{test/run-pass-fulldeps => libstd/tests}/env.rs (97%) delete mode 100644 src/test/run-pass-fulldeps/binary-heap-panic-safe.rs delete mode 100644 src/test/run-pass-fulldeps/sort-unstable.rs delete mode 100644 src/test/run-pass-fulldeps/vector-sort-panic-safe.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 646ddf1a7447..3252fda970b0 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -28,7 +28,7 @@ name = "alloc" version = "0.0.0" dependencies = [ "core 0.0.0", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "std_unicode 0.0.0", ] @@ -39,7 +39,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.0.0", ] @@ -81,7 +81,7 @@ name = "atty" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -93,8 +93,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -103,8 +103,8 @@ name = "backtrace-sys" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -131,16 +131,16 @@ name = "bootstrap" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -158,8 +158,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "build-manifest" version = "0.1.0" dependencies = [ - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -177,48 +177,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cargo" -version = "0.26.0" +version = "0.27.0" dependencies = [ "atty 0.2.8 (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", - "core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crates-io 0.15.0", + "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crates-io 0.16.0", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "git2-curl 0.8.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)", "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ignore 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -227,9 +227,9 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -239,25 +239,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cargotest" -version = "0.1.0" -dependencies = [ - "cargo 0.26.0", - "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -266,7 +250,7 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -279,7 +263,7 @@ name = "chrono" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -308,9 +292,9 @@ dependencies = [ "compiletest_rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -329,11 +313,11 @@ dependencies = [ "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.2 (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.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -349,11 +333,11 @@ dependencies = [ "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.2 (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.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -361,7 +345,7 @@ name = "cmake" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -377,14 +361,14 @@ name = "commoncrypto-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "compiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -393,16 +377,16 @@ name = "compiletest" version = "0.0.0" dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -414,11 +398,11 @@ dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "miow 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)", - "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -429,41 +413,39 @@ version = "0.1.0" [[package]] name = "core" version = "0.0.0" +dependencies = [ + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "core-foundation" -version = "0.4.6" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "core-foundation-sys" -version = "0.4.6" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crates-io" -version = "0.15.0" +version = "0.16.0" dependencies = [ "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crossbeam" version = "0.3.2" @@ -502,14 +484,13 @@ dependencies = [ [[package]] name = "crypto-hash" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -519,11 +500,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl-sys 0.4.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.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -532,10 +513,10 @@ name = "curl-sys" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -552,7 +533,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -574,9 +555,9 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -619,7 +600,7 @@ name = "enum_primitive" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -637,19 +618,19 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "env_logger" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -704,7 +685,7 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -721,7 +702,7 @@ name = "flate2" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -752,7 +733,7 @@ name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -782,26 +763,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "git2" -version = "0.6.11" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "git2-curl" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -811,29 +792,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "globset" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (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.41 (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.29.1" @@ -843,16 +815,11 @@ dependencies = [ "log 0.3.9 (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.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hex" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "hex" version = "0.3.1" @@ -895,18 +862,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ignore" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "globset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -931,7 +899,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "xz2 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -967,8 +935,8 @@ name = "jobserver" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -983,9 +951,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1003,10 +971,10 @@ version = "0.30.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.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1025,6 +993,11 @@ name = "lazycell" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lazycell" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.0.0" @@ -1034,21 +1007,21 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.36" +version = "0.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libgit2-sys" -version = "0.6.19" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (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.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1058,9 +1031,9 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1069,8 +1042,8 @@ name = "libz-sys" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1108,9 +1081,9 @@ name = "lzma-sys" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1126,7 +1099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1135,12 +1108,12 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1150,7 +1123,7 @@ name = "memchr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1158,7 +1131,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1171,8 +1144,8 @@ name = "miniz-sys" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1181,7 +1154,7 @@ 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.31 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.32 (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)", ] @@ -1191,7 +1164,7 @@ name = "miow" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1203,7 +1176,7 @@ dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "compiletest_rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1212,14 +1185,12 @@ version = "0.1.0" [[package]] name = "net2" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (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.36 (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)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1234,7 +1205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1245,68 +1216,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num" -version = "0.1.41" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-bigint" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (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.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-iter" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-rational" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.1.41" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1314,7 +1259,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1324,14 +1269,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl" -version = "0.9.23" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1341,11 +1286,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.24" +version = "0.9.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1401,8 +1346,8 @@ version = "0.2.9" 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.36 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1444,7 +1389,7 @@ dependencies = [ name = "profiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1514,11 +1459,22 @@ dependencies = [ [[package]] name = "rand" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1537,9 +1493,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1577,12 +1533,12 @@ dependencies = [ [[package]] name = "regex" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1597,6 +1553,14 @@ name = "regex-syntax" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "regex-syntax" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "remote-test-client" version = "0.1.0" @@ -1605,14 +1569,23 @@ version = "0.1.0" name = "remote-test-server" version = "0.1.0" +[[package]] +name = "remove_dir_all" +version = "0.3.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)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rls" version = "0.126.0" dependencies = [ - "cargo 0.26.0", + "cargo 0.27.0", "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.186 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1629,10 +1602,10 @@ dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustfmt-nightly 0.3.8", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1660,8 +1633,8 @@ 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.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1675,8 +1648,8 @@ version = "0.4.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)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1789,7 +1762,7 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.5" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1839,7 +1812,7 @@ name = "rustc_back" version = "0.0.0" dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "syntax 0.0.0", ] @@ -1893,7 +1866,7 @@ version = "0.0.0" dependencies = [ "ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "arena 0.0.0", - "env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -1927,7 +1900,7 @@ dependencies = [ "rustc_data_structures 0.0.0", "serialize 0.0.0", "syntax_pos 0.0.0", - "termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1937,7 +1910,7 @@ version = "0.0.0" dependencies = [ "graphviz 0.0.0", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", "serialize 0.0.0", @@ -1962,8 +1935,8 @@ version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "build_helper 0.1.0", - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", ] @@ -2100,15 +2073,15 @@ name = "rustc_trans" version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", - "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_allocator 0.0.0", "rustc_apfloat 0.0.0", "rustc_back 0.0.0", @@ -2123,7 +2096,7 @@ dependencies = [ "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", - "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2174,7 +2147,7 @@ name = "rustdoc" version = "0.0.0" dependencies = [ "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2199,14 +2172,14 @@ dependencies = [ "getopts 0.2.15 (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 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2223,7 +2196,7 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2232,7 +2205,7 @@ dependencies = [ [[package]] name = "scoped-tls" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2259,7 +2232,7 @@ version = "0.8.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)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2268,7 +2241,7 @@ version = "0.9.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)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2278,26 +2251,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.27" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.27" +version = "1.0.29" 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.19.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.19.0" +version = "0.20.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)", + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2305,18 +2279,18 @@ name = "serde_ignored" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2329,7 +2303,7 @@ 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)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2350,11 +2324,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "socket2" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2377,7 +2351,7 @@ dependencies = [ "panic_abort 0.0.0", "panic_unwind 0.0.0", "profiler_builtins 0.0.0", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_asan 0.0.0", "rustc_lsan 0.0.0", "rustc_msan 0.0.0", @@ -2410,7 +2384,7 @@ dependencies = [ [[package]] name = "syn" -version = "0.12.13" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2474,7 +2448,7 @@ name = "syntex_errors" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (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)", @@ -2496,7 +2470,7 @@ 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.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (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)", @@ -2511,17 +2485,18 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (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" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2539,10 +2514,10 @@ dependencies = [ [[package]] name = "termcolor" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2550,7 +2525,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2577,7 +2552,7 @@ 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.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2601,9 +2576,9 @@ dependencies = [ name = "tidy" version = "0.1.0" dependencies = [ - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2611,7 +2586,7 @@ name = "time" version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2629,7 +2604,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2640,10 +2615,15 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ucd-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -2707,7 +2687,7 @@ dependencies = [ [[package]] name = "url" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2720,8 +2700,8 @@ name = "url_serde" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2760,10 +2740,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "2.0.1" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2797,11 +2778,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "wincolor" -version = "0.1.4" +version = "0.1.6" 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)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2822,7 +2802,7 @@ name = "xattr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2855,7 +2835,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20d6fb2b5574726329c85cdba0df0347fddfec3cf9c8b588f9931708280f5643" -"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" +"checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" @@ -2864,14 +2844,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" "checksum compiletest_rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6c5aafb5d4a77c6b5fa384fe93c7a9a3561bd88c4b8b8e45187cf5e779b1badc" -"checksum core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8047f547cd6856d45b1cdd75ef8d2f21f3d0e4bf1dab0a0041b0ae9a5dda9c0e" -"checksum core-foundation-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "152195421a2e6497a8179195672e9d4ee8e45ed8c465b626f1606d27a08ebcd5" -"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" +"checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" +"checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "59796cc6cbbdc6bb319161349db0c3250ec73ec7fcb763a51065ec4e2e158552" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum crypto-hash 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34903878eec1694faf53cae8473a088df333181de421d4d3d48061d6559fe602" +"checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" "checksum curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b70fd6394677d3c0e239ff4be6f2b3176e171ffd1c23ffdc541e78dea2b8bb5e" "checksum curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e49c7125131f5afaded06944d6888b55cbdf8eba05dae73c954019b907961" "checksum derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "92f8b8e1d6c8a5f5ea0849a0e4c55941576115c62d3fc425e96918bbbeb3d3c2" @@ -2885,7 +2864,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" -"checksum env_logger 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f3cc21490995c841d68e00276eba02071ebb269ec24011d5728bd00eabd39e31" +"checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" @@ -2900,19 +2879,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" -"checksum git2 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5b4bb7cd2a44e6e5ee3a26ba6a9ca10d4ce2771cdc3839bbc54b47b7d1be84" -"checksum git2-curl 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "68676bc784bf0bef83278898929bf64a251e87c0340723d0b93fa096c9c5bf8e" +"checksum git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4813cd7ad02e53275e6e51aaaf21c30f9ef500b579ad7a54a92f6091a7ac296" +"checksum git2-curl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27245f4c3a65ab19fd1ab5b52659bd60ed0ce8d0d129202c4737044d1d21db29" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "464627f948c3190ae3d04b1bc6d7dca2f785bda0ac01278e6db129ad383dbeb6" -"checksum hamcrest 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf088f042a467089e9baa4972f57f9247e42a0cc549ba264c7a04fbb8ecb89d4" +"checksum globset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e96ab92362c06811385ae9a34d2698e8a1160745e0c78fbb434a44c8de3fabc" "checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc" -"checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc" "checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" -"checksum ignore 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb2f0238094bd1b41800fb6eb9b16fdd5e9832ed6053ed91409f0cd5bf28dcfd" +"checksum ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "245bea0ba52531a3739cb8ba99f8689eda13d7faf8c36b6a73ce4421aab42588" "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394" @@ -2925,8 +2902,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" -"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121" -"checksum libgit2-sys 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6eeae66e7b1c995de45cb4e65c5ab438a96a7b4077e448645d4048dc753ad357" +"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" +"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" +"checksum libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecbd6428006c321c29b6c8a895f0d90152f1cf4fd8faab69fc436a3d9594f63" "checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75" "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" @@ -2941,22 +2919,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d" -"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" +"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" "checksum nibble_vec 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "62e678237a4c70c5f2b917cefd7d080dfbf800421f06e8a59d4e28ef5130fd9e" "checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" -"checksum num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "bdc1494b5912f088f260b775799468d9b9209ac60885d8186a547a0476289e23" -"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c" -"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" -"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe" -"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" +"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +"checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" +"checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593" +"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +"checksum num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3c2bd9b9d21e48e956b763c9f37134dc62d9e95da6edb3f672cacb6caf3cd3" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" -"checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" +"checksum openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1636c9f1d78af9cbcc50e523bfff4a30274108aad5e86761afd4d31e4e184fa7" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "14ba54ac7d5a4eabd1d5f2c1fdeb7e7c14debfa669d94b983d01b465e767ba9e" +"checksum openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdc5c4a02e69ce65046f1763a0181107038e02176233acb0b3351d7cc588f9" "checksum os_pipe 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "998bfbb3042e715190fe2a41abfa047d7e8cb81374d2977d7f100eacd8619cb1" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412" @@ -2973,15 +2949,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" "checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4" "checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8" -"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" -"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a62bf8bb734ab90b7f234b681b01af396e5d39b028906c210dc04fa1d5e9e5b3" "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" +"checksum regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48d7391e7e90e06eaf3aefbe4652464153ecfec64806f3bf77ffc59638a63e77" +"checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" "checksum rls-analysis 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39461c31c9ec26c2f15821d6aaa349216bf71e24e69550d9f8eeded78dc435e1" "checksum rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56fb7b8e4850b988fbcf277fbdb1eff36879070d02fc1ca243b559273866973d" "checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510" @@ -2994,40 +2973,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0745fa445ff41c4b6699936cf35ce3ca49502377dd7b3929c829594772c3a7b" "checksum rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82efedabe30f393161e11214a9130edfa01ad476372d1c6f3fec1f8d30488c9d" "checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0" -"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" +"checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" -"checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016" -"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" +"checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4" +"checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" "checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" -"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" -"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" +"checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406" +"checksum serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8ab31f00ae5574bb643c196d5e302961c122da1c768604c6d16a35c5d551948a" +"checksum serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc848d073be32cd982380c06587ea1d433bc1a4c4a111de07ec2286a3ddade8" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" -"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb" +"checksum serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57781ed845b8e742fc2bf306aba8e3b408fe8c366b900e3769fbc39f49eb8b39" "checksum shared_child 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "099b38928dbe4a0a01fcd8c233183072f14a7d126a34bed05880869be66e14cc" "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" -"checksum socket2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf5d5aa364bf61a0d744a293da20381617b6445b89eb524800fab857c5aed2d8" +"checksum socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78e4c1cde1adbc6bc4c394da2e7727c916b9b7d0b53d6984c890c65c1f4e6437" "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 syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "517f6da31bc53bf080b9a77b29fbd0ff8da2f5a2ebd24c73c2238274a94ac7cb" +"checksum syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5bc2d6ff27891209efa5f63e9de78648d7801f085e4653701a692ce938d6fd" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e52bffe6202cfb67587784cf23e0ec5bf26d331eef4922a16d5c42e12aa1e9b" "checksum syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "955ef4b16af4c468e4680d1497f873ff288f557d338180649e18f915af5e15ac" "checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde" "checksum tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1605d3388ceb50252952ffebab4b5dc43017ead7e4481b175961c283bb951195" -"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" +"checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" -"checksum termcolor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9065bced9c3e43453aa3d56f1e98590b8455b341d2fa191a1090c0dd0b242c75" +"checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" @@ -3037,6 +3016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" "checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8" +"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" "checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" @@ -3045,7 +3025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" +"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" "checksum userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d28ea36bbd9192d75bd9fa9b39f96ddb986eaee824adae5d53b6e51919b2f3" "checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" @@ -3053,13 +3033,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b6d201f4f8998a837196b6de9c73e35af14c992cbb92c4ab641d2c2dce52de" +"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a39ee4464208f6430992ff20154216ab2357772ac871d994c51628d60e58b8b0" +"checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" "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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df591c3504d014dd791d998123ed00a476c7e26dc6b2e873cb55c6ac9e59fa" diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 22656e5a9da4..586216b9a588 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -775,7 +775,9 @@ impl<'a> Builder<'a> { // be resolved because MinGW has the import library. The downside is we // don't get newer functions from Windows, but we don't use any of them // anyway. - cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1"); + if mode != Mode::Tool { + cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1"); + } if self.is_very_verbose() { cargo.arg("-v"); diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml index 0a265ee1376a..3bf919b0c001 100644 --- a/src/liballoc/Cargo.toml +++ b/src/liballoc/Cargo.toml @@ -12,7 +12,7 @@ core = { path = "../libcore" } std_unicode = { path = "../libstd_unicode" } [dev-dependencies] -rand = "0.3" +rand = "0.4" [[test]] name = "collectionstests" diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 06d585f8ea82..5c979d82e55d 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -8,9 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::panic; +use std::cmp; use std::collections::BinaryHeap; use std::collections::binary_heap::{Drain, PeekMut}; +use std::panic::{self, AssertUnwindSafe}; +use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; + +use rand::{thread_rng, Rng}; #[test] fn test_iterator() { @@ -300,3 +304,80 @@ fn assert_covariance() { d } } + +// old binaryheap failed this test +// +// Integrity means that all elements are present after a comparison panics, +// even if the order may not be correct. +// +// Destructors must be called exactly once per element. +#[test] +fn panic_safe() { + static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; + + #[derive(Eq, PartialEq, Ord, Clone, Debug)] + struct PanicOrd(T, bool); + + impl Drop for PanicOrd { + fn drop(&mut self) { + // update global drop count + DROP_COUNTER.fetch_add(1, Ordering::SeqCst); + } + } + + impl PartialOrd for PanicOrd { + fn partial_cmp(&self, other: &Self) -> Option { + if self.1 || other.1 { + panic!("Panicking comparison"); + } + self.0.partial_cmp(&other.0) + } + } + let mut rng = thread_rng(); + const DATASZ: usize = 32; + const NTEST: usize = 10; + + // don't use 0 in the data -- we want to catch the zeroed-out case. + let data = (1..DATASZ + 1).collect::>(); + + // since it's a fuzzy test, run several tries. + for _ in 0..NTEST { + for i in 1..DATASZ + 1 { + DROP_COUNTER.store(0, Ordering::SeqCst); + + let mut panic_ords: Vec<_> = data.iter() + .filter(|&&x| x != i) + .map(|&x| PanicOrd(x, false)) + .collect(); + let panic_item = PanicOrd(i, true); + + // heapify the sane items + rng.shuffle(&mut panic_ords); + let mut heap = BinaryHeap::from(panic_ords); + let inner_data; + + { + // push the panicking item to the heap and catch the panic + let thread_result = { + let mut heap_ref = AssertUnwindSafe(&mut heap); + panic::catch_unwind(move || { + heap_ref.push(panic_item); + }) + }; + assert!(thread_result.is_err()); + + // Assert no elements were dropped + let drops = DROP_COUNTER.load(Ordering::SeqCst); + assert!(drops == 0, "Must not drop items. drops={}", drops); + inner_data = heap.clone().into_vec(); + drop(heap); + } + let drops = DROP_COUNTER.load(Ordering::SeqCst); + assert_eq!(drops, DATASZ); + + let mut data_sorted = inner_data.into_iter().map(|p| p.0).collect::>(); + data_sorted.sort(); + assert_eq!(data_sorted, data); + } + } +} diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 1a9d26fd1a29..d9e9d91cea88 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -8,9 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::cell::Cell; use std::cmp::Ordering::{Equal, Greater, Less}; +use std::cmp::Ordering; use std::mem; +use std::panic; use std::rc::Rc; +use std::sync::atomic::Ordering::Relaxed; +use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize}; +use std::thread; use rand::{Rng, thread_rng}; @@ -1341,3 +1347,162 @@ fn test_copy_from_slice_dst_shorter() { let mut dst = [0; 3]; dst.copy_from_slice(&src); } + +const MAX_LEN: usize = 80; + +static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [ + // FIXME #5244: AtomicUsize is not Copy. + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), + AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), +]; + +static VERSIONS: AtomicUsize = ATOMIC_USIZE_INIT; + +#[derive(Clone, Eq)] +struct DropCounter { + x: u32, + id: usize, + version: Cell, +} + +impl PartialEq for DropCounter { + fn eq(&self, other: &Self) -> bool { + self.partial_cmp(other) == Some(Ordering::Equal) + } +} + +impl PartialOrd for DropCounter { + fn partial_cmp(&self, other: &Self) -> Option { + self.version.set(self.version.get() + 1); + other.version.set(other.version.get() + 1); + VERSIONS.fetch_add(2, Relaxed); + self.x.partial_cmp(&other.x) + } +} + +impl Ord for DropCounter { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).unwrap() + } +} + +impl Drop for DropCounter { + fn drop(&mut self) { + DROP_COUNTS[self.id].fetch_add(1, Relaxed); + VERSIONS.fetch_sub(self.version.get(), Relaxed); + } +} + +macro_rules! test { + ($input:ident, $func:ident) => { + let len = $input.len(); + + // Work out the total number of comparisons required to sort + // this array... + let mut count = 0usize; + $input.to_owned().$func(|a, b| { count += 1; a.cmp(b) }); + + // ... and then panic on each and every single one. + for panic_countdown in 0..count { + // Refresh the counters. + VERSIONS.store(0, Relaxed); + for i in 0..len { + DROP_COUNTS[i].store(0, Relaxed); + } + + let v = $input.to_owned(); + let _ = thread::spawn(move || { + let mut v = v; + let mut panic_countdown = panic_countdown; + v.$func(|a, b| { + if panic_countdown == 0 { + SILENCE_PANIC.with(|s| s.set(true)); + panic!(); + } + panic_countdown -= 1; + a.cmp(b) + }) + }).join(); + + // Check that the number of things dropped is exactly + // what we expect (i.e. the contents of `v`). + for (i, c) in DROP_COUNTS.iter().enumerate().take(len) { + let count = c.load(Relaxed); + assert!(count == 1, + "found drop count == {} for i == {}, len == {}", + count, i, len); + } + + // Check that the most recent versions of values were dropped. + assert_eq!(VERSIONS.load(Relaxed), 0); + } + } +} + +thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); + +#[test] +#[cfg_attr(target_os = "emscripten", ignore)] // no threads +fn panic_safe() { + let prev = panic::take_hook(); + panic::set_hook(Box::new(move |info| { + if !SILENCE_PANIC.with(|s| s.get()) { + prev(info); + } + })); + + let mut rng = thread_rng(); + + for len in (1..20).chain(70..MAX_LEN) { + for &modulus in &[5, 20, 50] { + for &has_runs in &[false, true] { + let mut input = (0..len) + .map(|id| { + DropCounter { + x: rng.next_u32() % modulus, + id: id, + version: Cell::new(0), + } + }) + .collect::>(); + + if has_runs { + for c in &mut input { + c.x = c.id as u32; + } + + for _ in 0..5 { + let a = rng.gen::() % len; + let b = rng.gen::() % len; + if a < b { + input[a..b].reverse(); + } else { + input.swap(a, b); + } + } + } + + test!(input, sort_by); + test!(input, sort_unstable_by); + } + } + } +} diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml index 5af63aa970f2..24529f7a9d8d 100644 --- a/src/libcore/Cargo.toml +++ b/src/libcore/Cargo.toml @@ -16,3 +16,6 @@ path = "../libcore/tests/lib.rs" [[bench]] name = "corebenches" path = "../libcore/benches/lib.rs" + +[dev-dependencies] +rand = "0.4" diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index a9c5683e0ef7..d08d6b3215d8 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -50,6 +50,7 @@ extern crate core; extern crate test; +extern crate rand; mod any; mod array; diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs index ef0178815f98..04567e25e25b 100644 --- a/src/libcore/tests/num/flt2dec/mod.rs +++ b/src/libcore/tests/num/flt2dec/mod.rs @@ -23,6 +23,7 @@ mod strategy { mod dragon; mod grisu; } +mod random; pub fn decode_finite(v: T) -> Decoded { match decode(v).1 { diff --git a/src/test/run-pass-fulldeps/flt2dec.rs b/src/libcore/tests/num/flt2dec/random.rs similarity index 98% rename from src/test/run-pass-fulldeps/flt2dec.rs rename to src/libcore/tests/num/flt2dec/random.rs index 3db0644d1ef3..315ac4d7d99f 100644 --- a/src/test/run-pass-fulldeps/flt2dec.rs +++ b/src/libcore/tests/num/flt2dec/random.rs @@ -8,12 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:--test - -#![feature(rustc_private, flt2dec)] - -extern crate core; -extern crate rand; +#![cfg(not(target_arch = "wasm32"))] use std::i16; use std::mem; @@ -24,8 +19,9 @@ use core::num::flt2dec::strategy::grisu::format_exact_opt; use core::num::flt2dec::strategy::grisu::format_shortest_opt; use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded}; -use rand::{Rand, XorShiftRng}; +use rand::{self, Rand, XorShiftRng}; use rand::distributions::{IndependentSample, Range}; + pub fn decode_finite(v: T) -> Decoded { match decode(v).1 { FullDecoded::Finite(decoded) => decoded, @@ -161,3 +157,4 @@ fn exact_f64_random_equivalence_test() { |d, buf| fallback(d, buf, i16::MIN), k, 1_000); } } + diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 13740b958025..53fdfa068274 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -10,7 +10,6 @@ use core::result::Result::{Ok, Err}; - #[test] fn test_position() { let b = [1, 2, 3, 5, 5]; @@ -481,3 +480,73 @@ fn test_rotate_right() { assert_eq!(a[(i + 42) % N], i); } } + +#[test] +#[cfg(not(target_arch = "wasm32"))] +fn sort_unstable() { + use core::cmp::Ordering::{Equal, Greater, Less}; + use core::slice::heapsort; + use rand::{Rng, XorShiftRng}; + + let mut v = [0; 600]; + let mut tmp = [0; 600]; + let mut rng = XorShiftRng::new_unseeded(); + + for len in (2..25).chain(500..510) { + let v = &mut v[0..len]; + let tmp = &mut tmp[0..len]; + + for &modulus in &[5, 10, 100, 1000] { + for _ in 0..100 { + for i in 0..len { + v[i] = rng.gen::() % modulus; + } + + // Sort in default order. + tmp.copy_from_slice(v); + tmp.sort_unstable(); + assert!(tmp.windows(2).all(|w| w[0] <= w[1])); + + // Sort in ascending order. + tmp.copy_from_slice(v); + tmp.sort_unstable_by(|a, b| a.cmp(b)); + assert!(tmp.windows(2).all(|w| w[0] <= w[1])); + + // Sort in descending order. + tmp.copy_from_slice(v); + tmp.sort_unstable_by(|a, b| b.cmp(a)); + assert!(tmp.windows(2).all(|w| w[0] >= w[1])); + + // Test heapsort using `<` operator. + tmp.copy_from_slice(v); + heapsort(tmp, |a, b| a < b); + assert!(tmp.windows(2).all(|w| w[0] <= w[1])); + + // Test heapsort using `>` operator. + tmp.copy_from_slice(v); + heapsort(tmp, |a, b| a > b); + assert!(tmp.windows(2).all(|w| w[0] >= w[1])); + } + } + } + + // Sort using a completely random comparison function. + // This will reorder the elements *somehow*, but won't panic. + for i in 0..v.len() { + v[i] = i as i32; + } + v.sort_unstable_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap()); + v.sort_unstable(); + for i in 0..v.len() { + assert_eq!(v[i], i as i32); + } + + // Should not panic. + [0i32; 0].sort_unstable(); + [(); 10].sort_unstable(); + [(); 100].sort_unstable(); + + let mut v = [0xDEADBEEFu64]; + v.sort_unstable(); + assert!(v == [0xDEADBEEF]); +} diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index c1fe4a89d6ac..120175988533 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -26,7 +26,7 @@ std_unicode = { path = "../libstd_unicode" } unwind = { path = "../libunwind" } [dev-dependencies] -rand = "0.3" +rand = "0.4" [target.x86_64-apple-darwin.dependencies] rustc_asan = { path = "../librustc_asan" } diff --git a/src/test/run-pass-fulldeps/env.rs b/src/libstd/tests/env.rs similarity index 97% rename from src/test/run-pass-fulldeps/env.rs rename to src/libstd/tests/env.rs index cf2ea732ee1b..d4376523691a 100644 --- a/src/test/run-pass-fulldeps/env.rs +++ b/src/libstd/tests/env.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --test - -#![feature(rustc_private, std_panic)] - extern crate rand; use std::env::*; diff --git a/src/test/run-pass-fulldeps/binary-heap-panic-safe.rs b/src/test/run-pass-fulldeps/binary-heap-panic-safe.rs deleted file mode 100644 index 6139a7d3201c..000000000000 --- a/src/test/run-pass-fulldeps/binary-heap-panic-safe.rs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2015 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. - -#![feature(rustc_private, std_panic)] - -extern crate rand; - -use rand::{thread_rng, Rng}; -use std::panic::{self, AssertUnwindSafe}; - -use std::collections::BinaryHeap; -use std::cmp; -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; - -static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT; - -// old binaryheap failed this test -// -// Integrity means that all elements are present after a comparison panics, -// even if the order may not be correct. -// -// Destructors must be called exactly once per element. -fn test_integrity() { - #[derive(Eq, PartialEq, Ord, Clone, Debug)] - struct PanicOrd(T, bool); - - impl Drop for PanicOrd { - fn drop(&mut self) { - // update global drop count - DROP_COUNTER.fetch_add(1, Ordering::SeqCst); - } - } - - impl PartialOrd for PanicOrd { - fn partial_cmp(&self, other: &Self) -> Option { - if self.1 || other.1 { - panic!("Panicking comparison"); - } - self.0.partial_cmp(&other.0) - } - } - let mut rng = thread_rng(); - const DATASZ: usize = 32; - const NTEST: usize = 10; - - // don't use 0 in the data -- we want to catch the zeroed-out case. - let data = (1..DATASZ + 1).collect::>(); - - // since it's a fuzzy test, run several tries. - for _ in 0..NTEST { - for i in 1..DATASZ + 1 { - DROP_COUNTER.store(0, Ordering::SeqCst); - - let mut panic_ords: Vec<_> = data.iter() - .filter(|&&x| x != i) - .map(|&x| PanicOrd(x, false)) - .collect(); - let panic_item = PanicOrd(i, true); - - // heapify the sane items - rng.shuffle(&mut panic_ords); - let mut heap = BinaryHeap::from(panic_ords); - let inner_data; - - { - // push the panicking item to the heap and catch the panic - let thread_result = { - let mut heap_ref = AssertUnwindSafe(&mut heap); - panic::catch_unwind(move || { - heap_ref.push(panic_item); - }) - }; - assert!(thread_result.is_err()); - - // Assert no elements were dropped - let drops = DROP_COUNTER.load(Ordering::SeqCst); - assert!(drops == 0, "Must not drop items. drops={}", drops); - inner_data = heap.clone().into_vec(); - drop(heap); - } - let drops = DROP_COUNTER.load(Ordering::SeqCst); - assert_eq!(drops, DATASZ); - - let mut data_sorted = inner_data.into_iter().map(|p| p.0).collect::>(); - data_sorted.sort(); - assert_eq!(data_sorted, data); - } - } -} - -fn main() { - test_integrity(); -} - diff --git a/src/test/run-pass-fulldeps/sort-unstable.rs b/src/test/run-pass-fulldeps/sort-unstable.rs deleted file mode 100644 index af8a691aa3ec..000000000000 --- a/src/test/run-pass-fulldeps/sort-unstable.rs +++ /dev/null @@ -1,83 +0,0 @@ -// 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. - -#![feature(rustc_private, sort_internals)] - -extern crate core; -extern crate rand; - -use std::cmp::Ordering::{Equal, Greater, Less}; -use core::slice::heapsort; - -use rand::{Rng, XorShiftRng}; - -fn main() { - let mut v = [0; 600]; - let mut tmp = [0; 600]; - let mut rng = XorShiftRng::new_unseeded(); - - for len in (2..25).chain(500..510) { - let v = &mut v[0..len]; - let tmp = &mut tmp[0..len]; - - for &modulus in &[5, 10, 100, 1000] { - for _ in 0..100 { - for i in 0..len { - v[i] = rng.gen::() % modulus; - } - - // Sort in default order. - tmp.copy_from_slice(v); - tmp.sort_unstable(); - assert!(tmp.windows(2).all(|w| w[0] <= w[1])); - - // Sort in ascending order. - tmp.copy_from_slice(v); - tmp.sort_unstable_by(|a, b| a.cmp(b)); - assert!(tmp.windows(2).all(|w| w[0] <= w[1])); - - // Sort in descending order. - tmp.copy_from_slice(v); - tmp.sort_unstable_by(|a, b| b.cmp(a)); - assert!(tmp.windows(2).all(|w| w[0] >= w[1])); - - // Test heapsort using `<` operator. - tmp.copy_from_slice(v); - heapsort(tmp, |a, b| a < b); - assert!(tmp.windows(2).all(|w| w[0] <= w[1])); - - // Test heapsort using `>` operator. - tmp.copy_from_slice(v); - heapsort(tmp, |a, b| a > b); - assert!(tmp.windows(2).all(|w| w[0] >= w[1])); - } - } - } - - // Sort using a completely random comparison function. - // This will reorder the elements *somehow*, but won't panic. - for i in 0..v.len() { - v[i] = i as i32; - } - v.sort_unstable_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap()); - v.sort_unstable(); - for i in 0..v.len() { - assert_eq!(v[i], i as i32); - } - - // Should not panic. - [0i32; 0].sort_unstable(); - [(); 10].sort_unstable(); - [(); 100].sort_unstable(); - - let mut v = [0xDEADBEEFu64]; - v.sort_unstable(); - assert!(v == [0xDEADBEEF]); -} diff --git a/src/test/run-pass-fulldeps/vector-sort-panic-safe.rs b/src/test/run-pass-fulldeps/vector-sort-panic-safe.rs deleted file mode 100644 index adc72aa0ea23..000000000000 --- a/src/test/run-pass-fulldeps/vector-sort-panic-safe.rs +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2013 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-emscripten no threads support - -#![feature(rustc_private)] -#![feature(sort_unstable)] - -extern crate rand; - -use rand::{thread_rng, Rng}; -use std::cell::Cell; -use std::cmp::Ordering; -use std::panic; -use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize}; -use std::sync::atomic::Ordering::Relaxed; -use std::thread; - -const MAX_LEN: usize = 80; - -static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [ - // FIXME #5244: AtomicUsize is not Copy. - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), - AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), -]; - -static VERSIONS: AtomicUsize = ATOMIC_USIZE_INIT; - -#[derive(Clone, Eq)] -struct DropCounter { - x: u32, - id: usize, - version: Cell, -} - -impl PartialEq for DropCounter { - fn eq(&self, other: &Self) -> bool { - self.partial_cmp(other) == Some(Ordering::Equal) - } -} - -impl PartialOrd for DropCounter { - fn partial_cmp(&self, other: &Self) -> Option { - self.version.set(self.version.get() + 1); - other.version.set(other.version.get() + 1); - VERSIONS.fetch_add(2, Relaxed); - self.x.partial_cmp(&other.x) - } -} - -impl Ord for DropCounter { - fn cmp(&self, other: &Self) -> Ordering { - self.partial_cmp(other).unwrap() - } -} - -impl Drop for DropCounter { - fn drop(&mut self) { - DROP_COUNTS[self.id].fetch_add(1, Relaxed); - VERSIONS.fetch_sub(self.version.get(), Relaxed); - } -} - -macro_rules! test { - ($input:ident, $func:ident) => { - let len = $input.len(); - - // Work out the total number of comparisons required to sort - // this array... - let mut count = 0usize; - $input.to_owned().$func(|a, b| { count += 1; a.cmp(b) }); - - // ... and then panic on each and every single one. - for panic_countdown in 0..count { - // Refresh the counters. - VERSIONS.store(0, Relaxed); - for i in 0..len { - DROP_COUNTS[i].store(0, Relaxed); - } - - let v = $input.to_owned(); - let _ = thread::spawn(move || { - let mut v = v; - let mut panic_countdown = panic_countdown; - v.$func(|a, b| { - if panic_countdown == 0 { - SILENCE_PANIC.with(|s| s.set(true)); - panic!(); - } - panic_countdown -= 1; - a.cmp(b) - }) - }).join(); - - // Check that the number of things dropped is exactly - // what we expect (i.e. the contents of `v`). - for (i, c) in DROP_COUNTS.iter().enumerate().take(len) { - let count = c.load(Relaxed); - assert!(count == 1, - "found drop count == {} for i == {}, len == {}", - count, i, len); - } - - // Check that the most recent versions of values were dropped. - assert_eq!(VERSIONS.load(Relaxed), 0); - } - } -} - -thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); - -fn main() { - let prev = panic::take_hook(); - panic::set_hook(Box::new(move |info| { - if !SILENCE_PANIC.with(|s| s.get()) { - prev(info); - } - })); - - let mut rng = thread_rng(); - - for len in (1..20).chain(70..MAX_LEN) { - for &modulus in &[5, 20, 50] { - for &has_runs in &[false, true] { - let mut input = (0..len) - .map(|id| { - DropCounter { - x: rng.next_u32() % modulus, - id: id, - version: Cell::new(0), - } - }) - .collect::>(); - - if has_runs { - for c in &mut input { - c.x = c.id as u32; - } - - for _ in 0..5 { - let a = rng.gen::() % len; - let b = rng.gen::() % len; - if a < b { - input[a..b].reverse(); - } else { - input.swap(a, b); - } - } - } - - test!(input, sort_by); - test!(input, sort_unstable_by); - } - } - } -} diff --git a/src/tools/cargo b/src/tools/cargo index 1d6dfea44f97..5f83bb4044f3 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 1d6dfea44f97199d5d5c177c7dadcde393eaff9a +Subproject commit 5f83bb4044f32b60d06717c609610f67411fc671 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 72414c2a53ef..22c6af28ceae 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -91,6 +91,7 @@ static WHITELIST: &'static [Crate] = &[ Crate("redox_termios"), Crate("regex"), Crate("regex-syntax"), + Crate("remove_dir_all"), Crate("rustc-demangle"), Crate("smallvec"), Crate("stable_deref_trait"), @@ -99,6 +100,7 @@ static WHITELIST: &'static [Crate] = &[ Crate("terminon"), Crate("termion"), Crate("thread_local"), + Crate("ucd-util"), Crate("unicode-width"), Crate("unreachable"), Crate("utf8-ranges"), From 9a3128ec1d603dfa87de5db8eccff08d6dd62f67 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 11 Mar 2018 13:15:46 -0700 Subject: [PATCH 108/830] test: Forcibly remove MAKEFLAGS in compiletest When executing run-make tests we run a risk of leaking the `MAKEFLAGS` environment variable if `./x.py` itself was called from `make` (aka `make check -j3` as the OSX bots do). We may then leak accidentally fds into the child process and trick it into thinking it's got a jobserver! Hopefully addresses [this] spurious failure [this]: https://github.com/rust-lang/rust/pull/48295#issuecomment-372134717 --- src/tools/compiletest/src/runtest.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index d3f571dd8aeb..6619838cce07 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2412,7 +2412,14 @@ impl<'test> TestCx<'test> { .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path)) .env("LLVM_COMPONENTS", &self.config.llvm_components) - .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags); + .env("LLVM_CXXFLAGS", &self.config.llvm_cxxflags) + + // We for sure don't want these tests to run in parallel, so make + // sure they don't have access to these vars if we we run via `make` + // at the top level + .env_remove("MAKEFLAGS") + .env_remove("MFLAGS") + .env_remove("CARGO_MAKEFLAGS"); if let Some(ref linker) = self.config.linker { cmd.env("RUSTC_LINKER", linker); From e63b1a0e368e2f7d3bf5eadd1262dc530a38394b Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 11 Mar 2018 17:17:18 -0400 Subject: [PATCH 109/830] Remove "and may change between Rust releases" --- src/libstd/io/stdio.rs | 6 +++--- src/libstd/net/addr.rs | 6 +++--- src/libstd/net/ip.rs | 6 +++--- src/libstd/time.rs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 4565b7fa0d6f..9a4cde7e1628 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -32,7 +32,7 @@ thread_local! { /// the `std::io::stdio::stdin_raw` function. /// /// The size of a StdinRaw struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. struct StdinRaw(stdio::Stdin); /// A handle to a raw instance of the standard output stream of this process. @@ -41,7 +41,7 @@ struct StdinRaw(stdio::Stdin); /// the `std::io::stdio::stdout_raw` function. /// /// The size of a StdoutRaw struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. struct StdoutRaw(stdio::Stdout); /// A handle to a raw instance of the standard output stream of this process. @@ -50,7 +50,7 @@ struct StdoutRaw(stdio::Stdout); /// the `std::io::stdio::stderr_raw` function. /// /// The size of a StderrRaw struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. struct StderrRaw(stdio::Stderr); /// Constructs a new raw handle to the standard input of this process. diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 75b050638392..f985c1f2bc8c 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -29,7 +29,7 @@ use slice; /// [`SocketAddrV6`]'s respective documentation for more details. /// /// The size of a SocketAddr instance may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IP address]: ../../std/net/enum.IpAddr.html /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html @@ -65,7 +65,7 @@ pub enum SocketAddr { /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// /// The size of a SocketAddrV4 struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html @@ -95,7 +95,7 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in } /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// /// The size of a SocketAddrV6 struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 36a34e147d55..67b9e7a2f9d6 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -27,7 +27,7 @@ use sys_common::{AsInner, FromInner}; /// respective documentation for more details. /// /// The size of an IpAddr instance may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html /// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html @@ -65,7 +65,7 @@ pub enum IpAddr { /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// /// The size of an Ipv4Addr struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html @@ -100,7 +100,7 @@ pub struct Ipv4Addr { /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// /// The size of an Ipv6Addr struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 054450a51862..4e08301fe05b 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -50,7 +50,7 @@ pub use core::time::Duration; /// instants). /// /// The size of an Instant struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// Example: /// @@ -92,7 +92,7 @@ pub struct Instant(time::Instant); /// or perhaps some other string representation. /// /// The size of a SystemTime struct may vary depending on the target operating -/// system, and may change between Rust releases. +/// system. /// /// [`Instant`]: ../../std/time/struct.Instant.html /// [`Result`]: ../../std/result/enum.Result.html From 8654738260e8490f678fcfb07e6abaed337a0926 Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Mon, 12 Mar 2018 01:04:51 -0400 Subject: [PATCH 110/830] include AsciiExt in tests --- src/libcore/tests/ascii.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs index dbed5920519b..4d43067ad2cf 100644 --- a/src/libcore/tests/ascii.rs +++ b/src/libcore/tests/ascii.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use char::from_u32; +use core::char::from_u32; +use std::ascii::AsciiExt; #[test] fn test_is_ascii() { From 1a16271d1cc64e89f6c0acc7803b9d6fa25bf131 Mon Sep 17 00:00:00 2001 From: 1011X <1011XXXXX@gmail.com> Date: Mon, 12 Mar 2018 03:29:06 -0400 Subject: [PATCH 111/830] added ascii_ctypes feature to libcore tests module --- src/libcore/tests/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 971991dce3d1..e9d9e4d5c5d0 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -10,6 +10,7 @@ #![deny(warnings)] +#![feature(ascii_ctype)] #![feature(box_syntax)] #![feature(core_float)] #![feature(core_private_bignum)] From 37e897f4c4cc47b40d672255406b0917cbeda277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 3 Mar 2018 06:26:48 +0100 Subject: [PATCH 112/830] Require the metadata loader to be thread-safe --- src/librustc_metadata/cstore.rs | 4 ++-- src/librustc_trans/lib.rs | 2 +- src/librustc_trans_utils/trans_crate.rs | 6 +++--- src/test/run-make/hotplug_codegen_backend/the_backend.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 202efb9276a8..22c80e8db3ef 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -93,11 +93,11 @@ pub struct CStore { metas: RefCell>>>, /// Map from NodeId's of local extern crate statements to crate numbers extern_mod_crate_map: RefCell>, - pub metadata_loader: Box, + pub metadata_loader: Box, } impl CStore { - pub fn new(metadata_loader: Box) -> CStore { + pub fn new(metadata_loader: Box) -> CStore { CStore { metas: RefCell::new(IndexVec::new()), extern_mod_crate_map: RefCell::new(FxHashMap()), diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 39eb38658fee..29187c6c0a51 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -200,7 +200,7 @@ impl TransCrate for LlvmTransCrate { target_features(sess) } - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { box metadata::LlvmMetadataLoader } diff --git a/src/librustc_trans_utils/trans_crate.rs b/src/librustc_trans_utils/trans_crate.rs index 0d4811c4b025..5cf9819288b5 100644 --- a/src/librustc_trans_utils/trans_crate.rs +++ b/src/librustc_trans_utils/trans_crate.rs @@ -58,7 +58,7 @@ pub trait TransCrate { fn print_version(&self) {} fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] } - fn metadata_loader(&self) -> Box; + fn metadata_loader(&self) -> Box; fn provide(&self, _providers: &mut Providers); fn provide_extern(&self, _providers: &mut Providers); fn trans_crate<'a, 'tcx>( @@ -84,7 +84,7 @@ pub trait TransCrate { pub struct DummyTransCrate; impl TransCrate for DummyTransCrate { - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { box DummyMetadataLoader(()) } @@ -195,7 +195,7 @@ impl TransCrate for MetadataOnlyTransCrate { } } - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { box NoLlvmMetadataLoader } diff --git a/src/test/run-make/hotplug_codegen_backend/the_backend.rs b/src/test/run-make/hotplug_codegen_backend/the_backend.rs index 9e87268e6999..e266b0f5e834 100644 --- a/src/test/run-make/hotplug_codegen_backend/the_backend.rs +++ b/src/test/run-make/hotplug_codegen_backend/the_backend.rs @@ -28,7 +28,7 @@ use rustc_trans_utils::trans_crate::{TransCrate, MetadataOnlyTransCrate}; struct TheBackend(Box); impl TransCrate for TheBackend { - fn metadata_loader(&self) -> Box { + fn metadata_loader(&self) -> Box { self.0.metadata_loader() } From 4edb539159f26c366d6b0606a20e66fe727b78ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Feb 2018 10:52:26 +0100 Subject: [PATCH 113/830] Make CrateMetadata thread-safe --- src/librustc_metadata/creader.rs | 29 +++++++++++++++------------- src/librustc_metadata/cstore.rs | 13 ++++++------- src/librustc_metadata/cstore_impl.rs | 24 ++++++++++++++++------- src/librustc_metadata/decoder.rs | 21 +++++++++++++++----- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 789ecd0f6136..b2f014b930d6 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -14,7 +14,7 @@ use cstore::{self, CStore, CrateSource, MetadataBlob}; use locator::{self, CratePaths}; use native_libs::relevant_lib; use schema::CrateRoot; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX}; use rustc::hir::svh::Svh; @@ -30,7 +30,6 @@ use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; -use std::cell::{RefCell, Cell}; use std::ops::Deref; use std::path::PathBuf; use std::{cmp, fs}; @@ -63,7 +62,7 @@ fn dump_crates(cstore: &CStore) { info!(" name: {}", data.name()); info!(" cnum: {}", data.cnum); info!(" hash: {}", data.hash()); - info!(" reqd: {:?}", data.dep_kind.get()); + info!(" reqd: {:?}", *data.dep_kind.lock()); let CrateSource { dylib, rlib, rmeta } = data.source.clone(); dylib.map(|dl| info!(" dylib: {}", dl.0.display())); rlib.map(|rl| info!(" rlib: {}", rl.0.display())); @@ -233,7 +232,7 @@ impl<'a> CrateLoader<'a> { let mut cmeta = cstore::CrateMetadata { name, - extern_crate: Cell::new(None), + extern_crate: Lock::new(None), def_path_table: Lrc::new(def_path_table), trait_impls, proc_macros: crate_root.macro_derive_registrar.map(|_| { @@ -241,11 +240,11 @@ impl<'a> CrateLoader<'a> { }), root: crate_root, blob: metadata, - cnum_map: RefCell::new(cnum_map), + cnum_map: Lock::new(cnum_map), cnum, - codemap_import_info: RefCell::new(vec![]), - attribute_cache: RefCell::new([Vec::new(), Vec::new()]), - dep_kind: Cell::new(dep_kind), + codemap_import_info: RwLock::new(vec![]), + attribute_cache: Lock::new([Vec::new(), Vec::new()]), + dep_kind: Lock::new(dep_kind), source: cstore::CrateSource { dylib, rlib, @@ -335,7 +334,9 @@ impl<'a> CrateLoader<'a> { if data.root.macro_derive_registrar.is_some() { dep_kind = DepKind::UnexportedMacrosOnly; } - data.dep_kind.set(cmp::max(data.dep_kind.get(), dep_kind)); + data.dep_kind.with_lock(|data_dep_kind| { + *data_dep_kind = cmp::max(*data_dep_kind, dep_kind); + }); (cnum, data) } LoadResult::Loaded(library) => { @@ -379,14 +380,14 @@ impl<'a> CrateLoader<'a> { if !visited.insert((cnum, extern_crate.direct)) { return } let cmeta = self.cstore.get_crate_data(cnum); - let old_extern_crate = cmeta.extern_crate.get(); + let mut old_extern_crate = cmeta.extern_crate.borrow_mut(); // Prefer: // - something over nothing (tuple.0); // - direct extern crate to indirect (tuple.1); // - shorter paths to longer (tuple.2). let new_rank = (true, extern_crate.direct, !extern_crate.path_len); - let old_rank = match old_extern_crate { + let old_rank = match *old_extern_crate { None => (false, false, !0), Some(ref c) => (true, c.direct, !c.path_len), }; @@ -395,7 +396,9 @@ impl<'a> CrateLoader<'a> { return; // no change needed } - cmeta.extern_crate.set(Some(extern_crate)); + *old_extern_crate = Some(extern_crate); + drop(old_extern_crate); + // Propagate the extern crate info to dependencies. extern_crate.direct = false; for &dep_cnum in cmeta.cnum_map.borrow().iter() { @@ -646,7 +649,7 @@ impl<'a> CrateLoader<'a> { // #![panic_runtime] crate. self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime(sess)); - runtime_found = runtime_found || data.dep_kind.get() == DepKind::Explicit; + runtime_found = runtime_found || *data.dep_kind.lock() == DepKind::Explicit; } }); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 22c80e8db3ef..19f43c180de3 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -22,8 +22,7 @@ use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap}; -use std::cell::{RefCell, Cell}; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use syntax::{ast, attr}; use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; @@ -62,13 +61,13 @@ pub struct CrateMetadata { /// Information about the extern crate that caused this crate to /// be loaded. If this is `None`, then the crate was injected /// (e.g., by the allocator) - pub extern_crate: Cell>, + pub extern_crate: Lock>, pub blob: MetadataBlob, - pub cnum_map: RefCell, + pub cnum_map: Lock, pub cnum: CrateNum, - pub codemap_import_info: RefCell>, - pub attribute_cache: RefCell<[Vec>>; 2]>, + pub codemap_import_info: RwLock>, + pub attribute_cache: Lock<[Vec>>; 2]>, pub root: schema::CrateRoot, @@ -81,7 +80,7 @@ pub struct CrateMetadata { pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq>, - pub dep_kind: Cell, + pub dep_kind: Lock, pub source: CrateSource, pub proc_macros: Option)>>, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 0b50f5c44962..34c93097a51f 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -175,7 +175,10 @@ provide! { <'tcx> tcx, def_id, other, cdata, is_sanitizer_runtime => { cdata.is_sanitizer_runtime(tcx.sess) } is_profiler_runtime => { cdata.is_profiler_runtime(tcx.sess) } panic_strategy => { cdata.panic_strategy() } - extern_crate => { Lrc::new(cdata.extern_crate.get()) } + extern_crate => { + let r = Lrc::new(*cdata.extern_crate.lock()); + r + } is_no_builtins => { cdata.is_no_builtins(tcx.sess) } impl_defaultness => { cdata.get_impl_defaultness(def_id.index) } reachable_non_generics => { @@ -225,7 +228,10 @@ provide! { <'tcx> tcx, def_id, other, cdata, cdata.is_dllimport_foreign_item(def_id.index) } visibility => { cdata.get_visibility(def_id.index) } - dep_kind => { cdata.dep_kind.get() } + dep_kind => { + let r = *cdata.dep_kind.lock(); + r + } crate_name => { cdata.name } item_children => { let mut result = vec![]; @@ -241,10 +247,11 @@ provide! { <'tcx> tcx, def_id, other, cdata, } missing_extern_crate_item => { - match cdata.extern_crate.get() { + let r = match *cdata.extern_crate.borrow() { Some(extern_crate) if !extern_crate.direct => true, _ => false, - } + }; + r } used_crate_source => { Lrc::new(cdata.source.clone()) } @@ -419,13 +426,16 @@ impl CrateStore for cstore::CStore { fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { - self.get_crate_data(cnum).dep_kind.get() + let data = self.get_crate_data(cnum); + let r = *data.dep_kind.lock(); + r } fn export_macros_untracked(&self, cnum: CrateNum) { let data = self.get_crate_data(cnum); - if data.dep_kind.get() == DepKind::UnexportedMacrosOnly { - data.dep_kind.set(DepKind::MacrosOnly) + let mut dep_kind = data.dep_kind.lock(); + if *dep_kind == DepKind::UnexportedMacrosOnly { + *dep_kind = DepKind::MacrosOnly; } } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f44703b9335e..d83d6f26393d 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -13,7 +13,7 @@ use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; use schema::*; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, ReadGuard}; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir; use rustc::middle::cstore::{LinkagePreference, ExternConstBody, @@ -31,7 +31,6 @@ use rustc::ty::codec::TyDecoder; use rustc::mir::Mir; use rustc::util::nodemap::FxHashMap; -use std::cell::Ref; use std::collections::BTreeMap; use std::io; use std::mem; @@ -714,7 +713,7 @@ impl<'a, 'tcx> CrateMetadata { }; // Iterate over all children. - let macros_only = self.dep_kind.get().macros_only(); + let macros_only = self.dep_kind.lock().macros_only(); for child_index in item.children.decode((self, sess)) { if macros_only { continue @@ -950,6 +949,8 @@ impl<'a, 'tcx> CrateMetadata { if vec_.len() < node_index + 1 { vec_.resize(node_index + 1, None); } + // This can overwrite the result produced by another thread, but the value + // written should be the same vec_[node_index] = Some(result.clone()); result } @@ -1156,7 +1157,7 @@ impl<'a, 'tcx> CrateMetadata { /// for items inlined from other crates. pub fn imported_filemaps(&'a self, local_codemap: &codemap::CodeMap) - -> Ref<'a, Vec> { + -> ReadGuard<'a, Vec> { { let filemaps = self.codemap_import_info.borrow(); if !filemaps.is_empty() { @@ -1164,6 +1165,14 @@ impl<'a, 'tcx> CrateMetadata { } } + // Lock the codemap_import_info to ensure this only happens once + let mut codemap_import_info = self.codemap_import_info.borrow_mut(); + + if !codemap_import_info.is_empty() { + drop(codemap_import_info); + return self.codemap_import_info.borrow(); + } + let external_codemap = self.root.codemap.decode(self); let imported_filemaps = external_codemap.map(|filemap_to_import| { @@ -1222,8 +1231,10 @@ impl<'a, 'tcx> CrateMetadata { } }).collect(); + *codemap_import_info = imported_filemaps; + drop(codemap_import_info); + // This shouldn't borrow twice, but there is no way to downgrade RefMut to Ref. - *self.codemap_import_info.borrow_mut() = imported_filemaps; self.codemap_import_info.borrow() } } From 5b8f9c5fe238500fcbe7c3e432ea623370058524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Feb 2018 10:52:26 +0100 Subject: [PATCH 114/830] Make CStore thread-safe --- src/librustc_metadata/cstore.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 19f43c180de3..bd5ad93946e3 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -89,21 +89,23 @@ pub struct CrateMetadata { } pub struct CStore { - metas: RefCell>>>, + metas: RwLock>>>, /// Map from NodeId's of local extern crate statements to crate numbers - extern_mod_crate_map: RefCell>, + extern_mod_crate_map: Lock>, pub metadata_loader: Box, } impl CStore { pub fn new(metadata_loader: Box) -> CStore { CStore { - metas: RefCell::new(IndexVec::new()), - extern_mod_crate_map: RefCell::new(FxHashMap()), + metas: RwLock::new(IndexVec::new()), + extern_mod_crate_map: Lock::new(FxHashMap()), metadata_loader, } } + /// You cannot use this function to allocate a CrateNum in a thread-safe manner. + /// It is currently only used in CrateLoader which is single-threaded code. pub fn next_crate_num(&self) -> CrateNum { CrateNum::new(self.metas.borrow().len() + 1) } From c63d5e04df48fcd4eb8040a821936ae338810bf6 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 8 Mar 2018 10:20:18 -0800 Subject: [PATCH 115/830] Update libc to 0.2.39 CC #42681 --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liblibc b/src/liblibc index 56444a4545bd..ed04152aacf5 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit 56444a4545bd71430d64b86b8a71714cfdbe9f5d +Subproject commit ed04152aacf5b4798f78ff13396f3c04c0a77144 From a67e0723a3136fac1a72febbc5ee368a9a606c0d Mon Sep 17 00:00:00 2001 From: Bastien Orivel Date: Mon, 12 Mar 2018 20:23:23 +0100 Subject: [PATCH 116/830] Dedupe rand --- src/Cargo.lock | 43 +++++++++++------------------ src/librustc_back/Cargo.toml | 2 +- src/librustc_incremental/Cargo.toml | 2 +- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 3252fda970b0..57370f1c0136 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -198,7 +198,7 @@ dependencies = [ "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -932,11 +932,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jobserver" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1337,19 +1338,18 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" -version = "0.2.9" +version = "0.2.13" 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.39 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1457,16 +1457,6 @@ dependencies = [ "nibble_vec 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand" version = "0.4.2" @@ -1680,7 +1670,7 @@ dependencies = [ "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", - "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", @@ -1711,7 +1701,7 @@ dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1812,7 +1802,7 @@ name = "rustc_back" version = "0.0.0" dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "syntax 0.0.0", ] @@ -1855,7 +1845,7 @@ dependencies = [ "ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1910,7 +1900,7 @@ version = "0.0.0" dependencies = [ "graphviz 0.0.0", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", "serialize 0.0.0", @@ -2076,7 +2066,7 @@ dependencies = [ "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2894,7 +2884,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" -"checksum jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "565f6106bd87b394398f813bea4e5ecad6d6b0f6aa077592d088f882a506481d" +"checksum jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2abd9fd3242accb0e2e30986f2cf30cda3e19eec5cc6d584b218ce2b1c0e3c" "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483" "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -2936,7 +2926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum os_pipe 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "998bfbb3042e715190fe2a41abfa047d7e8cb81374d2977d7f100eacd8619cb1" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412" -"checksum parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6bf05dc61189828dfd7a59fd6e66d538e88d6b30390da1124a291e09fd3098b3" +"checksum parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "538ef00b7317875071d5e00f603f24d16f0b474c1a5fc0ccb8b454ca72eafa79" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "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" @@ -2949,7 +2939,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" "checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4" "checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" diff --git a/src/librustc_back/Cargo.toml b/src/librustc_back/Cargo.toml index d864c5bc6105..4c5b1417a2f6 100644 --- a/src/librustc_back/Cargo.toml +++ b/src/librustc_back/Cargo.toml @@ -12,7 +12,7 @@ crate-type = ["dylib"] syntax = { path = "../libsyntax" } serialize = { path = "../libserialize" } log = "0.4" -rand = "0.3" +rand = "0.4" [features] jemalloc = [] diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml index eabc3ab03b19..dd05679589e7 100644 --- a/src/librustc_incremental/Cargo.toml +++ b/src/librustc_incremental/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["dylib"] [dependencies] graphviz = { path = "../libgraphviz" } log = "0.4" -rand = "0.3" +rand = "0.4" rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } serialize = { path = "../libserialize" } From bda5a45793b7bf98290b815f80db6ae2e1f867ae Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Mar 2018 16:01:28 +0100 Subject: [PATCH 117/830] Add missing links --- src/libcore/fmt/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 8ad5a9861a02..213b317f632e 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -684,18 +684,16 @@ pub trait Octal { /// /// The `Binary` trait should format its output as a number in binary. /// -/// For primitive signed integers (`i8` to `i128`, and `isize`), +/// For primitive signed integers ([`i8`] to [`i128`], and [`isize`]), /// negative values are formatted as the two’s complement representation. /// /// The alternate flag, `#`, adds a `0b` in front of the output. /// /// For more information on formatters, see [the module-level documentation][module]. /// -/// [module]: ../../std/fmt/index.html -/// /// # Examples /// -/// Basic usage with `i32`: +/// Basic usage with [`i32`]: /// /// ``` /// let x = 42; // 42 is '101010' in binary @@ -725,6 +723,12 @@ pub trait Octal { /// /// println!("l as binary is: {:b}", l); /// ``` +/// +/// [module]: ../../std/fmt/index.html +/// [`i8`]: ../../std/primitive.i8.html +/// [`i128`]: ../../std/primitive.i128.html +/// [`isize`]: ../../std/primitive.isize.html +/// [`i32`]: ../../std/primitive.i32.html #[stable(feature = "rust1", since = "1.0.0")] pub trait Binary { /// Formats the value using the given formatter. From 366ee8518fe53e821e809812ba80e7696861c93c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Mar 2018 00:11:17 +0100 Subject: [PATCH 118/830] Fix blink when main theme is selected --- src/librustdoc/html/static/storage.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index 7e9cfbd67634..c8571e4cf918 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -44,8 +44,12 @@ function switchTheme(styleElem, mainStyleElem, newTheme) { var fullBasicCss = "rustdoc" + resourcesSuffix + ".css"; var fullNewTheme = newTheme + resourcesSuffix + ".css"; var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme); - var found = false; + if (styleElem.href === newHref) { + return; + } + + var found = false; if (savedHref.length === 0) { onEach(document.getElementsByTagName("link"), function(el) { savedHref.push(el.href); From 9b1c69ec93d17b9593d183858b7d8b3c3e0cb703 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 12 Mar 2018 13:02:49 -0700 Subject: [PATCH 119/830] Update the rls-rustc package Should hopefully fix compiling the rls! --- src/Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 3252fda970b0..f8c04fe9272a 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1598,7 +1598,7 @@ dependencies = [ "rls-analysis 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", "rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-rustc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-rustc 0.2.2 (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.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustfmt-nightly 0.3.8", @@ -1639,7 +1639,7 @@ dependencies = [ [[package]] name = "rls-rustc" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2964,7 +2964,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rls-analysis 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39461c31c9ec26c2f15821d6aaa349216bf71e24e69550d9f8eeded78dc435e1" "checksum rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56fb7b8e4850b988fbcf277fbdb1eff36879070d02fc1ca243b559273866973d" "checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510" -"checksum rls-rustc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "85cfb9dde19e313da3e47738008f8a472e470cc42d910b71595a9238494701f2" +"checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb" "checksum rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ad5e562044ea78a6764dd75ae8afe4b21fde49f4548024b5fdf6345c21fb524" From 74f5dd07cff8dba348f91cfef4df5242ab33a311 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 12 Mar 2018 13:09:03 -0700 Subject: [PATCH 120/830] rustc: Start a custom cabi module for wasm32 It actually was already using the `cabi_asmjs` module but that was by accident, so route the new `wasm32-unknown-unknown` target to a new `cabi_wasm32` module. The first entries in this module are to use `signext` and `zeroext` for types that are under 32 bytes in size Closes rust-lang-nursery/rust-wasm#88 --- src/librustc_trans/abi.rs | 9 ++++++++- src/librustc_trans/cabi_wasm32.rs | 31 +++++++++++++++++++++++++++++++ src/librustc_trans/lib.rs | 1 + 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/librustc_trans/cabi_wasm32.rs diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index ee0f2415bd80..d2420335b426 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -30,6 +30,7 @@ use cabi_sparc64; use cabi_nvptx; use cabi_nvptx64; use cabi_hexagon; +use cabi_wasm32; use mir::place::PlaceRef; use mir::operand::OperandValue; use type_::Type; @@ -948,7 +949,13 @@ impl<'a, 'tcx> FnType<'tcx> { "powerpc64" => cabi_powerpc64::compute_abi_info(cx, self), "s390x" => cabi_s390x::compute_abi_info(cx, self), "asmjs" => cabi_asmjs::compute_abi_info(cx, self), - "wasm32" => cabi_asmjs::compute_abi_info(cx, self), + "wasm32" => { + if cx.sess().opts.target_triple.contains("emscripten") { + cabi_asmjs::compute_abi_info(cx, self) + } else { + cabi_wasm32::compute_abi_info(cx, self) + } + } "msp430" => cabi_msp430::compute_abi_info(self), "sparc" => cabi_sparc::compute_abi_info(cx, self), "sparc64" => cabi_sparc64::compute_abi_info(cx, self), diff --git a/src/librustc_trans/cabi_wasm32.rs b/src/librustc_trans/cabi_wasm32.rs new file mode 100644 index 000000000000..5530a03d65dd --- /dev/null +++ b/src/librustc_trans/cabi_wasm32.rs @@ -0,0 +1,31 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use abi::{FnType, ArgType}; +use context::CodegenCx; + +fn classify_ret_ty<'a, 'tcx>(_cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) { + ret.extend_integer_width_to(32); +} + +fn classify_arg_ty(arg: &mut ArgType) { + arg.extend_integer_width_to(32); +} + +pub fn compute_abi_info<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, fty: &mut FnType<'tcx>) { + if !fty.ret.is_ignore() { + classify_ret_ty(cx, &mut fty.ret); + } + + for arg in &mut fty.args { + if arg.is_ignore() { continue; } + classify_arg_ty(arg); + } +} diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 39eb38658fee..4a32b614c05d 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -123,6 +123,7 @@ mod cabi_sparc64; mod cabi_x86; mod cabi_x86_64; mod cabi_x86_win64; +mod cabi_wasm32; mod callee; mod common; mod consts; From c80220436bf68dac572ee2c3d701d40f02e2eb88 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 12 Mar 2018 16:15:38 -0500 Subject: [PATCH 121/830] big fences to show that ```rust is the same as ``` --- src/doc/rustdoc/src/documentation-tests.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index e5a603a3709f..cc7b15812ec3 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -19,15 +19,19 @@ running `rustdoc --test foo.rs` will extract this example, and then run it as a Please note that by default, if no language is set for the block code, `rustdoc` assumes it is `Rust` code. So the following: +``````markdown ```rust let x = 5; ``` +`````` is strictly equivalent to: +``````markdown ``` let x = 5; ``` +`````` There's some subtlety though! Read on for more details. From 68d6eddaf8e1d34c1fa44f60463b70c81b277665 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sun, 18 Feb 2018 18:01:33 +0100 Subject: [PATCH 122/830] Some comments and documentation for name resolution crate --- src/librustc_resolve/lib.rs | 45 ++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 317bd9217b59..cb2c206c69b1 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -162,6 +162,10 @@ enum ResolutionError<'a> { ForwardDeclaredTyParam, } +/// Combines an error with provided span and emits it +/// +/// This takes the error provided, combines it with the span and any additional spans inside the +/// error and emits it. fn resolve_error<'sess, 'a>(resolver: &'sess Resolver, span: Span, resolution_error: ResolutionError<'a>) { @@ -364,7 +368,7 @@ struct BindingInfo { binding_mode: BindingMode, } -// Map from the name in a pattern to its binding mode. +/// Map from the name in a pattern to its binding mode. type BindingMap = FxHashMap; #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -559,6 +563,9 @@ impl<'a> PathSource<'a> { } } +/// Different kinds of symbols don't influence each other. +/// +/// Therefore, they have a separate universe (namespace). #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum Namespace { TypeNS, @@ -566,6 +573,7 @@ pub enum Namespace { MacroNS, } +/// Just a helper ‒ separate structure for each namespace. #[derive(Clone, Default, Debug)] pub struct PerNS { value_ns: T, @@ -662,6 +670,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { } } +/// This thing walks the whole crate in DFS manner, visiting each item, resolving names as it goes. impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { fn visit_item(&mut self, item: &'tcx Item) { self.resolve_item(item); @@ -788,7 +797,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { fn visit_generics(&mut self, generics: &'tcx Generics) { // For type parameter defaults, we have to ban access // to following type parameters, as the Substs can only - // provide previous type parameters as they're built. + // provide previous type parameters as they're built. We + // put all the parameters on the ban list and then remove + // them one by one as they are processed and become available. let mut default_ban_rib = Rib::new(ForwardTyParamBanRibKind); default_ban_rib.bindings.extend(generics.params.iter() .filter_map(|p| if let GenericParam::Type(ref tp) = *p { Some(tp) } else { None }) @@ -864,6 +875,16 @@ enum RibKind<'a> { } /// One local scope. +/// +/// A rib represents a scope names can live in. Note that these appear in many places, not just +/// around braces. At any place where the list of accessible names (of the given namespace) +/// changes, a new rib is put onto a stack. This may be, for example, a `let` statement (because it +/// introduces variables), a macro, etc. +/// +/// Different [rib kinds](enum.RibKind) are transparent for different names. +/// +/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When +/// resolving, the name is looked up from inside out. #[derive(Debug)] struct Rib<'a> { bindings: FxHashMap, @@ -879,6 +900,11 @@ impl<'a> Rib<'a> { } } +/// An intermediate resolution result. +/// +/// This refers to the thing referred by a name. The difference between `Def` and `Item` is that +/// items are visible in their whole block, while defs only from the place they are defined +/// forward. enum LexicalScopeBinding<'a> { Item(&'a NameBinding<'a>), Def(Def), @@ -909,7 +935,11 @@ enum PathResult<'a> { } enum ModuleKind { + /// Inline `mod something { ... }`. Block(NodeId), + /// Module from another file. + /// + /// Also called a normal module in the following code. Def(Def, Name), } @@ -1194,6 +1224,9 @@ impl<'a> NameBinding<'a> { } /// Interns the names of the primitive types. +/// +/// All other types are defined somewhere and possibly imported, but the primitive ones need +/// special handling, since they have no place of origin. struct PrimitiveTypeTable { primitive_types: FxHashMap, } @@ -1228,6 +1261,8 @@ impl PrimitiveTypeTable { } /// The main resolver class. +/// +/// This is the visitor that walks the whole crate. pub struct Resolver<'a> { session: &'a Session, cstore: &'a CrateStore, @@ -1359,6 +1394,7 @@ pub struct Resolver<'a> { injected_crate: Option>, } +/// Nothing really interesting here, it just provides memory for the rest of the crate. pub struct ResolverArenas<'a> { modules: arena::TypedArena>, local_modules: RefCell>>, @@ -1404,10 +1440,12 @@ impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> { match id.krate { LOCAL_CRATE => self.definitions.def_key(id.index).parent, _ => self.cstore.def_key(id).parent, - }.map(|index| DefId { index: index, ..id }) + }.map(|index| DefId { index, ..id }) } } +/// This is the interface through which the rest of the compiler asks about name resolution after +/// the whole AST has been indexed. impl<'a> hir::lowering::Resolver for Resolver<'a> { fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) { self.resolve_hir_path_cb(path, is_value, @@ -1630,6 +1668,7 @@ impl<'a> Resolver<'a> { } } + /// Runs the function on each namespace. fn per_ns T>(&mut self, mut f: F) -> PerNS { PerNS { type_ns: f(self, TypeNS), From 0511077ef2fe9c2803c1a8a25b265792deb56710 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 12 Mar 2018 14:32:29 -0700 Subject: [PATCH 123/830] rustc: Add `sha` to the x86 feature whitelist This'll help us bind the [`SHA` intrinsics][intr] in stdsimd! [intr]: https://software.intel.com/sites/landingpage/IntrinsicsGuide/#othertechs=SHA --- src/librustc_trans/llvm_util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 45445a48e233..02248d64d995 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -92,6 +92,7 @@ const X86_WHITELIST: &'static [&'static str] = &["aes", "avx", "avx2", "avx512bw "bmi1", "bmi2", "fma", "fxsr", "lzcnt", "mmx", "pclmulqdq", "popcnt", "rdrand", "rdseed", + "sha", "sse", "sse2", "sse3", "sse4.1", "sse4.2", "sse4a", "ssse3", "tbm", "xsave", "xsavec", From da257b8fecacdb577592032dcaa9e4b5900cab2c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 12 Mar 2018 22:42:23 +0100 Subject: [PATCH 124/830] Add missing examples --- src/libcore/fmt/mod.rs | 136 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 2 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 8ad5a9861a02..02a1b9e6a968 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1375,27 +1375,159 @@ impl<'a> Formatter<'a> { } } - /// Optionally specified integer width that the output should be + /// Optionally specified integer width that the output should be. + /// + /// # Examples + /// + /// ``` + /// use std::fmt; + /// + /// struct Foo(i32); + /// + /// impl fmt::Display for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// if let Some(width) = formatter.width() { + /// // If we received a width, we use it + /// write!(formatter, "{:width$}", &format!("Foo({})", self.0), width = width) + /// } else { + /// // Otherwise we do nothing special + /// write!(formatter, "Foo({})", self.0) + /// } + /// } + /// } + /// + /// assert_eq!(&format!("{:10}", Foo(23)), "Foo(23) "); + /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); + /// ``` #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn width(&self) -> Option { self.width } - /// Optionally specified precision for numeric types + /// Optionally specified precision for numeric types. + /// + /// # Examples + /// + /// ``` + /// use std::fmt; + /// + /// struct Foo(f32); + /// + /// impl fmt::Display for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// if let Some(precision) = formatter.precision() { + /// // If we received a precision, we use it. + /// write!(formatter, "Foo({1:.*})", precision, self.0) + /// } else { + /// // Otherwise we default to 2. + /// write!(formatter, "Foo({:.2})", self.0) + /// } + /// } + /// } + /// + /// assert_eq!(&format!("{:.4}", Foo(23.2)), "Foo(23.2000)"); + /// assert_eq!(&format!("{}", Foo(23.2)), "Foo(23.20)"); + /// ``` #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn precision(&self) -> Option { self.precision } /// Determines if the `+` flag was specified. + /// + /// # Examples + /// + /// ``` + /// use std::fmt; + /// + /// struct Foo(i32); + /// + /// impl fmt::Display for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// if formatter.sign_plus() { + /// write!(formatter, + /// "Foo({}{})", + /// if self.0 < 0 { '-' } else { '+' }, + /// self.0) + /// } else { + /// write!(formatter, "Foo({})", self.0) + /// } + /// } + /// } + /// + /// assert_eq!(&format!("{:+}", Foo(23)), "Foo(+23)"); + /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); + /// ``` #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_plus(&self) -> bool { self.flags & (1 << FlagV1::SignPlus as u32) != 0 } /// Determines if the `-` flag was specified. + /// + /// # Examples + /// + /// ``` + /// use std::fmt; + /// + /// struct Foo(i32); + /// + /// impl fmt::Display for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// if formatter.sign_minus() { + /// // You want a minus sign? Have one! + /// write!(formatter, "-Foo({})", self.0) + /// } else { + /// write!(formatter, "Foo({})", self.0) + /// } + /// } + /// } + /// + /// assert_eq!(&format!("{:-}", Foo(23)), "-Foo(23)"); + /// assert_eq!(&format!("{}", Foo(23)), "Foo(23)"); + /// ``` #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_minus(&self) -> bool { self.flags & (1 << FlagV1::SignMinus as u32) != 0 } /// Determines if the `#` flag was specified. + /// + /// # Examples + /// + /// ``` + /// use std::fmt; + /// + /// struct Foo(i32); + /// + /// impl fmt::Display for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// if formatter.alternate() { + /// write!(formatter, "Foo({})", self.0) + /// } else { + /// write!(formatter, "{}", self.0) + /// } + /// } + /// } + /// + /// assert_eq!(&format!("{:#}", Foo(23)), "Foo(23)"); + /// assert_eq!(&format!("{}", Foo(23)), "23"); + /// ``` #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn alternate(&self) -> bool { self.flags & (1 << FlagV1::Alternate as u32) != 0 } /// Determines if the `0` flag was specified. + /// + /// # Examples + /// + /// ``` + /// use std::fmt; + /// + /// struct Foo(i32); + /// + /// impl fmt::Display for Foo { + /// fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + /// assert!(formatter.sign_aware_zero_pad()); + /// assert_eq!(formatter.width(), Some(4)); + /// // We ignore the formatter's options. + /// write!(formatter, "{}", self.0) + /// } + /// } + /// + /// assert_eq!(&format!("{:04}", Foo(23)), "23"); + /// ``` #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_aware_zero_pad(&self) -> bool { self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0 From c685b57bf27d3ddecd83ab77e1973d36dff755b4 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 12 Mar 2018 17:16:21 -0500 Subject: [PATCH 125/830] add page to the Rustdoc Book about unstable features --- src/doc/rustdoc/src/SUMMARY.md | 1 + src/doc/rustdoc/src/unstable-features.md | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/doc/rustdoc/src/unstable-features.md diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md index 6315cb81a849..46528187c117 100644 --- a/src/doc/rustdoc/src/SUMMARY.md +++ b/src/doc/rustdoc/src/SUMMARY.md @@ -5,3 +5,4 @@ - [The `#[doc]` attribute](the-doc-attribute.md) - [Documentation tests](documentation-tests.md) - [Passes](passes.md) +- [Unstable features](unstable-features.md) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md new file mode 100644 index 000000000000..35380cdf069e --- /dev/null +++ b/src/doc/rustdoc/src/unstable-features.md @@ -0,0 +1,10 @@ +# Unstable features + +Rustdoc is under active developement, and like the Rust compiler, some features are only available +on the nightly releases. Some of these are new and need some more testing before they're able to get +released to the world at large, and some of them are tied to features in the Rust compiler that are +themselves unstable. Several features here require a matching `#![feature(...)]` attribute to +enable, and thus are more fully documented in the [Unstable Book]. Those sections will link over +there as necessary. + +[Unstable Book]: ../unstable-book/ From 373b2cdcd13788249e27d7f06f5c36f37bc8684e Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 12 Mar 2018 17:26:20 -0500 Subject: [PATCH 126/830] talk about error numbers for compile_fail doctests --- src/doc/rustdoc/src/unstable-features.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 35380cdf069e..8dbd0aa9a9a1 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -8,3 +8,26 @@ enable, and thus are more fully documented in the [Unstable Book]. Those section there as necessary. [Unstable Book]: ../unstable-book/ + +## Error numbers for `compile-fail` doctests + +As detailed in [the chapter on documentation tests][doctest-attributes], you can add a +`compile_fail` attribute to a doctest to state that the test should fail to compile. However, on +nightly, you can optionally add an error number to state that a doctest should emit a specific error +number: + +[doctest-attributes]: documentation-tests.html#attributes + +``````markdown +```compile_fail,E0044 +extern { fn some_func(x: T); } +``` +`````` + +This is used by the error index to ensure that the samples that correspond to a given error number +properly emit that error code. However, these error codes aren't guaranteed to be the only thing +that a piece of code emits from version to version, so this in unlikely to be stabilized in the +future. + +Attempting to use these error numbers on stable will result in the code sample being interpreted as +plain text. From 5a073d496d0a401980233d8ec3e8569abfc2269f Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 12 Mar 2018 20:05:18 -0500 Subject: [PATCH 127/830] Move librustc_typeck READMEs to rustc guide --- src/librustc_typeck/README.md | 51 +--- src/librustc_typeck/check/method/README.md | 111 --------- src/librustc_typeck/check/method/mod.rs | 4 +- src/librustc_typeck/variance/README.md | 276 --------------------- src/librustc_typeck/variance/mod.rs | 6 +- src/librustc_typeck/variance/terms.rs | 5 +- 6 files changed, 15 insertions(+), 438 deletions(-) delete mode 100644 src/librustc_typeck/check/method/README.md delete mode 100644 src/librustc_typeck/variance/README.md diff --git a/src/librustc_typeck/README.md b/src/librustc_typeck/README.md index 1abc914e7d66..f00597cb27f0 100644 --- a/src/librustc_typeck/README.md +++ b/src/librustc_typeck/README.md @@ -1,48 +1,5 @@ -NB: This crate is part of the Rust compiler. For an overview of the -compiler as a whole, see -[the README.md file found in `librustc`](../librustc/README.md). +For high-level intro to how type checking works in rustc, see the +[type checking] chapter of the [rustc guide]. -The `rustc_typeck` crate contains the source for "type collection" and -"type checking", as well as a few other bits of related functionality. -(It draws heavily on the [type inferencing][infer] and -[trait solving][traits] code found in librustc.) - -[infer]: ../librustc/infer/README.md -[traits]: ../librustc/traits/README.md - -## Type collection - -Type "collection" is the process of converting the types found in the -HIR (`hir::Ty`), which represent the syntactic things that the user -wrote, into the **internal representation** used by the compiler -(`Ty<'tcx>`) -- we also do similar conversions for where-clauses and -other bits of the function signature. - -To try and get a sense for the difference, consider this function: - -```rust -struct Foo { } -fn foo(x: Foo, y: self::Foo) { .. } -// ^^^ ^^^^^^^^^ -``` - -Those two parameters `x` and `y` each have the same type: but they -will have distinct `hir::Ty` nodes. Those nodes will have different -spans, and of course they encode the path somewhat differently. But -once they are "collected" into `Ty<'tcx>` nodes, they will be -represented by the exact same internal type. - -Collection is defined as a bundle of queries (e.g., `type_of`) for -computing information about the various functions, traits, and other -items in the crate being compiled. Note that each of these queries is -concerned with *interprocedural* things -- for example, for a function -definition, collection will figure out the type and signature of the -function, but it will not visit the *body* of the function in any way, -nor examine type annotations on local variables (that's the job of -type *checking*). - -For more details, see the `collect` module. - -## Type checking - -TODO +[type checking]: https://rust-lang-nursery.github.io/rustc-guide/type-checking.html +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ diff --git a/src/librustc_typeck/check/method/README.md b/src/librustc_typeck/check/method/README.md deleted file mode 100644 index b5d317d60253..000000000000 --- a/src/librustc_typeck/check/method/README.md +++ /dev/null @@ -1,111 +0,0 @@ -# Method lookup - -Method lookup can be rather complex due to the interaction of a number -of factors, such as self types, autoderef, trait lookup, etc. This -file provides an overview of the process. More detailed notes are in -the code itself, naturally. - -One way to think of method lookup is that we convert an expression of -the form: - - receiver.method(...) - -into a more explicit UFCS form: - - Trait::method(ADJ(receiver), ...) // for a trait call - ReceiverType::method(ADJ(receiver), ...) // for an inherent method call - -Here `ADJ` is some kind of adjustment, which is typically a series of -autoderefs and then possibly an autoref (e.g., `&**receiver`). However -we sometimes do other adjustments and coercions along the way, in -particular unsizing (e.g., converting from `[T; n]` to `[T]`). - -## The Two Phases - -Method lookup is divided into two major phases: probing (`probe.rs`) -and confirmation (`confirm.rs`). The probe phase is when we decide -what method to call and how to adjust the receiver. The confirmation -phase "applies" this selection, updating the side-tables, unifying -type variables, and otherwise doing side-effectful things. - -One reason for this division is to be more amenable to caching. The -probe phase produces a "pick" (`probe::Pick`), which is designed to be -cacheable across method-call sites. Therefore, it does not include -inference variables or other information. - -## Probe phase - -The probe phase (`probe.rs`) decides what method is being called and -how to adjust the receiver. - -### Steps - -The first thing that the probe phase does is to create a series of -*steps*. This is done by progressively dereferencing the receiver type -until it cannot be deref'd anymore, as well as applying an optional -"unsize" step. So if the receiver has type `Rc>`, this -might yield: - - Rc> - Box<[T; 3]> - [T; 3] - [T] - -### Candidate assembly - -We then search along those steps to create a list of *candidates*. A -`Candidate` is a method item that might plausibly be the method being -invoked. For each candidate, we'll derive a "transformed self type" -that takes into account explicit self. - -Candidates are grouped into two kinds, inherent and extension. - -**Inherent candidates** are those that are derived from the -type of the receiver itself. So, if you have a receiver of some -nominal type `Foo` (e.g., a struct), any methods defined within an -impl like `impl Foo` are inherent methods. Nothing needs to be -imported to use an inherent method, they are associated with the type -itself (note that inherent impls can only be defined in the same -module as the type itself). - -FIXME: Inherent candidates are not always derived from impls. If you -have a trait object, such as a value of type `Box`, then the -trait methods (`to_string()`, in this case) are inherently associated -with it. Another case is type parameters, in which case the methods of -their bounds are inherent. However, this part of the rules is subject -to change: when DST's "impl Trait for Trait" is complete, trait object -dispatch could be subsumed into trait matching, and the type parameter -behavior should be reconsidered in light of where clauses. - -**Extension candidates** are derived from imported traits. If I have -the trait `ToString` imported, and I call `to_string()` on a value of -type `T`, then we will go off to find out whether there is an impl of -`ToString` for `T`. These kinds of method calls are called "extension -methods". They can be defined in any module, not only the one that -defined `T`. Furthermore, you must import the trait to call such a -method. - -So, let's continue our example. Imagine that we were calling a method -`foo` with the receiver `Rc>` and there is a trait `Foo` -that defines it with `&self` for the type `Rc` as well as a method -on the type `Box` that defines `Foo` but with `&mut self`. Then we -might have two candidates: - - &Rc> from the impl of `Foo` for `Rc` where `U=Box - &mut Box<[T; 3]>> from the inherent impl on `Box` where `U=[T; 3]` - -### Candidate search - -Finally, to actually pick the method, we will search down the steps, -trying to match the receiver type against the candidate types. At -each step, we also consider an auto-ref and auto-mut-ref to see whether -that makes any of the candidates match. We pick the first step where -we find a match. - -In the case of our example, the first step is `Rc>`, -which does not itself match any candidate. But when we autoref it, we -get the type `&Rc>` which does match. We would then -recursively consider all where-clauses that appear on the impl: if -those match (or we cannot rule out that they do), then this is the -method we would pick. Otherwise, we would continue down the series of -steps. diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f7bb1a6a2323..1664f46464d1 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -8,7 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Method lookup: the secret sauce of Rust. See `README.md`. +//! Method lookup: the secret sauce of Rust. See the [rustc guide] chapter. +//! +//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/method-lookup.html use check::FnCtxt; use hir::def::Def; diff --git a/src/librustc_typeck/variance/README.md b/src/librustc_typeck/variance/README.md deleted file mode 100644 index 64d3389b34af..000000000000 --- a/src/librustc_typeck/variance/README.md +++ /dev/null @@ -1,276 +0,0 @@ -## Variance of type and lifetime parameters - -This file infers the variance of type and lifetime parameters. The -algorithm is taken from Section 4 of the paper "Taming the Wildcards: -Combining Definition- and Use-Site Variance" published in PLDI'11 and -written by Altidor et al., and hereafter referred to as The Paper. - -This inference is explicitly designed *not* to consider the uses of -types within code. To determine the variance of type parameters -defined on type `X`, we only consider the definition of the type `X` -and the definitions of any types it references. - -We only infer variance for type parameters found on *data types* -like structs and enums. In these cases, there is fairly straightforward -explanation for what variance means. The variance of the type -or lifetime parameters defines whether `T` is a subtype of `T` -(resp. `T<'a>` and `T<'b>`) based on the relationship of `A` and `B` -(resp. `'a` and `'b`). - -We do not infer variance for type parameters found on traits, fns, -or impls. Variance on trait parameters can make indeed make sense -(and we used to compute it) but it is actually rather subtle in -meaning and not that useful in practice, so we removed it. See the -addendum for some details. Variances on fn/impl parameters, otoh, -doesn't make sense because these parameters are instantiated and -then forgotten, they don't persist in types or compiled -byproducts. - -### The algorithm - -The basic idea is quite straightforward. We iterate over the types -defined and, for each use of a type parameter X, accumulate a -constraint indicating that the variance of X must be valid for the -variance of that use site. We then iteratively refine the variance of -X until all constraints are met. There is *always* a sol'n, because at -the limit we can declare all type parameters to be invariant and all -constraints will be satisfied. - -As a simple example, consider: - - enum Option { Some(A), None } - enum OptionalFn { Some(|B|), None } - enum OptionalMap { Some(|C| -> C), None } - -Here, we will generate the constraints: - - 1. V(A) <= + - 2. V(B) <= - - 3. V(C) <= + - 4. V(C) <= - - -These indicate that (1) the variance of A must be at most covariant; -(2) the variance of B must be at most contravariant; and (3, 4) the -variance of C must be at most covariant *and* contravariant. All of these -results are based on a variance lattice defined as follows: - - * Top (bivariant) - - + - o Bottom (invariant) - -Based on this lattice, the solution `V(A)=+`, `V(B)=-`, `V(C)=o` is the -optimal solution. Note that there is always a naive solution which -just declares all variables to be invariant. - -You may be wondering why fixed-point iteration is required. The reason -is that the variance of a use site may itself be a function of the -variance of other type parameters. In full generality, our constraints -take the form: - - V(X) <= Term - Term := + | - | * | o | V(X) | Term x Term - -Here the notation `V(X)` indicates the variance of a type/region -parameter `X` with respect to its defining class. `Term x Term` -represents the "variance transform" as defined in the paper: - -> If the variance of a type variable `X` in type expression `E` is `V2` - and the definition-site variance of the [corresponding] type parameter - of a class `C` is `V1`, then the variance of `X` in the type expression - `C` is `V3 = V1.xform(V2)`. - -### Constraints - -If I have a struct or enum with where clauses: - - struct Foo { ... } - -you might wonder whether the variance of `T` with respect to `Bar` -affects the variance `T` with respect to `Foo`. I claim no. The -reason: assume that `T` is invariant w/r/t `Bar` but covariant w/r/t -`Foo`. And then we have a `Foo` that is upcast to `Foo`, where -`X <: Y`. However, while `X : Bar`, `Y : Bar` does not hold. In that -case, the upcast will be illegal, but not because of a variance -failure, but rather because the target type `Foo` is itself just -not well-formed. Basically we get to assume well-formedness of all -types involved before considering variance. - -#### Dependency graph management - -Because variance is a whole-crate inference, its dependency graph -can become quite muddled if we are not careful. To resolve this, we refactor -into two queries: - -- `crate_variances` computes the variance for all items in the current crate. -- `variances_of` accesses the variance for an individual reading; it - works by requesting `crate_variances` and extracting the relevant data. - -If you limit yourself to reading `variances_of`, your code will only -depend then on the inference inferred for that particular item. - -Ultimately, this setup relies on the red-green algorithm. -In particular, every variance query ultimately depends on -- effectively -- -all type definitions in the entire crate (through `crate_variances`), -but since most changes will not result in a change -to the actual results from variance inference, -the `variances_of` query will wind up being considered green after it is re-evaluated. - -### Addendum: Variance on traits - -As mentioned above, we used to permit variance on traits. This was -computed based on the appearance of trait type parameters in -method signatures and was used to represent the compatibility of -vtables in trait objects (and also "virtual" vtables or dictionary -in trait bounds). One complication was that variance for -associated types is less obvious, since they can be projected out -and put to myriad uses, so it's not clear when it is safe to allow -`X::Bar` to vary (or indeed just what that means). Moreover (as -covered below) all inputs on any trait with an associated type had -to be invariant, limiting the applicability. Finally, the -annotations (`MarkerTrait`, `PhantomFn`) needed to ensure that all -trait type parameters had a variance were confusing and annoying -for little benefit. - -Just for historical reference,I am going to preserve some text indicating -how one could interpret variance and trait matching. - -#### Variance and object types - -Just as with structs and enums, we can decide the subtyping -relationship between two object types `&Trait` and `&Trait` -based on the relationship of `A` and `B`. Note that for object -types we ignore the `Self` type parameter -- it is unknown, and -the nature of dynamic dispatch ensures that we will always call a -function that is expected the appropriate `Self` type. However, we -must be careful with the other type parameters, or else we could -end up calling a function that is expecting one type but provided -another. - -To see what I mean, consider a trait like so: - - trait ConvertTo { - fn convertTo(&self) -> A; - } - -Intuitively, If we had one object `O=&ConvertTo` and another -`S=&ConvertTo`, then `S <: O` because `String <: Object` -(presuming Java-like "string" and "object" types, my go to examples -for subtyping). The actual algorithm would be to compare the -(explicit) type parameters pairwise respecting their variance: here, -the type parameter A is covariant (it appears only in a return -position), and hence we require that `String <: Object`. - -You'll note though that we did not consider the binding for the -(implicit) `Self` type parameter: in fact, it is unknown, so that's -good. The reason we can ignore that parameter is precisely because we -don't need to know its value until a call occurs, and at that time (as -you said) the dynamic nature of virtual dispatch means the code we run -will be correct for whatever value `Self` happens to be bound to for -the particular object whose method we called. `Self` is thus different -from `A`, because the caller requires that `A` be known in order to -know the return type of the method `convertTo()`. (As an aside, we -have rules preventing methods where `Self` appears outside of the -receiver position from being called via an object.) - -#### Trait variance and vtable resolution - -But traits aren't only used with objects. They're also used when -deciding whether a given impl satisfies a given trait bound. To set the -scene here, imagine I had a function: - - fn convertAll>(v: &[T]) { - ... - } - -Now imagine that I have an implementation of `ConvertTo` for `Object`: - - impl ConvertTo for Object { ... } - -And I want to call `convertAll` on an array of strings. Suppose -further that for whatever reason I specifically supply the value of -`String` for the type parameter `T`: - - let mut vector = vec!["string", ...]; - convertAll::(vector); - -Is this legal? To put another way, can we apply the `impl` for -`Object` to the type `String`? The answer is yes, but to see why -we have to expand out what will happen: - -- `convertAll` will create a pointer to one of the entries in the - vector, which will have type `&String` -- It will then call the impl of `convertTo()` that is intended - for use with objects. This has the type: - - fn(self: &Object) -> i32 - - It is ok to provide a value for `self` of type `&String` because - `&String <: &Object`. - -OK, so intuitively we want this to be legal, so let's bring this back -to variance and see whether we are computing the correct result. We -must first figure out how to phrase the question "is an impl for -`Object,i32` usable where an impl for `String,i32` is expected?" - -Maybe it's helpful to think of a dictionary-passing implementation of -type classes. In that case, `convertAll()` takes an implicit parameter -representing the impl. In short, we *have* an impl of type: - - V_O = ConvertTo for Object - -and the function prototype expects an impl of type: - - V_S = ConvertTo for String - -As with any argument, this is legal if the type of the value given -(`V_O`) is a subtype of the type expected (`V_S`). So is `V_O <: V_S`? -The answer will depend on the variance of the various parameters. In -this case, because the `Self` parameter is contravariant and `A` is -covariant, it means that: - - V_O <: V_S iff - i32 <: i32 - String <: Object - -These conditions are satisfied and so we are happy. - -#### Variance and associated types - -Traits with associated types -- or at minimum projection -expressions -- must be invariant with respect to all of their -inputs. To see why this makes sense, consider what subtyping for a -trait reference means: - - <: - -means that if I know that `T as Trait`, I also know that `U as -Trait`. Moreover, if you think of it as dictionary passing style, -it means that a dictionary for `` is safe to use where -a dictionary for `` is expected. - -The problem is that when you can project types out from ``, the relationship to types projected out of `` -is completely unknown unless `T==U` (see #21726 for more -details). Making `Trait` invariant ensures that this is true. - -Another related reason is that if we didn't make traits with -associated types invariant, then projection is no longer a -function with a single result. Consider: - -``` -trait Identity { type Out; fn foo(&self); } -impl Identity for T { type Out = T; ... } -``` - -Now if I have `<&'static () as Identity>::Out`, this can be -validly derived as `&'a ()` for any `'a`: - - <&'a () as Identity> <: <&'static () as Identity> - if &'static () < : &'a () -- Identity is contravariant in Self - if 'static : 'a -- Subtyping rules for relations - -This change otoh means that `<'static () as Identity>::Out` is -always `&'static ()` (which might then be upcast to `'a ()`, -separately). This was helpful in solving #21750. - - diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs index da243650c839..fd2b964103a3 100644 --- a/src/librustc_typeck/variance/mod.rs +++ b/src/librustc_typeck/variance/mod.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Module for inferring the variance of type and lifetime -//! parameters. See README.md for details. +//! Module for inferring the variance of type and lifetime parameters. See the [rustc guide] +//! chapter for more info. +//! +//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/variance.html use arena; use rustc::hir; diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index ac3d575b6488..b9ab00130b3c 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -87,7 +87,10 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx> lang_items: lang_items(tcx), }; - // See README.md for a discussion on dep-graph management. + // See the following for a discussion on dep-graph management. + // + // - https://rust-lang-nursery.github.io/rustc-guide/query.html + // - https://rust-lang-nursery.github.io/rustc-guide/variance.html tcx.hir.krate().visit_all_item_likes(&mut terms_cx); terms_cx From 0ca9a4c55b16761d3fd6ee5d305f15c4270b78e7 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 12 Mar 2018 20:09:50 -0500 Subject: [PATCH 128/830] Move librustdoc readme to rustc guide --- src/librustdoc/README.md | 173 +-------------------------------------- 1 file changed, 2 insertions(+), 171 deletions(-) diff --git a/src/librustdoc/README.md b/src/librustdoc/README.md index b0a5ae3718df..2cfe43a8389b 100644 --- a/src/librustdoc/README.md +++ b/src/librustdoc/README.md @@ -1,172 +1,3 @@ -# The walking tour of rustdoc +For more information about how `librustdoc` works, see the [rustc guide]. -Rustdoc is implemented entirely within the crate `librustdoc`. After partially compiling a crate to -get its AST (technically the HIR map) from rustc, librustdoc performs two major steps past that to -render a set of documentation: - -* "Clean" the AST into a form that's more suited to creating documentation (and slightly more - resistant to churn in the compiler). -* Use this cleaned AST to render a crate's documentation, one page at a time. - -Naturally, there's more than just this, and those descriptions simplify out lots of details, but -that's the high-level overview. - -(Side note: this is a library crate! The `rustdoc` binary is crated using the project in -`src/tools/rustdoc`. Note that literally all that does is call the `main()` that's in this crate's -`lib.rs`, though.) - -## Cheat sheet - -* Use `x.py build --stage 1 src/libstd src/tools/rustdoc` to make a useable rustdoc you can run on - other projects. - * Add `src/libtest` to be able to use `rustdoc --test`. - * If you've used `rustup toolchain link local /path/to/build/$TARGET/stage1` previously, then - after the previous build command, `cargo +local doc` will Just Work. -* Use `x.py doc --stage 1 src/libstd` to use this rustdoc to generate the standard library docs. - * The completed docs will be available in `build/$TARGET/doc/std`, though the bundle is meant to - be used as though you would copy out the `doc` folder to a web server, since that's where the - CSS/JS and landing page are. -* Most of the HTML printing code is in `html/format.rs` and `html/render.rs`. It's in a bunch of - `fmt::Display` implementations and supplementary functions. -* The types that got `Display` impls above are defined in `clean/mod.rs`, right next to the custom - `Clean` trait used to process them out of the rustc HIR. -* The bits specific to using rustdoc as a test harness are in `test.rs`. -* The Markdown renderer is loaded up in `html/markdown.rs`, including functions for extracting - doctests from a given block of Markdown. -* The tests on rustdoc *output* are located in `src/test/rustdoc`, where they're handled by the test - runner of rustbuild and the supplementary script `src/etc/htmldocck.py`. -* Tests on search index generation are located in `src/test/rustdoc-js`, as a series of JavaScript - files that encode queries on the standard library search index and expected results. - -## From crate to clean - -In `core.rs` are two central items: the `DocContext` struct, and the `run_core` function. The latter -is where rustdoc calls out to rustc to compile a crate to the point where rustdoc can take over. The -former is a state container used when crawling through a crate to gather its documentation. - -The main process of crate crawling is done in `clean/mod.rs` through several implementations of the -`Clean` trait defined within. This is a conversion trait, which defines one method: - -```rust -pub trait Clean { - fn clean(&self, cx: &DocContext) -> T; -} -``` - -`clean/mod.rs` also defines the types for the "cleaned" AST used later on to render documentation -pages. Each usually accompanies an implementation of `Clean` that takes some AST or HIR type from -rustc and converts it into the appropriate "cleaned" type. "Big" items like modules or associated -items may have some extra processing in its `Clean` implementation, but for the most part these -impls are straightforward conversions. The "entry point" to this module is the `impl Clean -for visit_ast::RustdocVisitor`, which is called by `run_core` above. - -You see, I actually lied a little earlier: There's another AST transformation that happens before -the events in `clean/mod.rs`. In `visit_ast.rs` is the type `RustdocVisitor`, which *actually* -crawls a `hir::Crate` to get the first intermediate representation, defined in `doctree.rs`. This -pass is mainly to get a few intermediate wrappers around the HIR types and to process visibility -and inlining. This is where `#[doc(inline)]`, `#[doc(no_inline)]`, and `#[doc(hidden)]` are -processed, as well as the logic for whether a `pub use` should get the full page or a "Reexport" -line in the module page. - -The other major thing that happens in `clean/mod.rs` is the collection of doc comments and -`#[doc=""]` attributes into a separate field of the Attributes struct, present on anything that gets -hand-written documentation. This makes it easier to collect this documentation later in the process. - -The primary output of this process is a clean::Crate with a tree of Items which describe the -publicly-documentable items in the target crate. - -### Hot potato - -Before moving on to the next major step, a few important "passes" occur over the documentation. -These do things like combine the separate "attributes" into a single string and strip leading -whitespace to make the document easier on the markdown parser, or drop items that are not public or -deliberately hidden with `#[doc(hidden)]`. These are all implemented in the `passes/` directory, one -file per pass. By default, all of these passes are run on a crate, but the ones regarding dropping -private/hidden items can be bypassed by passing `--document-private-items` to rustdoc. - -(Strictly speaking, you can fine-tune the passes run and even add your own, but [we're trying to -deprecate that][44136]. If you need finer-grain control over these passes, please let us know!) - -[44136]: https://github.com/rust-lang/rust/issues/44136 - -## From clean to crate - -This is where the "second phase" in rustdoc begins. This phase primarily lives in the `html/` -folder, and it all starts with `run()` in `html/render.rs`. This code is responsible for setting up -the `Context`, `SharedContext`, and `Cache` which are used during rendering, copying out the static -files which live in every rendered set of documentation (things like the fonts, CSS, and JavaScript -that live in `html/static/`), creating the search index, and printing out the source code rendering, -before beginning the process of rendering all the documentation for the crate. - -Several functions implemented directly on `Context` take the `clean::Crate` and set up some state -between rendering items or recursing on a module's child items. From here the "page rendering" -begins, via an enormous `write!()` call in `html/layout.rs`. The parts that actually generate HTML -from the items and documentation occurs within a series of `std::fmt::Display` implementations and -functions that pass around a `&mut std::fmt::Formatter`. The top-level implementation that writes -out the page body is the `impl<'a> fmt::Display for Item<'a>` in `html/render.rs`, which switches -out to one of several `item_*` functions based on the kind of `Item` being rendered. - -Depending on what kind of rendering code you're looking for, you'll probably find it either in -`html/render.rs` for major items like "what sections should I print for a struct page" or -`html/format.rs` for smaller component pieces like "how should I print a where clause as part of -some other item". - -Whenever rustdoc comes across an item that should print hand-written documentation alongside, it -calls out to `html/markdown.rs` which interfaces with the Markdown parser. This is exposed as a -series of types that wrap a string of Markdown, and implement `fmt::Display` to emit HTML text. It -takes special care to enable certain features like footnotes and tables and add syntax highlighting -to Rust code blocks (via `html/highlight.rs`) before running the Markdown parser. There's also a -function in here (`find_testable_code`) that specifically scans for Rust code blocks so the -test-runner code can find all the doctests in the crate. - -### From soup to nuts - -(alternate title: ["An unbroken thread that stretches from those first `Cell`s to us"][video]) - -[video]: https://www.youtube.com/watch?v=hOLAGYmUQV0 - -It's important to note that the AST cleaning can ask the compiler for information (crucially, -`DocContext` contains a `TyCtxt`), but page rendering cannot. The `clean::Crate` created within -`run_core` is passed outside the compiler context before being handed to `html::render::run`. This -means that a lot of the "supplementary data" that isn't immediately available inside an item's -definition, like which trait is the `Deref` trait used by the language, needs to be collected during -cleaning, stored in the `DocContext`, and passed along to the `SharedContext` during HTML rendering. -This manifests as a bunch of shared state, context variables, and `RefCell`s. - -Also of note is that some items that come from "asking the compiler" don't go directly into the -`DocContext` - for example, when loading items from a foreign crate, rustdoc will ask about trait -implementations and generate new `Item`s for the impls based on that information. This goes directly -into the returned `Crate` rather than roundabout through the `DocContext`. This way, these -implementations can be collected alongside the others, right before rendering the HTML. - -## Other tricks up its sleeve - -All this describes the process for generating HTML documentation from a Rust crate, but there are -couple other major modes that rustdoc runs in. It can also be run on a standalone Markdown file, or -it can run doctests on Rust code or standalone Markdown files. For the former, it shortcuts straight -to `html/markdown.rs`, optionally including a mode which inserts a Table of Contents to the output -HTML. - -For the latter, rustdoc runs a similar partial-compilation to get relevant documentation in -`test.rs`, but instead of going through the full clean and render process, it runs a much simpler -crate walk to grab *just* the hand-written documentation. Combined with the aforementioned -"`find_testable_code`" in `html/markdown.rs`, it builds up a collection of tests to run before -handing them off to the libtest test runner. One notable location in `test.rs` is the function -`make_test`, which is where hand-written doctests get transformed into something that can be -executed. - -## Dotting i's and crossing t's - -So that's rustdoc's code in a nutshell, but there's more things in the repo that deal with it. Since -we have the full `compiletest` suite at hand, there's a set of tests in `src/test/rustdoc` that make -sure the final HTML is what we expect in various situations. These tests also use a supplementary -script, `src/etc/htmldocck.py`, that allows it to look through the final HTML using XPath notation -to get a precise look at the output. The full description of all the commands available to rustdoc -tests is in `htmldocck.py`. - -In addition, there are separate tests for the search index and rustdoc's ability to query it. The -files in `src/test/rustdoc-js` each contain a different search query and the expected results, -broken out by search tab. These files are processed by a script in `src/tools/rustdoc-js` and the -Node.js runtime. These tests don't have as thorough of a writeup, but a broad example that features -results in all tabs can be found in `basic.js`. The basic idea is that you match a given `QUERY` -with a set of `EXPECTED` results, complete with the full item path of each item. +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustdoc.html From c1337cda4ccf349b8a5a80156e32c2499520b621 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Mon, 12 Mar 2018 21:26:51 -0400 Subject: [PATCH 129/830] Update -Wall message based on feedback The reference to -Wunused was removed, and some phrasing was changed. --- src/librustc_driver/lib.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 47168cb955a0..4b3315cf8d7a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1138,10 +1138,9 @@ fn usage(verbose: bool, include_unstable_options: bool) { fn print_wall_help() { println!(" -The flag -Wall does not exist in rustc. Most useful lints are enabled by default. -Use `rustc -W help` to see all available lints. The most used lints that are not -enabled by default covered by -Wunused; however, the best practice is to put -warning settings in the crate root using `#![warn(unused)]` instead of using +The flag `-Wall` does not exist in `rustc`. Most useful lints are enabled by +default. Use `rustc -W help` to see all available lints. It's more common to put +warning settings in the crate root using `#![warn(LINT_NAME)]` instead of using the command line flag directly. "); } From a48224b9ac287b9fe1b2e0783d0ccefe5b8c87df Mon Sep 17 00:00:00 2001 From: Anthony Defranceschi Date: Mon, 12 Mar 2018 21:22:03 +0100 Subject: [PATCH 130/830] Add a section for using assertions into doc tests. See #47945. --- src/doc/rustdoc/src/documentation-tests.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index e5a603a3709f..d907fbba0a08 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -31,6 +31,22 @@ let x = 5; There's some subtlety though! Read on for more details. +## Passing or failing a doctest + +Like regular unit tests, regular doctests are considered to "pass" +if they compile and run without panicking. +So if you want to demonstrate that some computation gives a certain result, +the `assert!` family of macros works the same as other Rust code: + +```rust +let foo = "foo"; + +assert_eq!(foo, "foo"); +``` + +This way, if the computation ever returns something different, +the code panics and the doctest fails. + ## Pre-processing examples In the example above, you'll note something strange: there's no `main` From 4897935e8645e5f1d9d9ef61c78a1cb019c44f89 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 13 Mar 2018 14:08:15 +0100 Subject: [PATCH 131/830] Add hexadecimal formatting of integers with fmt::Debug This can be used for integers within a larger types which implements Debug (possibly through derive) but not fmt::UpperHex or fmt::LowerHex. ```rust assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]"); assert!(format!("{:02X?}", b"Foo\0") == "[46, 6F, 6F, 00]"); ``` RFC: https://github.com/rust-lang/rfcs/pull/2226 --- src/liballoc/fmt.rs | 2 ++ src/libcore/fmt/mod.rs | 8 +++++++- src/libcore/fmt/num.rs | 8 +++++++- src/libcore/tests/fmt/num.rs | 6 ++++++ src/libfmt_macros/lib.rs | 22 ++++++++++++++++++++-- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index a092bfb3b0a8..2c4cdef03b0f 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -113,6 +113,8 @@ //! //! * *nothing* ⇒ [`Display`] //! * `?` ⇒ [`Debug`] +//! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers +//! * `X?` ⇒ [`Debug`] with lower-case hexadecimal integers //! * `o` ⇒ [`Octal`](trait.Octal.html) //! * `x` ⇒ [`LowerHex`](trait.LowerHex.html) //! * `X` ⇒ [`UpperHex`](trait.UpperHex.html) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 8ad5a9861a02..a31be0e216f2 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -333,7 +333,7 @@ impl<'a> ArgumentV1<'a> { // flags available in the v1 format of format_args #[derive(Copy, Clone)] -enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, } +enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, DebugLowerHex, DebugUpperHex } impl<'a> Arguments<'a> { /// When using the format_args!() macro, this function is used to generate the @@ -1401,6 +1401,12 @@ impl<'a> Formatter<'a> { self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0 } + // FIXME: Decide what public API we want for these two flags. + // https://github.com/rust-lang/rust/issues/48584 + fn debug_lower_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugLowerHex as u32) != 0 } + + fn debug_upper_hex(&self) -> bool { self.flags & (1 << FlagV1::DebugUpperHex as u32) != 0 } + /// Creates a [`DebugStruct`] builder designed to assist with creation of /// [`fmt::Debug`] implementations for structs. /// diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 2992e7cf8db3..86f1b5a8f287 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -159,7 +159,13 @@ macro_rules! debug { impl fmt::Debug for $T { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) + if f.debug_lower_hex() { + fmt::LowerHex::fmt(self, f) + } else if f.debug_upper_hex() { + fmt::UpperHex::fmt(self, f) + } else { + fmt::Display::fmt(self, f) + } } } } diff --git a/src/libcore/tests/fmt/num.rs b/src/libcore/tests/fmt/num.rs index 4ddedd910048..bc205ec0582e 100644 --- a/src/libcore/tests/fmt/num.rs +++ b/src/libcore/tests/fmt/num.rs @@ -150,3 +150,9 @@ fn test_format_int_twos_complement() { assert!(format!("{}", i32::MIN) == "-2147483648"); assert!(format!("{}", i64::MIN) == "-9223372036854775808"); } + +#[test] +fn test_format_debug_hex() { + assert!(format!("{:02x?}", b"Foo\0") == "[46, 6f, 6f, 00]"); + assert!(format!("{:02X?}", b"Foo\0") == "[46, 6F, 6F, 00]"); +} diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 71519ab21fef..0f45f965104c 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -108,6 +108,10 @@ pub enum Flag { /// For numbers, this means that the number will be padded with zeroes, /// and the sign (`+` or `-`) will precede them. FlagSignAwareZeroPad, + /// For Debug / `?`, format integers in lower-case hexadecimal. + FlagDebugLowerHex, + /// For Debug / `?`, format integers in upper-case hexadecimal. + FlagDebugUpperHex, } /// A count is used for the precision and width parameters of an integer, and @@ -377,8 +381,22 @@ impl<'a> Parser<'a> { spec.precision = self.count(); } } - // Finally the actual format specifier - if self.consume('?') { + // Optional radix followed by the actual format specifier + if self.consume('x') { + if self.consume('?') { + spec.flags |= 1 << (FlagDebugLowerHex as u32); + spec.ty = "?"; + } else { + spec.ty = "x"; + } + } else if self.consume('X') { + if self.consume('?') { + spec.flags |= 1 << (FlagDebugUpperHex as u32); + spec.ty = "?"; + } else { + spec.ty = "X"; + } + } else if self.consume('?') { spec.ty = "?"; } else { spec.ty = self.word(); From 04442af18bf01622288a33faa58caf7e666cac40 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 13 Mar 2018 07:54:03 -0700 Subject: [PATCH 132/830] rustc: Don't invoke `lld` with an `@`-file Looks like LLD doesn't support this yet, so always try to use the OS before we fall back to using `@` --- src/librustc_trans/back/command.rs | 7 +++++++ src/librustc_trans/back/link.rs | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/librustc_trans/back/command.rs b/src/librustc_trans/back/command.rs index ecf7bf5036e0..a5649e98baa7 100644 --- a/src/librustc_trans/back/command.rs +++ b/src/librustc_trans/back/command.rs @@ -132,6 +132,13 @@ impl Command { return false } + // Right now LLD doesn't support the `@` syntax of passing an argument + // through files, so regardless of the platform we try to go to the OS + // on this one. + if let Program::Lld(..) = self.program { + return false + } + // Ok so on Windows to spawn a process is 32,768 characters in its // command line [1]. Unfortunately we don't actually have access to that // as it's calculated just before spawning. Instead we perform a diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 867498d0c59e..bdda7741221f 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -827,11 +827,14 @@ fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) if !cmd.very_likely_to_exceed_some_spawn_limit() { match cmd.command().stdout(Stdio::piped()).stderr(Stdio::piped()).spawn() { Ok(child) => return child.wait_with_output(), - Err(ref e) if command_line_too_big(e) => {} + Err(ref e) if command_line_too_big(e) => { + info!("command line to linker was too big: {}", e); + } Err(e) => return Err(e) } } + info!("falling back to passing arguments to linker via an @-file"); let mut cmd2 = cmd.clone(); let mut args = String::new(); for arg in cmd2.take_args() { @@ -856,6 +859,7 @@ fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) }; fs::write(&file, &bytes)?; cmd2.arg(format!("@{}", file.display())); + info!("invoking linker {:?}", cmd2); return cmd2.output(); #[cfg(unix)] From af099bb2401bc9fe7aa753a20086d51c49816bcd Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 9 Mar 2018 07:09:24 +0100 Subject: [PATCH 133/830] Cache const eval queries --- src/librustc/ty/maps/config.rs | 12 +++++ src/librustc/ty/maps/mod.rs | 2 +- src/librustc/ty/maps/on_disk_cache.rs | 68 +++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 21affcbc9ede..7e2ece1b334b 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -156,6 +156,18 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String { format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id())) } + + #[inline] + fn cache_on_disk(key: Self::Key) -> bool { + key.value.instance.def_id().is_local() + } + + #[inline] + fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + id: SerializedDepNodeIndex) + -> Option { + tcx.on_disk_query_result_cache.load_constant(tcx, id).map(Ok) + } } impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 0ded759fec73..27eb7de2d06a 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -82,7 +82,7 @@ pub use self::on_disk_cache::OnDiskCache; // the driver creates (using several `rustc_*` crates). // // The result of query must implement Clone. They must also implement ty::maps::values::Value -// which produces an appropiate error value if the query resulted in a query cycle. +// which produces an appropriate error value if the query resulted in a query cycle. // Queries marked with `fatal_cycle` do not need that implementation // as they will raise an fatal error on query cycles instead. define_maps! { <'tcx> diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 49c4b8bc49d8..bb0b1975b9e4 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -75,6 +75,10 @@ pub struct OnDiskCache<'sess> { // A map from dep-node to the position of any associated diagnostics in // `serialized_data`. prev_diagnostics_index: FxHashMap, + + // A map from dep-node to the position of any associated constants in + // `serialized_data`. + prev_constants_index: FxHashMap, } // This type is used only for (de-)serialization. @@ -84,8 +88,10 @@ struct Footer { prev_cnums: Vec<(u32, String, CrateDisambiguator)>, query_result_index: EncodedQueryResultIndex, diagnostics_index: EncodedQueryResultIndex, + constants_index: EncodedConstantsIndex, } +type EncodedConstantsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnostics = Vec; @@ -139,6 +145,7 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: RefCell::new(FxHashMap()), query_result_index: footer.query_result_index.into_iter().collect(), prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(), + prev_constants_index: footer.constants_index.into_iter().collect(), synthetic_expansion_infos: RefCell::new(FxHashMap()), } } @@ -154,6 +161,7 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: RefCell::new(FxHashMap()), query_result_index: FxHashMap(), prev_diagnostics_index: FxHashMap(), + prev_constants_index: FxHashMap(), synthetic_expansion_infos: RefCell::new(FxHashMap()), } } @@ -223,6 +231,45 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::(tcx, enc, qri)?; } + // encode successful constant evaluations + let constants_index = { + let mut constants_index = EncodedConstantsIndex::new(); + use ty::maps::queries::const_eval; + use ty::maps::plumbing::GetCacheInternal; + use ty::maps::config::QueryDescription; + for (key, entry) in const_eval::get_cache_internal(tcx).map.iter() { + if let Ok(ref constant) = entry.value { + if const_eval::cache_on_disk(key.clone()) { + trace!("caching constant {:?} with value {:#?}", key, constant); + let dep_node = SerializedDepNodeIndex::new(entry.index.index()); + + // Record position of the cache entry + constants_index.push(( + dep_node, + AbsoluteBytePos::new(encoder.position()), + )); + let did = key.value.instance.def_id(); + let constant = if key.value.promoted.is_none() + && tcx.is_static(did).is_some() { + // memorize the allocation for the static, too, so + // we can refer to the static, not just read its value + // since we have had a successful query, the cached value must + // exist, so we can unwrap it + let cached = tcx.interpret_interner.get_cached(did).unwrap(); + (constant, Some(cached)) + } else { + (constant, None) + }; + + // Encode the type check tables with the SerializedDepNodeIndex + // as tag. + encoder.encode_tagged(dep_node, &constant)?; + } + } + } + constants_index + }; + // Encode diagnostics let diagnostics_index = { let mut diagnostics_index = EncodedDiagnosticsIndex::new(); @@ -256,6 +303,7 @@ impl<'sess> OnDiskCache<'sess> { prev_cnums, query_result_index, diagnostics_index, + constants_index, })?; // Encode the position of the footer as the last 8 bytes of the @@ -278,6 +326,25 @@ impl<'sess> OnDiskCache<'sess> { }) } + /// Load a constant emitted during the previous compilation session. + pub fn load_constant<'a, 'tcx>(&self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + dep_node_index: SerializedDepNodeIndex) + -> Option<&'tcx ty::Const<'tcx>> { + type Encoded<'tcx> = (ty::Const<'tcx>, Option); + let constant: Option> = self.load_indexed( + tcx, + dep_node_index, + &self.prev_constants_index, + "constants"); + + constant.map(|(c, _alloc_id)| { + // the AllocId decoding already registers the AllocId to its DefId + // so we don't need to take additional actions here + tcx.mk_const(c) + }) + } + /// Load a diagnostic emitted during the previous compilation session. pub fn load_diagnostics<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -563,6 +630,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, ' tcx.interpret_interner.intern_at_reserved(alloc_id, allocation); if let Some(glob) = Option::::decode(self)? { + trace!("connecting alloc {:?} with {:?}", alloc_id, glob); tcx.interpret_interner.cache(glob, alloc_id); } From f873c1e2db8d06be6a816b838655906fa9f2dac9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 14 Feb 2018 16:00:07 -0500 Subject: [PATCH 134/830] require `Lifted` types to outlive `'tcx` --- src/librustc/ty/context.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b760649c37d1..e7d6bdd3383d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1508,7 +1508,7 @@ impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { /// pointer differs. The latter case is possible if a primitive type, /// e.g. `()` or `u8`, was interned in a different context. pub trait Lift<'tcx> { - type Lifted; + type Lifted: 'tcx; fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option; } From 23837c1901ab234ee6bc806744cd47d5a652cdfc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Feb 2018 10:34:23 -0500 Subject: [PATCH 135/830] improve TypeFoldable/Lift macros and make a bunch of stuff use them Improvements: - Use Clone not Copy for the "simple cases" - Separate TypeFoldable and Lift for the "simple cases" - Support generics type parameters - Support named fields in enum variants - etc --- src/librustc/infer/mod.rs | 13 - src/librustc/lib.rs | 1 + src/librustc/macros.rs | 300 +++++++++++++ src/librustc/mir/cache.rs | 4 + src/librustc/mir/mod.rs | 188 +++----- src/librustc/mir/tcx.rs | 24 +- src/librustc/traits/structural_impls.rs | 281 ++---------- src/librustc/ty/fold.rs | 3 + src/librustc/ty/relate.rs | 11 +- src/librustc/ty/structural_impls.rs | 543 ++++++------------------ 10 files changed, 553 insertions(+), 815 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 5d44b2043e26..b94f1819c7dd 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1647,19 +1647,6 @@ impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for TypeTrace<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - TypeTrace { - cause: self.cause.fold_with(folder), - values: self.values.fold_with(folder) - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.cause.visit_with(visitor) || self.values.visit_with(visitor) - } -} - impl<'tcx> fmt::Debug for RegionObligation<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "RegionObligation(sub_region={:?}, sup_type={:?})", diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 56de2939ffae..2cf176036296 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -57,6 +57,7 @@ #![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![cfg_attr(windows, feature(libc))] +#![feature(macro_lifetime_matcher)] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] #![feature(never_type)] diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index 9a394e524817..6013e3aef81e 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -138,3 +138,303 @@ macro_rules! impl_stable_hash_for_spanned { ); } +/////////////////////////////////////////////////////////////////////////// +// Lift and TypeFoldable macros +// +// When possible, use one of these (relatively) convenient macros to write +// the impls for you. + +#[macro_export] +macro_rules! CloneLiftImpls { + (for <$tcx:lifetime> { $($ty:ty,)+ }) => { + $( + impl<$tcx> $crate::ty::Lift<$tcx> for $ty { + type Lifted = Self; + fn lift_to_tcx<'a, 'gcx>(&self, _: $crate::ty::TyCtxt<'a, 'gcx, $tcx>) -> Option { + Some(Clone::clone(self)) + } + } + )+ + }; + + ($($ty:ty,)+) => { + CloneLiftImpls! { + for <'tcx> { + $($ty,)+ + } + } + }; +} + +/// Used for types that are `Copy` and which **do not care arena +/// allocated data** (i.e., don't need to be folded). +#[macro_export] +macro_rules! CloneTypeFoldableImpls { + (for <$tcx:lifetime> { $($ty:ty,)+ }) => { + $( + impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty { + fn super_fold_with<'gcx: $tcx, F: $crate::ty::fold::TypeFolder<'gcx, $tcx>>( + &self, + _: &mut F + ) -> $ty { + Clone::clone(self) + } + + fn super_visit_with>( + &self, + _: &mut F) + -> bool + { + false + } + } + )+ + }; + + ($($ty:ty,)+) => { + CloneTypeFoldableImpls! { + for <'tcx> { + $($ty,)+ + } + } + }; +} + +#[macro_export] +macro_rules! CloneTypeFoldableAndLiftImpls { + ($($t:tt)*) => { + CloneTypeFoldableImpls! { $($t)* } + CloneLiftImpls! { $($t)* } + } +} + +#[macro_export] +macro_rules! BraceStructLiftImpl { + (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path { + type Lifted = $lifted:ty; + $($field:ident),* $(,)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::ty::Lift<$tcx> for $s + $(where $($wc)*)* + { + type Lifted = $lifted; + + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> { + $(let $field = tcx.lift(&self.$field)?;)* + Some(Self::Lifted { $($field),* }) + } + } + }; +} + +#[macro_export] +macro_rules! EnumLiftImpl { + (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path { + type Lifted = $lifted:ty; + $( + ($variant:path) ( $( $variant_arg:ident),* ) + ),* + $(,)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::ty::Lift<$tcx> for $s + $(where $($wc)*)* + { + type Lifted = $lifted; + + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> { + match self { + $($variant ( $($variant_arg),* ) => { + Some($variant ( $(tcx.lift($variant_arg)?),* )) + })* + } + } + } + }; +} + +#[macro_export] +macro_rules! BraceStructTypeFoldableImpl { + (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { + $($field:ident),* $(,)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s + $(where $($wc)*)* + { + fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>( + &self, + folder: &mut V, + ) -> Self { + let $s { $($field,)* } = self; + $s { $($field: $crate::ty::fold::TypeFoldable::fold_with($field, folder),)* } + } + + fn super_visit_with>( + &self, + visitor: &mut V, + ) -> bool { + let $s { $($field,)* } = self; + false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* + } + } + }; +} + +#[macro_export] +macro_rules! TupleStructTypeFoldableImpl { + (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { + $($field:ident),* $(,)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s + $(where $($wc)*)* + { + fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>( + &self, + folder: &mut V, + ) -> Self { + let $s($($field,)*)= self; + $s($($crate::ty::fold::TypeFoldable::fold_with($field, folder),)*) + } + + fn super_visit_with>( + &self, + visitor: &mut V, + ) -> bool { + let $s($($field,)*) = self; + false $(|| $crate::ty::fold::TypeFoldable::visit_with($field, visitor))* + } + } + }; +} + +#[macro_export] +macro_rules! EnumTypeFoldableImpl { + (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { + $($variants:tt)* + } $(where $($wc:tt)*)*) => { + impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s + $(where $($wc)*)* + { + fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>( + &self, + folder: &mut V, + ) -> Self { + EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output()) + } + + fn super_visit_with>( + &self, + visitor: &mut V, + ) -> bool { + EnumTypeFoldableImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) + } + } + }; + + (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => { + match $this { + $($output)* + } + }; + + (@FoldVariants($this:expr, $folder:expr) + input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @FoldVariants($this, $folder) + input($($input)*) + output( + $variant ( $($variant_arg),* ) => { + $variant ( + $($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)),* + ) + } + $($output)* + ) + ) + }; + + (@FoldVariants($this:expr, $folder:expr) + input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @FoldVariants($this, $folder) + input($($input)*) + output( + $variant { $($variant_arg),* } => { + $variant { + $($variant_arg: $crate::ty::fold::TypeFoldable::fold_with( + $variant_arg, $folder + )),* } + } + $($output)* + ) + ) + }; + + (@FoldVariants($this:expr, $folder:expr) + input( ($variant:path), $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @FoldVariants($this, $folder) + input($($input)*) + output( + $variant => { $variant } + $($output)* + ) + ) + }; + + (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => { + match $this { + $($output)* + } + }; + + (@VisitVariants($this:expr, $visitor:expr) + input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @VisitVariants($this, $visitor) + input($($input)*) + output( + $variant ( $($variant_arg),* ) => { + false $(|| $crate::ty::fold::TypeFoldable::visit_with( + $variant_arg, $visitor + ))* + } + $($output)* + ) + ) + }; + + (@VisitVariants($this:expr, $visitor:expr) + input( ($variant:path) { $($variant_arg:ident),* $(,)* } , $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @VisitVariants($this, $visitor) + input($($input)*) + output( + $variant { $($variant_arg),* } => { + false $(|| $crate::ty::fold::TypeFoldable::visit_with( + $variant_arg, $visitor + ))* + } + $($output)* + ) + ) + }; + + (@VisitVariants($this:expr, $visitor:expr) + input( ($variant:path), $($input:tt)*) + output( $($output:tt)*) ) => { + EnumTypeFoldableImpl!( + @VisitVariants($this, $visitor) + input($($input)*) + output( + $variant => { false } + $($output)* + ) + ) + }; +} + diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 45cb70d00706..9b75c19a875e 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -76,3 +76,7 @@ fn calculate_predecessors(mir: &Mir) -> IndexVec> { result } + +CloneTypeFoldableAndLiftImpls! { + Cache, +} diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index e39765699f9b..939710ffd2b8 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2109,150 +2109,92 @@ pub enum ClosureOutlivesSubject<'tcx> { * TypeFoldable implementations for MIR types */ -impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - Mir { - basic_blocks: self.basic_blocks.fold_with(folder), - visibility_scopes: self.visibility_scopes.clone(), - visibility_scope_info: self.visibility_scope_info.clone(), - promoted: self.promoted.fold_with(folder), - yield_ty: self.yield_ty.fold_with(folder), - generator_drop: self.generator_drop.fold_with(folder), - generator_layout: self.generator_layout.fold_with(folder), - local_decls: self.local_decls.fold_with(folder), - arg_count: self.arg_count, - upvar_decls: self.upvar_decls.clone(), - spread_arg: self.spread_arg, - span: self.span, - cache: cache::Cache::new() - } - } +CloneTypeFoldableAndLiftImpls! { + Mutability, + SourceInfo, + UpvarDecl, + ValidationOp, + VisibilityScopeData, + VisibilityScope, + VisibilityScopeInfo, +} - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.basic_blocks.visit_with(visitor) || - self.generator_drop.visit_with(visitor) || - self.generator_layout.visit_with(visitor) || - self.yield_ty.visit_with(visitor) || - self.promoted.visit_with(visitor) || - self.local_decls.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> { + basic_blocks, + visibility_scopes, + visibility_scope_info, + promoted, + yield_ty, + generator_drop, + generator_layout, + local_decls, + arg_count, + upvar_decls, + spread_arg, + span, + cache, } } -impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - GeneratorLayout { - fields: self.fields.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.fields.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> { + fields } } -impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - LocalDecl { - ty: self.ty.fold_with(folder), - ..self.clone() - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.ty.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for LocalDecl<'tcx> { + mutability, + is_user_variable, + internal, + ty, + name, + source_info, + syntactic_scope, } } -impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - BasicBlockData { - statements: self.statements.fold_with(folder), - terminator: self.terminator.fold_with(folder), - is_cleanup: self.is_cleanup - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.statements.visit_with(visitor) || self.terminator.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for BasicBlockData<'tcx> { + statements, + terminator, + is_cleanup, } } -impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ValidationOperand { - place: self.place.fold_with(folder), - ty: self.ty.fold_with(folder), - re: self.re, - mutbl: self.mutbl, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.place.visit_with(visitor) || self.ty.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ValidationOperand<'tcx, Place<'tcx>> { + place, ty, re, mutbl } } -impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use mir::StatementKind::*; - - let kind = match self.kind { - Assign(ref place, ref rval) => Assign(place.fold_with(folder), rval.fold_with(folder)), - SetDiscriminant { ref place, variant_index } => SetDiscriminant { - place: place.fold_with(folder), - variant_index, - }, - StorageLive(ref local) => StorageLive(local.fold_with(folder)), - StorageDead(ref local) => StorageDead(local.fold_with(folder)), - InlineAsm { ref asm, ref outputs, ref inputs } => InlineAsm { - asm: asm.clone(), - outputs: outputs.fold_with(folder), - inputs: inputs.fold_with(folder) - }, - - // Note for future: If we want to expose the region scopes - // during the fold, we need to either generalize EndRegion - // to carry `[ty::Region]`, or extend the `TypeFolder` - // trait with a `fn fold_scope`. - EndRegion(ref region_scope) => EndRegion(region_scope.clone()), - - Validate(ref op, ref places) => - Validate(op.clone(), - places.iter().map(|operand| operand.fold_with(folder)).collect()), - - Nop => Nop, - }; - Statement { - source_info: self.source_info, - kind, - } +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> { + source_info, kind } +} - fn super_visit_with>(&self, visitor: &mut V) -> bool { - use mir::StatementKind::*; - - match self.kind { - Assign(ref place, ref rval) => { place.visit_with(visitor) || rval.visit_with(visitor) } - SetDiscriminant { ref place, .. } => place.visit_with(visitor), - StorageLive(ref local) | - StorageDead(ref local) => local.visit_with(visitor), - InlineAsm { ref outputs, ref inputs, .. } => - outputs.visit_with(visitor) || inputs.visit_with(visitor), - - // Note for future: If we want to expose the region scopes - // during the visit, we need to either generalize EndRegion - // to carry `[ty::Region]`, or extend the `TypeVisitor` - // trait with a `fn visit_scope`. - EndRegion(ref _scope) => false, - - Validate(ref _op, ref places) => - places.iter().any(|ty_and_place| ty_and_place.visit_with(visitor)), - - Nop => false, - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> { + (StatementKind::Assign)(a, b), + (StatementKind::SetDiscriminant) { place, variant_index }, + (StatementKind::StorageLive)(a), + (StatementKind::StorageDead)(a), + (StatementKind::InlineAsm) { asm, outputs, inputs }, + (StatementKind::Validate)(a, b), + (StatementKind::EndRegion)(a), + (StatementKind::Nop), } } +EnumTypeFoldableImpl! { + impl<'tcx, T> TypeFoldable<'tcx> for ClearCrossCrate { + (ClearCrossCrate::Clear), + (ClearCrossCrate::Set)(a), + } where T: TypeFoldable<'tcx> +} + impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { use mir::TerminatorKind::*; diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 7d232ac20bfd..d779ccd17360 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -16,7 +16,6 @@ use mir::*; use ty::subst::{Subst, Substs}; use ty::{self, AdtDef, Ty, TyCtxt}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use hir; use ty::util::IntTypeExt; @@ -100,25 +99,10 @@ impl<'a, 'gcx, 'tcx> PlaceTy<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - PlaceTy::Ty { ty } => PlaceTy::Ty { ty: ty.fold_with(folder) }, - PlaceTy::Downcast { adt_def, substs, variant_index } => { - PlaceTy::Downcast { - adt_def, - substs: substs.fold_with(folder), - variant_index, - } - } - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - PlaceTy::Ty { ty } => ty.visit_with(visitor), - PlaceTy::Downcast { substs, .. } => substs.visit_with(visitor) - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for PlaceTy<'tcx> { + (PlaceTy::Ty) { ty }, + (PlaceTy::Downcast) { adt_def, substs, variant_index }, } } diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 9dd5aaee7b72..99adc1fc873d 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -363,258 +363,67 @@ impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx } } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::VtableImplData { - impl_def_id: self.impl_def_id, - substs: self.substs.fold_with(folder), - nested: self.nested.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.substs.visit_with(visitor) || self.nested.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> { + impl_def_id, substs, nested + } where N: TypeFoldable<'tcx> } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::VtableGeneratorData { - closure_def_id: self.closure_def_id, - substs: self.substs.fold_with(folder), - nested: self.nested.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.substs.visit_with(visitor) || self.nested.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> { + closure_def_id, substs, nested + } where N: TypeFoldable<'tcx> } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::VtableClosureData { - closure_def_id: self.closure_def_id, - substs: self.substs.fold_with(folder), - nested: self.nested.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.substs.visit_with(visitor) || self.nested.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> { + closure_def_id, substs, nested + } where N: TypeFoldable<'tcx> } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::VtableAutoImplData { - trait_def_id: self.trait_def_id, - nested: self.nested.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.nested.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableAutoImplData { + trait_def_id, nested + } where N: TypeFoldable<'tcx> } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::VtableBuiltinData { - nested: self.nested.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.nested.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableBuiltinData { + nested + } where N: TypeFoldable<'tcx> } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::VtableObjectData { - upcast_trait_ref: self.upcast_trait_ref.fold_with(folder), - vtable_base: self.vtable_base, - nested: self.nested.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> { + upcast_trait_ref, vtable_base, nested + } where N: TypeFoldable<'tcx> } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::VtableFnPointerData { - fn_ty: self.fn_ty.fold_with(folder), - nested: self.nested.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> { + fn_ty, + nested + } where N: TypeFoldable<'tcx> } -impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)), - traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)), - traits::VtableGenerator(ref d) => { - traits::VtableGenerator(d.fold_with(folder)) - } - traits::VtableClosure(ref d) => { - traits::VtableClosure(d.fold_with(folder)) - } - traits::VtableFnPointer(ref d) => { - traits::VtableFnPointer(d.fold_with(folder)) - } - traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)), - traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)), - traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - traits::VtableImpl(ref v) => v.visit_with(visitor), - traits::VtableAutoImpl(ref t) => t.visit_with(visitor), - traits::VtableGenerator(ref d) => d.visit_with(visitor), - traits::VtableClosure(ref d) => d.visit_with(visitor), - traits::VtableFnPointer(ref d) => d.visit_with(visitor), - traits::VtableParam(ref n) => n.visit_with(visitor), - traits::VtableBuiltin(ref d) => d.visit_with(visitor), - traits::VtableObject(ref d) => d.visit_with(visitor), - } - } +EnumTypeFoldableImpl! { + impl<'tcx, N> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> { + (traits::VtableImpl)(a), + (traits::VtableAutoImpl)(a), + (traits::VtableGenerator)(a), + (traits::VtableClosure)(a), + (traits::VtableFnPointer)(a), + (traits::VtableParam)(a), + (traits::VtableBuiltin)(a), + (traits::VtableObject)(a), + } where N: TypeFoldable<'tcx> } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - Normalized { - value: self.value.fold_with(folder), - obligations: self.obligations.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.value.visit_with(visitor) || self.obligations.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, T> TypeFoldable<'tcx> for Normalized<'tcx, T> { + value, + obligations + } where T: TypeFoldable<'tcx> } -impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - super::ExprAssignable | - super::MatchExpressionArm { arm_span: _, source: _ } | - super::IfExpression | - super::IfExpressionWithNoElse | - super::MainFunctionType | - super::StartFunctionType | - super::IntrinsicType | - super::MethodReceiver | - super::MiscObligation | - super::SliceOrArrayElem | - super::TupleElem | - super::ItemObligation(_) | - super::AssignmentLhsSized | - super::TupleInitializerSized | - super::StructInitializerSized | - super::VariableType(_) | - super::ReturnType(_) | - super::SizedReturnType | - super::SizedYieldType | - super::ReturnNoExpression | - super::RepeatVec | - super::FieldSized(_) | - super::ConstSized | - super::SharedStatic | - super::BlockTailExpression(_) | - super::CompareImplMethodObligation { .. } => self.clone(), - super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)), - super::ReferenceOutlivesReferent(ty) => { - super::ReferenceOutlivesReferent(ty.fold_with(folder)) - } - super::ObjectTypeBound(ty, r) => { - super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder)) - } - super::ObjectCastObligation(ty) => { - super::ObjectCastObligation(ty.fold_with(folder)) - } - super::BuiltinDerivedObligation(ref cause) => { - super::BuiltinDerivedObligation(cause.fold_with(folder)) - } - super::ImplDerivedObligation(ref cause) => { - super::ImplDerivedObligation(cause.fold_with(folder)) - } - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - super::ExprAssignable | - super::MatchExpressionArm { arm_span: _, source: _ } | - super::IfExpression | - super::IfExpressionWithNoElse | - super::MainFunctionType | - super::StartFunctionType | - super::IntrinsicType | - super::MethodReceiver | - super::MiscObligation | - super::SliceOrArrayElem | - super::TupleElem | - super::ItemObligation(_) | - super::AssignmentLhsSized | - super::TupleInitializerSized | - super::StructInitializerSized | - super::VariableType(_) | - super::ReturnType(_) | - super::SizedReturnType | - super::SizedYieldType | - super::ReturnNoExpression | - super::RepeatVec | - super::FieldSized(_) | - super::ConstSized | - super::SharedStatic | - super::BlockTailExpression(_) | - super::CompareImplMethodObligation { .. } => false, - - super::ProjectionWf(proj) => proj.visit_with(visitor), - super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor), - super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor), - super::ObjectCastObligation(ty) => ty.visit_with(visitor), - super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor), - super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor) - } - } -} - -impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::DerivedObligationCause { - parent_trait_ref: self.parent_trait_ref.fold_with(folder), - parent_code: self.parent_code.fold_with(folder) - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor) - } -} - -impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - traits::ObligationCause { - span: self.span, - body_id: self.body_id, - code: self.code.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.code.visit_with(visitor) - } -} diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 4cc7406af721..8071cd0c639d 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -49,6 +49,9 @@ use util::nodemap::FxHashSet; /// The TypeFoldable trait is implemented for every type that can be folded. /// Basically, every type that has a corresponding method in TypeFolder. +/// +/// To implement this conveniently, use the +/// `BraceStructTypeFoldableImpl` etc macros found in `macros.rs`. pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self; fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index bae1ce31a5e7..0ca2769aa17b 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -18,7 +18,6 @@ use middle::const_val::ConstVal; use traits::Reveal; use ty::subst::{UnpackedKind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; -use ty::fold::{TypeVisitor, TypeFolder}; use ty::error::{ExpectedFound, TypeError}; use mir::interpret::{GlobalId, Value, PrimVal}; use util::common::ErrorReported; @@ -326,13 +325,9 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> { #[derive(Debug, Clone)] struct GeneratorWitness<'tcx>(&'tcx ty::Slice>); -impl<'tcx> TypeFoldable<'tcx> for GeneratorWitness<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - GeneratorWitness(self.0.fold_with(folder)) - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.0.visit_with(visitor) +TupleStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for GeneratorWitness<'tcx> { + a } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 78fccaa11310..0627bcdfb0ec 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -28,153 +28,37 @@ use std::rc::Rc; // For things that don't carry any arena-allocated data (and are // copy...), just add them to this list. -macro_rules! CopyImpls { - ($($ty:ty,)+) => { - $( - impl<'tcx> Lift<'tcx> for $ty { - type Lifted = Self; - fn lift_to_tcx<'a, 'gcx>(&self, _: TyCtxt<'a, 'gcx, 'tcx>) -> Option { - Some(*self) - } - } - - impl<'tcx> TypeFoldable<'tcx> for $ty { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> $ty { - *self - } - - fn super_visit_with>(&self, _: &mut F) -> bool { - false - } - } - )+ - } -} - -CopyImpls! { +CloneTypeFoldableAndLiftImpls! { (), + bool, + usize, + u64, + ::middle::region::Scope, + ::syntax::ast::FloatTy, + ::syntax::ast::NodeId, + ::syntax_pos::symbol::Symbol, + ::hir::def::Def, + ::hir::def_id::DefId, + ::hir::InlineAsm, + ::hir::MatchSource, + ::hir::Mutability, ::hir::Unsafety, ::syntax::abi::Abi, - ::hir::def_id::DefId, ::mir::Local, ::mir::Promoted, ::traits::Reveal, + ::ty::adjustment::AutoBorrowMutability, + ::ty::AdtKind, + // Including `BoundRegion` is a *bit* dubious, but direct + // references to bound region appear in `ty::Error`, and aren't + // really meant to be folded. In general, we can only fold a fully + // general `Region`. + ::ty::BoundRegion, + ::ty::ClosureKind, + ::ty::IntVarValue, ::syntax_pos::Span, } -/////////////////////////////////////////////////////////////////////////// -// Macros -// -// When possible, use one of these (relatively) convenient macros to write -// the impls for you. - -#[macro_export] -macro_rules! BraceStructLiftImpl { - (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path { - type Lifted = $lifted:ty; - $($field:ident),* $(,)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::Lift<$tcx> for $s - $(where $($wc)*)* - { - type Lifted = $lifted; - - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> { - $(let $field = tcx.lift(&self.$field)?;)* - Some(Self::Lifted { $($field),* }) - } - } - }; -} - -#[macro_export] -macro_rules! EnumLiftImpl { - (impl<$($p:tt),*> Lift<$tcx:tt> for $s:path { - type Lifted = $lifted:ty; - $( - ($variant:path) ( $( $variant_arg:ident),* ) - ),* - $(,)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::Lift<$tcx> for $s - $(where $($wc)*)* - { - type Lifted = $lifted; - - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<$lifted> { - match self { - $($variant ( $($variant_arg),* ) => { - Some($variant ( $(tcx.lift($variant_arg)?),* )) - })* - } - } - } - }; -} - -#[macro_export] -macro_rules! BraceStructTypeFoldableImpl { - (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { - $($field:ident),* $(,)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s - $(where $($wc)*)* - { - fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>( - &self, - folder: &mut V, - ) -> Self { - let $s { $($field,)* } = self; - $s { $($field: $field.fold_with(folder),)* } - } - - fn super_visit_with>( - &self, - visitor: &mut V, - ) -> bool { - let $s { $($field,)* } = self; - false $(|| $field.visit_with(visitor))* - } - } - }; -} - -#[macro_export] -macro_rules! EnumTypeFoldableImpl { - (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { - $( - ($variant:path) ( $( $variant_arg:ident),* ) - ),* - $(,)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s - $(where $($wc)*)* - { - fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>( - &self, - folder: &mut V, - ) -> Self { - match self { - $($variant ( $($variant_arg),* ) => { - $variant ( $($variant_arg.fold_with(folder)),* ) - })* - } - } - - fn super_visit_with>( - &self, - visitor: &mut V, - ) -> bool { - match self { - $($variant ( $($variant_arg),* ) => { - false $(|| $variant_arg.visit_with(visitor))* - })* - } - } - } - }; -} - /////////////////////////////////////////////////////////////////////////// // Lift implementations @@ -776,6 +660,17 @@ BraceStructLiftImpl! { // can easily refactor the folding into the TypeFolder trait as // needed. +/// AdtDefs are basically the same as a DefId. +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { + *self + } + + fn super_visit_with>(&self, _visitor: &mut V) -> bool { + false + } +} + impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) { (self.0.fold_with(folder), self.1.fold_with(folder)) @@ -786,14 +681,11 @@ impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Option { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - self.as_ref().map(|t| t.fold_with(folder)) - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.iter().any(|t| t.visit_with(visitor)) - } +EnumTypeFoldableImpl! { + impl<'tcx, T> TypeFoldable<'tcx> for Option { + (Some)(a), + (None), + } where T: TypeFoldable<'tcx> } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc { @@ -881,22 +773,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice } } -impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use ty::ExistentialPredicate::*; - match *self { - Trait(ref tr) => Trait(tr.fold_with(folder)), - Projection(ref p) => Projection(p.fold_with(folder)), - AutoTrait(did) => AutoTrait(did), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - ty::ExistentialPredicate::Trait(ref tr) => tr.visit_with(visitor), - ty::ExistentialPredicate::Projection(ref p) => p.visit_with(visitor), - ty::ExistentialPredicate::AutoTrait(_) => false, - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::ExistentialPredicate<'tcx> { + (ty::ExistentialPredicate::Trait)(a), + (ty::ExistentialPredicate::Projection)(a), + (ty::ExistentialPredicate::AutoTrait)(a), } } @@ -1049,13 +930,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::TypeAndMut { ty: self.ty.fold_with(folder), mutbl: self.mutbl } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.ty.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> { + ty, mutbl } } @@ -1065,20 +942,9 @@ BraceStructTypeFoldableImpl! { } } -impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - let inputs_and_output = self.inputs_and_output.fold_with(folder); - ty::FnSig { - inputs_and_output: folder.tcx().intern_type_list(&inputs_and_output), - variadic: self.variadic, - unsafety: self.unsafety, - abi: self.abi, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.inputs().iter().any(|i| i.visit_with(visitor)) || - self.output().visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::FnSig<'tcx> { + inputs_and_output, variadic, unsafety, abi } } @@ -1117,28 +983,15 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::ClosureSubsts { - substs: self.substs.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.substs.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::ClosureSubsts<'tcx> { + substs, } } -impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::GeneratorInterior { - witness: self.witness.fold_with(folder), - movable: self.movable, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.witness.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> { + witness, movable, } } @@ -1149,74 +1002,32 @@ BraceStructTypeFoldableImpl! { } } -impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - ty::adjustment::Adjust::NeverToAny | - ty::adjustment::Adjust::ReifyFnPointer | - ty::adjustment::Adjust::UnsafeFnPointer | - ty::adjustment::Adjust::ClosureFnPointer | - ty::adjustment::Adjust::MutToConstPointer | - ty::adjustment::Adjust::Unsize => self.clone(), - ty::adjustment::Adjust::Deref(ref overloaded) => { - ty::adjustment::Adjust::Deref(overloaded.fold_with(folder)) - } - ty::adjustment::Adjust::Borrow(ref autoref) => { - ty::adjustment::Adjust::Borrow(autoref.fold_with(folder)) - } - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - ty::adjustment::Adjust::NeverToAny | - ty::adjustment::Adjust::ReifyFnPointer | - ty::adjustment::Adjust::UnsafeFnPointer | - ty::adjustment::Adjust::ClosureFnPointer | - ty::adjustment::Adjust::MutToConstPointer | - ty::adjustment::Adjust::Unsize => false, - ty::adjustment::Adjust::Deref(ref overloaded) => { - overloaded.visit_with(visitor) - } - ty::adjustment::Adjust::Borrow(ref autoref) => { - autoref.visit_with(visitor) - } - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::Adjust<'tcx> { + (ty::adjustment::Adjust::NeverToAny), + (ty::adjustment::Adjust::ReifyFnPointer), + (ty::adjustment::Adjust::UnsafeFnPointer), + (ty::adjustment::Adjust::ClosureFnPointer), + (ty::adjustment::Adjust::MutToConstPointer), + (ty::adjustment::Adjust::Unsize), + (ty::adjustment::Adjust::Deref)(a), + (ty::adjustment::Adjust::Borrow)(a), } } -impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::adjustment::OverloadedDeref { - region: self.region.fold_with(folder), - mutbl: self.mutbl, - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.region.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::OverloadedDeref<'tcx> { + region, mutbl, } } -impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - ty::adjustment::AutoBorrow::Ref(ref r, m) => { - ty::adjustment::AutoBorrow::Ref(r.fold_with(folder), m) - } - ty::adjustment::AutoBorrow::RawPtr(m) => ty::adjustment::AutoBorrow::RawPtr(m) - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - ty::adjustment::AutoBorrow::Ref(r, _m) => r.visit_with(visitor), - ty::adjustment::AutoBorrow::RawPtr(_m) => false, - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::adjustment::AutoBorrow<'tcx> { + (ty::adjustment::AutoBorrow::Ref)(a, b), + (ty::adjustment::AutoBorrow::RawPtr)(m), } } - BraceStructTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> { parent, predicates @@ -1234,43 +1045,17 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice> { } } -impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - ty::Predicate::Trait(ref a) => - ty::Predicate::Trait(a.fold_with(folder)), - ty::Predicate::Subtype(ref binder) => - ty::Predicate::Subtype(binder.fold_with(folder)), - ty::Predicate::RegionOutlives(ref binder) => - ty::Predicate::RegionOutlives(binder.fold_with(folder)), - ty::Predicate::TypeOutlives(ref binder) => - ty::Predicate::TypeOutlives(binder.fold_with(folder)), - ty::Predicate::Projection(ref binder) => - ty::Predicate::Projection(binder.fold_with(folder)), - ty::Predicate::WellFormed(data) => - ty::Predicate::WellFormed(data.fold_with(folder)), - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => - ty::Predicate::ClosureKind(closure_def_id, closure_substs.fold_with(folder), kind), - ty::Predicate::ObjectSafe(trait_def_id) => - ty::Predicate::ObjectSafe(trait_def_id), - ty::Predicate::ConstEvaluatable(def_id, substs) => - ty::Predicate::ConstEvaluatable(def_id, substs.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - ty::Predicate::Trait(ref a) => a.visit_with(visitor), - ty::Predicate::Subtype(ref binder) => binder.visit_with(visitor), - ty::Predicate::RegionOutlives(ref binder) => binder.visit_with(visitor), - ty::Predicate::TypeOutlives(ref binder) => binder.visit_with(visitor), - ty::Predicate::Projection(ref binder) => binder.visit_with(visitor), - ty::Predicate::WellFormed(data) => data.visit_with(visitor), - ty::Predicate::ClosureKind(_closure_def_id, closure_substs, _kind) => - closure_substs.visit_with(visitor), - ty::Predicate::ObjectSafe(_trait_def_id) => false, - ty::Predicate::ConstEvaluatable(_def_id, substs) => substs.visit_with(visitor), - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { + (ty::Predicate::Trait)(a), + (ty::Predicate::Subtype)(a), + (ty::Predicate::RegionOutlives)(a), + (ty::Predicate::TypeOutlives)(a), + (ty::Predicate::Projection)(a), + (ty::Predicate::WellFormed)(a), + (ty::Predicate::ClosureKind)(a, b, c), + (ty::Predicate::ObjectSafe)(a), + (ty::Predicate::ConstEvaluatable)(a, b), } } @@ -1298,71 +1083,40 @@ BraceStructTypeFoldableImpl! { } } -impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::SubtypePredicate { - a_is_expected: self.a_is_expected, - a: self.a.fold_with(folder), - b: self.b.fold_with(folder) - } - } +BraceStructTypeFoldableImpl! { + impl<'tcx, T> TypeFoldable<'tcx> for ty::ParamEnvAnd<'tcx, T> { + param_env, value + } where T: TypeFoldable<'tcx> +} - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.a.visit_with(visitor) || self.b.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::SubtypePredicate<'tcx> { + a_is_expected, a, b } } -impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::TraitPredicate { - trait_ref: self.trait_ref.fold_with(folder) - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.trait_ref.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> { + trait_ref } } -impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate - where T : TypeFoldable<'tcx>, - U : TypeFoldable<'tcx>, -{ - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::OutlivesPredicate(self.0.fold_with(folder), - self.1.fold_with(folder)) - } +TupleStructTypeFoldableImpl! { + impl<'tcx,T,U> TypeFoldable<'tcx> for ty::OutlivesPredicate { + a, b + } where T : TypeFoldable<'tcx>, U : TypeFoldable<'tcx>, +} - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.0.visit_with(visitor) || self.1.visit_with(visitor) +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { + def, span, ty } } -impl<'tcx> TypeFoldable<'tcx> for ty::ClosureUpvar<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::ClosureUpvar { - def: self.def, - span: self.span, - ty: self.ty.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.ty.visit_with(visitor) - } -} - -impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::error::ExpectedFound { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - ty::error::ExpectedFound { - expected: self.expected.fold_with(folder), - found: self.found.fold_with(folder), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - self.expected.visit_with(visitor) || self.found.visit_with(visitor) - } +BraceStructTypeFoldableImpl! { + impl<'tcx, T> TypeFoldable<'tcx> for ty::error::ExpectedFound { + expected, found + } where T: TypeFoldable<'tcx> } impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec { @@ -1375,69 +1129,28 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec } } -impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use ty::error::TypeError::*; - - match *self { - Mismatch => Mismatch, - UnsafetyMismatch(x) => UnsafetyMismatch(x.fold_with(folder)), - AbiMismatch(x) => AbiMismatch(x.fold_with(folder)), - Mutability => Mutability, - TupleSize(x) => TupleSize(x), - FixedArraySize(x) => FixedArraySize(x), - ArgCount => ArgCount, - RegionsDoesNotOutlive(a, b) => { - RegionsDoesNotOutlive(a.fold_with(folder), b.fold_with(folder)) - }, - RegionsInsufficientlyPolymorphic(a, b) => { - RegionsInsufficientlyPolymorphic(a, b.fold_with(folder)) - }, - RegionsOverlyPolymorphic(a, b) => { - RegionsOverlyPolymorphic(a, b.fold_with(folder)) - }, - IntMismatch(x) => IntMismatch(x), - FloatMismatch(x) => FloatMismatch(x), - Traits(x) => Traits(x), - VariadicMismatch(x) => VariadicMismatch(x), - CyclicTy(t) => CyclicTy(t.fold_with(folder)), - ProjectionMismatched(x) => ProjectionMismatched(x), - ProjectionBoundsLength(x) => ProjectionBoundsLength(x), - Sorts(x) => Sorts(x.fold_with(folder)), - ExistentialMismatch(x) => ExistentialMismatch(x.fold_with(folder)), - OldStyleLUB(ref x) => OldStyleLUB(x.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - use ty::error::TypeError::*; - - match *self { - UnsafetyMismatch(x) => x.visit_with(visitor), - AbiMismatch(x) => x.visit_with(visitor), - RegionsDoesNotOutlive(a, b) => { - a.visit_with(visitor) || b.visit_with(visitor) - }, - RegionsInsufficientlyPolymorphic(_, b) | - RegionsOverlyPolymorphic(_, b) => { - b.visit_with(visitor) - }, - Sorts(x) => x.visit_with(visitor), - OldStyleLUB(ref x) => x.visit_with(visitor), - ExistentialMismatch(x) => x.visit_with(visitor), - CyclicTy(t) => t.visit_with(visitor), - Mismatch | - Mutability | - TupleSize(_) | - FixedArraySize(_) | - ArgCount | - IntMismatch(_) | - FloatMismatch(_) | - Traits(_) | - VariadicMismatch(_) | - ProjectionMismatched(_) | - ProjectionBoundsLength(_) => false, - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> { + (ty::error::TypeError::Mismatch), + (ty::error::TypeError::UnsafetyMismatch)(x), + (ty::error::TypeError::AbiMismatch)(x), + (ty::error::TypeError::Mutability), + (ty::error::TypeError::TupleSize)(x), + (ty::error::TypeError::FixedArraySize)(x), + (ty::error::TypeError::ArgCount), + (ty::error::TypeError::RegionsDoesNotOutlive)(a, b), + (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b), + (ty::error::TypeError::RegionsOverlyPolymorphic)(a, b), + (ty::error::TypeError::IntMismatch)(x), + (ty::error::TypeError::FloatMismatch)(x), + (ty::error::TypeError::Traits)(x), + (ty::error::TypeError::VariadicMismatch)(x), + (ty::error::TypeError::CyclicTy)(t), + (ty::error::TypeError::ProjectionMismatched)(x), + (ty::error::TypeError::ProjectionBoundsLength)(x), + (ty::error::TypeError::Sorts)(x), + (ty::error::TypeError::ExistentialMismatch)(x), + (ty::error::TypeError::OldStyleLUB)(x), } } From 5ddcd09b53989f0a3c3fcefa5ba3ee9d40e60064 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Feb 2018 10:39:46 -0500 Subject: [PATCH 136/830] add `TypeRelation` and `Lift` impls for `Kind` --- src/librustc/ty/relate.rs | 33 +++++++++++++++++++++++---------- src/librustc/ty/subst.rs | 13 ++++++++++++- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 0ca2769aa17b..7f48f8c431fa 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -16,7 +16,7 @@ use hir::def_id::DefId; use middle::const_val::ConstVal; use traits::Reveal; -use ty::subst::{UnpackedKind, Substs}; +use ty::subst::{Kind, UnpackedKind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; use mir::interpret::{GlobalId, Value, PrimVal}; @@ -142,15 +142,7 @@ pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R, let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| { let variance = variances.map_or(ty::Invariant, |v| v[i]); - match (a.unpack(), b.unpack()) { - (UnpackedKind::Lifetime(a_lt), UnpackedKind::Lifetime(b_lt)) => { - Ok(relation.relate_with_variance(variance, &a_lt, &b_lt)?.into()) - } - (UnpackedKind::Type(a_ty), UnpackedKind::Type(b_ty)) => { - Ok(relation.relate_with_variance(variance, &a_ty, &b_ty)?.into()) - } - (UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => bug!() - } + relation.relate_with_variance(variance, a, b) }); Ok(tcx.mk_substs(params)?) @@ -693,6 +685,27 @@ impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Box { } } +impl<'tcx> Relate<'tcx> for Kind<'tcx> { + fn relate<'a, 'gcx, R>( + relation: &mut R, + a: &Kind<'tcx>, + b: &Kind<'tcx> + ) -> RelateResult<'tcx, Kind<'tcx>> + where + R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a, + { + match (a.unpack(), b.unpack()) { + (UnpackedKind::Lifetime(a_lt), UnpackedKind::Lifetime(b_lt)) => { + Ok(relation.relate(&a_lt, &b_lt)?.into()) + } + (UnpackedKind::Type(a_ty), UnpackedKind::Type(b_ty)) => { + Ok(relation.relate(&a_ty, &b_ty)?.into()) + } + (UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => bug!() + } + } +} + /////////////////////////////////////////////////////////////////////////// // Error handling diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 5e3417e98c2e..e70c72335aa3 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -11,7 +11,7 @@ // Type substitutions. use hir::def_id::DefId; -use ty::{self, Slice, Region, Ty, TyCtxt}; +use ty::{self, Lift, Slice, Region, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use serialize::{self, Encodable, Encoder, Decodable, Decoder}; @@ -113,6 +113,17 @@ impl<'tcx> fmt::Display for Kind<'tcx> { } } +impl<'a, 'tcx> Lift<'tcx> for Kind<'a> { + type Lifted = Kind<'tcx>; + + fn lift_to_tcx<'cx, 'gcx>(&self, tcx: TyCtxt<'cx, 'gcx, 'tcx>) -> Option { + match self.unpack() { + UnpackedKind::Lifetime(a) => a.lift_to_tcx(tcx).map(|a| a.into()), + UnpackedKind::Type(a) => a.lift_to_tcx(tcx).map(|a| a.into()), + } + } +} + impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match self.unpack() { From 10ae216b7516af352fbb477875887b085f731aad Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Feb 2018 11:24:18 -0500 Subject: [PATCH 137/830] fix typo in comment --- src/librustc/infer/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index b94f1819c7dd..d5afd6e9d3ea 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1246,7 +1246,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // it can be resolved to an int/float variable, which // can then be recursively resolved, hence the // recursion. Note though that we prevent type - // variables from unifying to other type variables + // variables from unifyxing to other type variables // directly (though they may be embedded // structurally), and we prevent cycles in any case, // so this recursion should always be of very limited From d0aff859d55766e132f3bbdd67e3d38a1d95e80a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Feb 2018 10:43:15 -0500 Subject: [PATCH 138/830] make regions "traceable" so you can do `infcx.at(..).eq(r1, r2)` --- src/librustc/infer/at.rs | 14 +++++++++++ src/librustc/infer/error_reporting/mod.rs | 1 + src/librustc/infer/mod.rs | 30 ++++++----------------- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs index 3fd7ee276729..d9fbf4aa5148 100644 --- a/src/librustc/infer/at.rs +++ b/src/librustc/infer/at.rs @@ -281,6 +281,20 @@ impl<'tcx> ToTrace<'tcx> for Ty<'tcx> { } } +impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self) + -> TypeTrace<'tcx> + { + TypeTrace { + cause: cause.clone(), + values: Regions(ExpectedFound::new(a_is_expected, a, b)) + } + } +} + impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a_is_expected: bool, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 52caf46878b1..07551c4ebd31 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -975,6 +975,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> { match *values { infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found), + infer::Regions(ref exp_found) => self.expected_found_str(exp_found), infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found), infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found), } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index d5afd6e9d3ea..d952e430f619 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -26,7 +26,7 @@ use ty::subst::Substs; use ty::{TyVid, IntVid, FloatVid}; use ty::{self, Ty, TyCtxt}; use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; -use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use ty::fold::TypeFoldable; use ty::relate::RelateResult; use traits::{self, ObligationCause, PredicateObligations, Reveal}; use rustc_data_structures::unify as ut; @@ -191,6 +191,7 @@ pub type SkolemizationMap<'tcx> = BTreeMap>; #[derive(Clone, Debug)] pub enum ValuePairs<'tcx> { Types(ExpectedFound>), + Regions(ExpectedFound>), TraitRefs(ExpectedFound>), PolyTraitRefs(ExpectedFound>), } @@ -1623,27 +1624,12 @@ impl RegionVariableOrigin { } } -impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - match *self { - ValuePairs::Types(ref ef) => { - ValuePairs::Types(ef.fold_with(folder)) - } - ValuePairs::TraitRefs(ref ef) => { - ValuePairs::TraitRefs(ef.fold_with(folder)) - } - ValuePairs::PolyTraitRefs(ref ef) => { - ValuePairs::PolyTraitRefs(ef.fold_with(folder)) - } - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - match *self { - ValuePairs::Types(ref ef) => ef.visit_with(visitor), - ValuePairs::TraitRefs(ref ef) => ef.visit_with(visitor), - ValuePairs::PolyTraitRefs(ref ef) => ef.visit_with(visitor), - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> { + (ValuePairs::Types)(a), + (ValuePairs::Regions)(a), + (ValuePairs::TraitRefs)(a), + (ValuePairs::PolyTraitRefs)(a), } } From 0037cca2f79c63143e3849ec84eebdaf4b451712 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Feb 2018 10:43:36 -0500 Subject: [PATCH 139/830] comment the purpose of `TransNormalize` --- src/librustc/infer/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index d952e430f619..713cf5608515 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -487,6 +487,10 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> { /// Helper trait for shortening the lifetimes inside a /// value for post-type-checking normalization. +/// +/// This trait offers a normalization method where the inputs and +/// outputs both have the `'gcx` lifetime; the implementations +/// internally create inference contexts and/or lift as needed. pub trait TransNormalize<'gcx>: TypeFoldable<'gcx> { fn trans_normalize<'a, 'tcx>(&self, infcx: &InferCtxt<'a, 'gcx, 'tcx>, From 652b3b71f30eb6657bc63d351570dc7ff3b78eb0 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Feb 2018 04:16:25 -0500 Subject: [PATCH 140/830] random reformatting --- .../borrow_check/nll/type_check/liveness.rs | 10 +++----- .../borrow_check/nll/type_check/mod.rs | 23 +++++++++++-------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs index a50b99937475..5b3f439e0ebb 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs @@ -105,8 +105,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo for live_local in live_locals { debug!( "add_liveness_constraints: location={:?} live_local={:?}", - location, - live_local + location, live_local ); self.flow_inits.each_state_bit(|mpi_init| { @@ -157,8 +156,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo { debug!( "push_type_live_constraint(live_ty={:?}, location={:?})", - value, - location + value, location ); self.tcx.for_each_free_region(&value, |live_region| { @@ -182,9 +180,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo ) { debug!( "add_drop_live_constraint(dropped_local={:?}, dropped_ty={:?}, location={:?})", - dropped_local, - dropped_ty, - location + dropped_local, dropped_ty, location ); // If we end visiting the same type twice (usually due to a cycle involving diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 36e173dd5d64..c474cabdb3c5 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -243,8 +243,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { fn sanitize_constant(&mut self, constant: &Constant<'tcx>, location: Location) { debug!( "sanitize_constant(constant={:?}, location={:?})", - constant, - location + constant, location ); let expected_ty = match constant.literal { @@ -678,8 +677,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { let data = self.infcx.take_and_reset_region_constraints(); if !data.is_empty() { - debug!("fully_perform_op: constraints generated at {:?} are {:#?}", - locations, data); + debug!( + "fully_perform_op: constraints generated at {:?} are {:#?}", + locations, data + ); self.constraints .outlives_sets .push(OutlivesSet { locations, data }); @@ -1137,12 +1138,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } TerminatorKind::FalseUnwind { real_target, - unwind + unwind, } => { self.assert_iscleanup(mir, block_data, real_target, is_cleanup); if let Some(unwind) = unwind { if is_cleanup { - span_mirbug!(self, block_data, "cleanup in cleanup block via false unwind"); + span_mirbug!( + self, + block_data, + "cleanup in cleanup block via false unwind" + ); } self.assert_iscleanup(mir, block_data, unwind, true); } @@ -1435,8 +1440,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { debug!( "prove_aggregate_predicates(aggregate_kind={:?}, location={:?})", - aggregate_kind, - location + aggregate_kind, location ); let instantiated_predicates = match aggregate_kind { @@ -1502,8 +1506,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { fn prove_predicates(&mut self, predicates: &[ty::Predicate<'tcx>], location: Location) { debug!( "prove_predicates(predicates={:?}, location={:?})", - predicates, - location + predicates, location ); self.fully_perform_op(location.at_self(), |this| { let cause = this.misc(this.last_span); From 1d377d10a1c86152a49b46f446557c150fda655d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 20 Feb 2018 10:36:29 -0500 Subject: [PATCH 141/830] add handy helper for Cell, used for perf stats --- src/librustc/util/common.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index e1ae41f24721..96b77d351e24 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -373,3 +373,13 @@ fn test_to_readable_str() { assert_eq!("1_000_000", to_readable_str(1_000_000)); assert_eq!("1_234_567", to_readable_str(1_234_567)); } + +pub trait CellUsizeExt { + fn increment(&self); +} + +impl CellUsizeExt for Cell { + fn increment(&self) { + self.set(self.get() + 1); + } +} From 6d0f9319dfd4a115f64fd5e00be3749da5eda8bc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 10 Feb 2018 13:18:02 -0500 Subject: [PATCH 142/830] refactor `ParamEnv::empty(Reveal)` into two distinct methods - `ParamEnv::empty()` -- does not reveal all, good for typeck - `ParamEnv::reveal_all()` -- does, good for trans - `param_env.with_reveal_all()` -- converts an existing parameter environment --- src/librustc/infer/mod.rs | 6 ++--- src/librustc/lint/context.rs | 3 +-- src/librustc/traits/coherence.rs | 4 +-- src/librustc/traits/error_reporting.rs | 3 +-- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/select.rs | 2 +- src/librustc/traits/specialize/mod.rs | 4 +-- src/librustc/traits/structural_impls.rs | 2 -- src/librustc/ty/instance.rs | 2 +- src/librustc/ty/layout.rs | 8 +++--- src/librustc/ty/mod.rs | 4 +-- src/librustc/ty/relate.rs | 3 +-- src/librustc/ty/util.rs | 26 +++++++++++++++++--- src/librustc_driver/test.rs | 4 +-- src/librustc_lint/builtin.rs | 4 +-- src/librustc_mir/interpret/eval_context.rs | 3 +-- src/librustc_mir/monomorphize/collector.rs | 17 ++++++------- src/librustc_mir/monomorphize/mod.rs | 4 +-- src/librustc_mir/transform/qualify_consts.rs | 4 +-- src/librustc_passes/rvalue_promotion.rs | 3 +-- src/librustc_trans/callee.rs | 3 +-- src/librustc_trans/common.rs | 7 +++--- src/librustc_trans/context.rs | 5 ++-- src/librustc_trans/mir/block.rs | 3 +-- src/librustc_trans/mir/constant.rs | 9 +++---- src/librustc_typeck/check/compare_method.rs | 4 +-- src/librustc_typeck/check/dropck.rs | 4 +-- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/lib.rs | 4 +-- 29 files changed, 77 insertions(+), 72 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 713cf5608515..5f0c2d1e76bc 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -28,7 +28,7 @@ use ty::{self, Ty, TyCtxt}; use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use ty::fold::TypeFoldable; use ty::relate::RelateResult; -use traits::{self, ObligationCause, PredicateObligations, Reveal}; +use traits::{self, ObligationCause, PredicateObligations}; use rustc_data_structures::unify as ut; use std::cell::{Cell, RefCell, Ref, RefMut}; use std::collections::BTreeMap; @@ -563,7 +563,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { { debug!("fully_normalize_associated_types_in(t={:?})", value); - let param_env = ty::ParamEnv::empty(Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); let value = self.erase_regions(value); if !value.has_projections() { @@ -593,7 +593,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } self.infer_ctxt().enter(|infcx| { - value.trans_normalize(&infcx, env.reveal_all()) + value.trans_normalize(&infcx, env.with_reveal_all()) }) } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index a1381817223f..4fa6594df169 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -34,7 +34,6 @@ use lint::levels::{LintLevelSets, LintLevelsBuilder}; use middle::privacy::AccessLevels; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use session::{config, early_error, Session}; -use traits::Reveal; use ty::{self, TyCtxt, Ty}; use ty::layout::{LayoutError, LayoutOf, TyLayout}; use util::nodemap::FxHashMap; @@ -1055,7 +1054,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut cx = LateContext { tcx, tables: &ty::TypeckTables::empty(None), - param_env: ty::ParamEnv::empty(Reveal::UserFacing), + param_env: ty::ParamEnv::empty(), access_levels, lint_sess: LintSession::new(&tcx.sess.lint_store), last_ast_node_with_lint_attrs: ast::CRATE_NODE_ID, diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 183b1a5470e5..06926b1648df 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -16,7 +16,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use syntax_pos::DUMMY_SP; -use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause, Reveal}; +use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause}; use traits::IntercrateMode; use traits::select::IntercrateAmbiguityCause; use ty::{self, Ty, TyCtxt}; @@ -125,7 +125,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, // types into scope; instead, we replace the generic types with // fresh type variables, and hence we do our evaluations in an // empty environment. - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); let a_impl_header = with_fresh_ty_vars(selcx, param_env, a_def_id); let b_impl_header = with_fresh_ty_vars(selcx, param_env, b_def_id); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index cd2d0d7e2a04..b8455b97fa41 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -21,7 +21,6 @@ use super::{ TraitNotObjectSafe, ConstEvalFailure, PredicateObligation, - Reveal, SelectionContext, SelectionError, ObjectSafetyViolation, @@ -140,7 +139,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // FIXME: I'm just not taking associated types at all here. // Eventually I'll need to implement param-env-aware // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); if let Ok(_) = self.can_sub(param_env, error, implication) { debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); return true diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index e0e85600b903..4450c60b68d3 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -695,7 +695,7 @@ fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, predicates); let result = tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::empty(Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); let mut selcx = SelectionContext::new(&infcx); let mut fulfill_cx = FulfillmentContext::new(); let cause = ObligationCause::dummy(); diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 91d86394b019..728702ef61fd 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -777,7 +777,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // value in order to work, so we can clear out the param env and get better // caching. (If the current param env is inconsistent, we don't care what happens). debug!("evaluate_trait_predicate_recursively({:?}) - in global", obligation); - obligation.param_env = ty::ParamEnv::empty(obligation.param_env.reveal); + obligation.param_env = obligation.param_env.without_caller_bounds(); } let stack = self.push_stack(previous_stack, &obligation); diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index d11565618a68..5ea089abb8e8 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -26,7 +26,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use hir::def_id::DefId; use infer::{InferCtxt, InferOk}; use ty::subst::{Subst, Substs}; -use traits::{self, Reveal, ObligationCause}; +use traits::{self, ObligationCause}; use traits::select::IntercrateAmbiguityCause; use ty::{self, TyCtxt, TypeFoldable}; use syntax_pos::DUMMY_SP; @@ -132,7 +132,7 @@ pub fn find_associated_item<'a, 'tcx>( match ancestors.defs(tcx, item.name, item.kind, trait_def_id).next() { Some(node_item) => { let substs = tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::empty(Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs); let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id, substs, node_item.node); diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 99adc1fc873d..a2d98a456f49 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -425,5 +425,3 @@ BraceStructTypeFoldableImpl! { obligations } where T: TypeFoldable<'tcx> } - - diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 614158bafa63..ebb058c5d292 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -199,7 +199,7 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { _ => { if Some(def_id) == tcx.lang_items().drop_in_place_fn() { let ty = substs.type_at(0); - if ty.needs_drop(tcx, ty::ParamEnv::empty(traits::Reveal::All)) { + if ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) { debug!(" => nontrivial drop glue"); ty::InstanceDef::DropGlue(def_id, Some(ty)) } else { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 1b919ad68d04..9ce232ba1730 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2058,7 +2058,7 @@ impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - let param_env = self.param_env.reveal_all(); + let param_env = self.param_env.with_reveal_all(); let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env); let details = self.tcx.layout_raw(param_env.and(ty))?; let layout = TyLayout { @@ -2084,9 +2084,9 @@ impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx /// Computes the layout of a type. Note that this implicitly /// executes in "reveal all" mode. fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - let param_env = self.param_env.reveal_all(); - let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all()); - let details = self.tcx.layout_raw(param_env.reveal_all().and(ty))?; + let param_env = self.param_env.with_reveal_all(); + let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env); + let details = self.tcx.layout_raw(param_env.and(ty))?; let layout = TyLayout { ty, details diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 63494438f7d8..40d7aa9556df 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1420,7 +1420,7 @@ impl<'tcx> ParamEnv<'tcx> { } } else { ParamEnvAnd { - param_env: ParamEnv::empty(self.reveal), + param_env: self.without_caller_bounds(), value, } } @@ -1829,7 +1829,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { tcx: TyCtxt<'a, 'gcx, 'tcx>, expr_did: DefId, ) -> Option> { - let param_env = ParamEnv::empty(traits::Reveal::UserFacing); + let param_env = ParamEnv::empty(); let repr_type = self.repr.discr_type(); let bit_size = layout::Integer::from_attr(tcx, repr_type).size().bits(); let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 7f48f8c431fa..72e7d16b64dc 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -15,7 +15,6 @@ use hir::def_id::DefId; use middle::const_val::ConstVal; -use traits::Reveal; use ty::subst::{Kind, UnpackedKind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; @@ -473,7 +472,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, ConstVal::Value(Value::ByVal(prim)) => Ok(prim.to_u64().unwrap()), ConstVal::Unevaluated(def_id, substs) => { // FIXME(eddyb) get the right param_env. - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); match tcx.lift_to_global(&substs) { Some(substs) => { let instance = ty::Instance::resolve( diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index cbd9a1b8d4f9..ca6817d992b6 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -183,9 +183,22 @@ pub enum Representability { impl<'tcx> ty::ParamEnv<'tcx> { /// Construct a trait environment suitable for contexts where - /// there are no where clauses in scope. - pub fn empty(reveal: Reveal) -> Self { - Self::new(ty::Slice::empty(), reveal, ty::UniverseIndex::ROOT) + /// there are no where clauses in scope. Hidden types (like `impl + /// Trait`) are left hidden, so this is suitable for ordinary + /// type-checking. + pub fn empty() -> Self { + Self::new(ty::Slice::empty(), Reveal::UserFacing, ty::UniverseIndex::ROOT) + } + + /// Construct a trait environment with no where clauses in scope + /// where the values of all `impl Trait` and other hidden types + /// are revealed. This is suitable for monomorphized, post-typeck + /// environments like trans or doing optimizations. + /// + /// NB. If you want to have predicates in scope, use `ParamEnv::new`, + /// or invoke `param_env.with_reveal_all()`. + pub fn reveal_all() -> Self { + Self::new(ty::Slice::empty(), Reveal::All, ty::UniverseIndex::ROOT) } /// Construct a trait environment with the given set of predicates. @@ -202,10 +215,15 @@ impl<'tcx> ty::ParamEnv<'tcx> { /// the desired behavior during trans and certain other special /// contexts; normally though we want to use `Reveal::UserFacing`, /// which is the default. - pub fn reveal_all(self) -> Self { + pub fn with_reveal_all(self) -> Self { ty::ParamEnv { reveal: Reveal::All, ..self } } + /// Returns this same environment but with no caller bounds. + pub fn without_caller_bounds(self) -> Self { + ty::ParamEnv { caller_bounds: ty::Slice::empty(), ..self } + } + pub fn can_type_implement_copy<'a>(self, tcx: TyCtxt<'a, 'tcx, 'tcx>, self_type: Ty<'tcx>, span: Span) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index becdbb54e5be..06610609ebdb 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -18,7 +18,7 @@ use rustc_lint; use rustc_resolve::MakeGlobMap; use rustc::middle::region; use rustc::ty::subst::Subst; -use rustc::traits::{ObligationCause, Reveal}; +use rustc::traits::ObligationCause; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::maps::OnDiskCache; use rustc::infer::{self, InferOk, InferResult}; @@ -153,7 +153,7 @@ fn test_env(source_string: &str, |tcx| { tcx.infer_ctxt().enter(|infcx| { let mut region_scope_tree = region::ScopeTree::default(); - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); body(Env { infcx: &infcx, region_scope_tree: &mut region_scope_tree, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c6698cbd0068..031033f7208e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -33,7 +33,7 @@ use rustc::hir::def_id::DefId; use rustc::cfg; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty}; -use rustc::traits::{self, Reveal}; +use rustc::traits; use rustc::hir::map as hir_map; use util::nodemap::NodeSet; use lint::{LateContext, LintContext, LintArray}; @@ -525,7 +525,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingCopyImplementations { if def.has_dtor(cx.tcx) { return; } - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); if !ty.moves_by_default(cx.tcx, param_env, item.span) { return; } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 13090ca53302..d766ea3e2bd0 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -949,8 +949,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> { let param_env = if self.tcx.is_static(gid.instance.def_id()).is_some() { - use rustc::traits; - ty::ParamEnv::empty(traits::Reveal::All) + ty::ParamEnv::reveal_all() } else { self.param_env }; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index f6b47efca31c..561500a3f3c5 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -196,7 +196,6 @@ use rustc::hir::def_id::DefId; use rustc::middle::const_val::ConstVal; use rustc::mir::interpret::{Value, PrimVal, AllocId, Pointer}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; -use rustc::traits; use rustc::ty::subst::{Substs, Kind}; use rustc::ty::{self, TypeFoldable, Ty, TyCtxt}; use rustc::ty::adjustment::CustomCoerceUnsized; @@ -383,7 +382,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance, promoted: None, }; - let param_env = ty::ParamEnv::empty(traits::Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); match tcx.const_eval(param_env.and(cid)) { Ok(val) => collect_const(tcx, val, instance.substs, &mut neighbors), @@ -654,7 +653,7 @@ fn visit_fn_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, { if let ty::TyFnDef(def_id, substs) = ty.sty { let instance = ty::Instance::resolve(tcx, - ty::ParamEnv::empty(traits::Reveal::All), + ty::ParamEnv::reveal_all(), def_id, substs).unwrap(); visit_instance_use(tcx, instance, is_direct_call, output); @@ -776,7 +775,7 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { let type_has_metadata = |ty: Ty<'tcx>| -> bool { use syntax_pos::DUMMY_SP; - if ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All)) { + if ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) { return false; } let tail = tcx.struct_tail(ty); @@ -859,7 +858,7 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let methods = methods.iter().cloned().filter_map(|method| method) .map(|(def_id, substs)| ty::Instance::resolve( tcx, - ty::ParamEnv::empty(traits::Reveal::All), + ty::ParamEnv::reveal_all(), def_id, substs).unwrap()) .filter(|&instance| should_monomorphize_locally(tcx, &instance)) @@ -1013,7 +1012,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { let start_instance = Instance::resolve( self.tcx, - ty::ParamEnv::empty(traits::Reveal::All), + ty::ParamEnv::reveal_all(), start_def_id, self.tcx.mk_substs(iter::once(Kind::from(main_ret_ty))) ).unwrap(); @@ -1062,7 +1061,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let instance = ty::Instance::resolve(tcx, - ty::ParamEnv::empty(traits::Reveal::All), + ty::ParamEnv::reveal_all(), method.def_id, callee_substs).unwrap(); @@ -1120,7 +1119,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, output, param_substs: instance.substs, }.visit_mir(&mir); - let param_env = ty::ParamEnv::empty(traits::Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); for (i, promoted) in mir.promoted.iter().enumerate() { use rustc_data_structures::indexed_vec::Idx; let cid = GlobalId { @@ -1155,7 +1154,7 @@ fn collect_const<'a, 'tcx>( let val = match constant.val { ConstVal::Unevaluated(def_id, substs) => { - let param_env = ty::ParamEnv::empty(traits::Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); let substs = tcx.trans_apply_param_substs(param_substs, &substs); let instance = ty::Instance::resolve(tcx, diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 2ca6c76a8009..4c9789782a6e 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -154,7 +154,7 @@ pub fn resolve_drop_in_place<'a, 'tcx>( { let def_id = tcx.require_lang_item(DropInPlaceFnLangItem); let substs = tcx.intern_substs(&[ty.into()]); - Instance::resolve(tcx, ty::ParamEnv::empty(traits::Reveal::All), def_id, substs).unwrap() + Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap() } pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -168,7 +168,7 @@ pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, substs: tcx.mk_substs_trait(source_ty, &[target_ty]) }); - match tcx.trans_fulfill_obligation( (ty::ParamEnv::empty(traits::Reveal::All), trait_ref)) { + match tcx.trans_fulfill_obligation( (ty::ParamEnv::reveal_all(), trait_ref)) { traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => { tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap() } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 88618122e4f1..94446a98e63f 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -21,7 +21,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::middle::const_val::ConstVal; -use rustc::traits::{self, Reveal}; +use rustc::traits; use rustc::ty::{self, TyCtxt, Ty, TypeFoldable}; use rustc::ty::cast::CastTy; use rustc::ty::maps::Providers; @@ -1237,7 +1237,7 @@ impl MirPass for QualifyAndPromoteConstants { } let ty = mir.return_ty(); tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic); let mut fulfillment_cx = traits::FulfillmentContext::new(); fulfillment_cx.register_bound(&infcx, diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 16278c37a0cc..356ad9ec11bb 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -34,7 +34,6 @@ use rustc::middle::mem_categorization::Categorization; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::Providers; use rustc::ty::subst::Substs; -use rustc::traits::Reveal; use rustc::util::nodemap::{ItemLocalSet, NodeSet}; use rustc::hir; use rustc_data_structures::sync::Lrc; @@ -87,7 +86,7 @@ fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, in_static: false, promotable: false, mut_rvalue_borrows: NodeSet(), - param_env: ty::ParamEnv::empty(Reveal::UserFacing), + param_env: ty::ParamEnv::empty(), identity_substs: Substs::empty(), result: ItemLocalSet(), }; diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 54cc561e8041..1dcf349e23bd 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -25,7 +25,6 @@ use type_of::LayoutLlvmExt; use rustc::hir::def_id::DefId; use rustc::ty::{self, TypeFoldable}; use rustc::ty::layout::LayoutOf; -use rustc::traits; use rustc::ty::subst::Substs; use rustc_back::PanicStrategy; @@ -185,7 +184,7 @@ pub fn resolve_and_get_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, cx, ty::Instance::resolve( cx.tcx, - ty::ParamEnv::empty(traits::Reveal::All), + ty::ParamEnv::reveal_all(), def_id, substs ).unwrap() diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 7c4e2340d5bd..c71c0cc0ebf2 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -25,7 +25,6 @@ use declare; use type_::Type; use type_of::LayoutLlvmExt; use value::Value; -use rustc::traits; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::{HasDataLayout, LayoutOf}; use rustc::hir; @@ -40,15 +39,15 @@ use syntax_pos::{Span, DUMMY_SP}; pub use context::CodegenCx; pub fn type_needs_drop<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.needs_drop(tcx, ty::ParamEnv::empty(traits::Reveal::All)) + ty.needs_drop(tcx, ty::ParamEnv::reveal_all()) } pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All)) + ty.is_sized(tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) } pub fn type_is_freeze<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.is_freeze(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP) + ty.is_freeze(tcx, ty::ParamEnv::reveal_all(), DUMMY_SP) } /* diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index dc5e78895944..1f2c3cc883c6 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -14,7 +14,6 @@ use llvm::{ContextRef, ModuleRef, ValueRef}; use rustc::dep_graph::DepGraphSafe; use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::traits; use debuginfo; use callee; use base; @@ -435,7 +434,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> { pub fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool { use syntax_pos::DUMMY_SP; - if ty.is_sized(self.tcx.at(DUMMY_SP), ty::ParamEnv::empty(traits::Reveal::All)) { + if ty.is_sized(self.tcx.at(DUMMY_SP), ty::ParamEnv::reveal_all()) { return false; } @@ -464,7 +463,7 @@ impl<'a, 'tcx> LayoutOf> for &'a CodegenCx<'a, 'tcx> { type TyLayout = TyLayout<'tcx>; fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { - self.tcx.layout_of(ty::ParamEnv::empty(traits::Reveal::All).and(ty)) + self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)) .unwrap_or_else(|e| match e { LayoutError::SizeOverflow(_) => self.sess().fatal(&e.to_string()), _ => bug!("failed to get layout for `{}`: {}", ty, e) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index efb5338f680a..606c1396c1da 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -12,7 +12,6 @@ use llvm::{self, ValueRef, BasicBlockRef}; use rustc::middle::lang_items; use rustc::ty::{self, TypeFoldable}; use rustc::ty::layout::{self, LayoutOf}; -use rustc::traits; use rustc::mir; use abi::{Abi, FnType, ArgType, PassMode}; use base; @@ -419,7 +418,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { let (instance, mut llfn) = match callee.layout.ty.sty { ty::TyFnDef(def_id, substs) => { (Some(ty::Instance::resolve(bx.cx.tcx, - ty::ParamEnv::empty(traits::Reveal::All), + ty::ParamEnv::reveal_all(), def_id, substs).unwrap()), None) diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 6aa8b7e5449f..977c7c983d6f 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -12,7 +12,6 @@ use llvm::{self, ValueRef}; use rustc::middle::const_val::{ConstVal, ConstEvalErr}; use rustc_mir::interpret::{read_target_uint, const_val_field}; use rustc::hir::def_id::DefId; -use rustc::traits; use rustc::mir; use rustc_data_structures::indexed_vec::Idx; use rustc::mir::interpret::{Allocation, GlobalId, MemoryPointer, PrimVal, Value as MiriValue}; @@ -126,7 +125,7 @@ pub fn trans_static_initializer<'a, 'tcx>( instance, promoted: None }; - let param_env = ty::ParamEnv::empty(traits::Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); cx.tcx.const_eval(param_env.and(cid))?; let alloc_id = cx @@ -152,7 +151,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { match constant.val { ConstVal::Unevaluated(def_id, ref substs) => { let tcx = bx.tcx(); - let param_env = ty::ParamEnv::empty(traits::Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); let instance = ty::Instance::resolve(tcx, param_env, def_id, substs).unwrap(); let cid = GlobalId { instance, @@ -172,7 +171,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { ) -> Result> { match constant.literal { mir::Literal::Promoted { index } => { - let param_env = ty::ParamEnv::empty(traits::Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { instance: self.instance, promoted: Some(index), @@ -201,7 +200,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { let values: Result, _> = (0..fields).map(|field| { let field = const_val_field( bx.tcx(), - ty::ParamEnv::empty(traits::Reveal::All), + ty::ParamEnv::reveal_all(), self.instance, None, mir::Field::new(field as usize), diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index a3a1f2a93077..b6459b624104 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -501,7 +501,7 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::TraitContainer(_) => tcx.mk_self_type() }; let self_arg_ty = *tcx.fn_sig(method.def_id).input(0).skip_binder(); - let param_env = ty::ParamEnv::empty(Reveal::All); + let param_env = ty::ParamEnv::reveal_all(); tcx.infer_ctxt().enter(|infcx| { let self_arg_ty = tcx.liberate_late_bound_regions( @@ -759,7 +759,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref); tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); let inh = Inherited::new(infcx, impl_c.def_id); let infcx = &inh.infcx; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 165cfe6604e8..f33536227a0b 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -16,7 +16,7 @@ use rustc::infer::outlives::env::OutlivesEnvironment; use rustc::middle::region; use rustc::ty::subst::{Subst, Substs, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::traits::{self, Reveal, ObligationCause}; +use rustc::traits::{self, ObligationCause}; use util::common::ErrorReported; use util::nodemap::FxHashSet; @@ -126,7 +126,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( // it did the wrong thing, so I chose to preserve existing // behavior, since it ought to be simply more // conservative. -nmatsakis - let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty(Reveal::UserFacing)); + let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty()); infcx.resolve_regions_and_report_errors(drop_impl_did, ®ion_scope_tree, &outlives_env); Ok(()) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1ea1ff1fae24..48591998a1fb 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3997,7 +3997,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } hir::ExprRepeat(ref element, count) => { let count_def_id = tcx.hir.body_owner_def_id(count); - let param_env = ty::ParamEnv::empty(traits::Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id); let instance = ty::Instance::resolve( tcx.global_tcx(), diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 49a23f14338b..ea90c35cb8f2 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -110,7 +110,7 @@ use rustc::infer::InferOk; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::Providers; -use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal}; +use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode}; use session::{CompileIncomplete, config}; use util::common::time; @@ -158,7 +158,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, actual: Ty<'tcx>) -> bool { tcx.infer_ctxt().enter(|ref infcx| { - let param_env = ty::ParamEnv::empty(Reveal::UserFacing); + let param_env = ty::ParamEnv::empty(); let mut fulfill_cx = FulfillmentContext::new(); match infcx.at(&cause, param_env).eq(expected, actual) { Ok(InferOk { obligations, .. }) => { From 64d4ed300b52834954179284a0d0a6eb5084d39e Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 14 Feb 2018 05:08:02 -0500 Subject: [PATCH 143/830] move ParamEnv methods from `ty/util` to `ty/mod` --- src/librustc/ty/mod.rs | 44 ++++++++++++++++++++++++++++++++++++++++- src/librustc/ty/util.rs | 44 +---------------------------------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 40d7aa9556df..f81a2b9750ae 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -29,7 +29,7 @@ use mir::Mir; use mir::interpret::{GlobalId, Value, PrimVal}; use mir::GeneratorLayout; use session::CrateDisambiguator; -use traits; +use traits::{self, Reveal}; use ty; use ty::subst::{Subst, Substs}; use ty::util::{IntTypeExt, Discr}; @@ -1396,6 +1396,48 @@ pub struct ParamEnv<'tcx> { } impl<'tcx> ParamEnv<'tcx> { + /// Construct a trait environment suitable for contexts where + /// there are no where clauses in scope. Hidden types (like `impl + /// Trait`) are left hidden, so this is suitable for ordinary + /// type-checking. + pub fn empty() -> Self { + Self::new(ty::Slice::empty(), Reveal::UserFacing, ty::UniverseIndex::ROOT) + } + + /// Construct a trait environment with no where clauses in scope + /// where the values of all `impl Trait` and other hidden types + /// are revealed. This is suitable for monomorphized, post-typeck + /// environments like trans or doing optimizations. + /// + /// NB. If you want to have predicates in scope, use `ParamEnv::new`, + /// or invoke `param_env.with_reveal_all()`. + pub fn reveal_all() -> Self { + Self::new(ty::Slice::empty(), Reveal::All, ty::UniverseIndex::ROOT) + } + + /// Construct a trait environment with the given set of predicates. + pub fn new(caller_bounds: &'tcx ty::Slice>, + reveal: Reveal, + universe: ty::UniverseIndex) + -> Self { + ty::ParamEnv { caller_bounds, reveal, universe } + } + + /// Returns a new parameter environment with the same clauses, but + /// which "reveals" the true results of projections in all cases + /// (even for associated types that are specializable). This is + /// the desired behavior during trans and certain other special + /// contexts; normally though we want to use `Reveal::UserFacing`, + /// which is the default. + pub fn with_reveal_all(self) -> Self { + ty::ParamEnv { reveal: Reveal::All, ..self } + } + + /// Returns this same environment but with no caller bounds. + pub fn without_caller_bounds(self) -> Self { + ty::ParamEnv { caller_bounds: ty::Slice::empty(), ..self } + } + /// Creates a suitable environment in which to perform trait /// queries on the given value. This will either be `self` *or* /// the empty environment, depending on whether `value` references diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index ca6817d992b6..a7ee8579fb98 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -16,7 +16,7 @@ use hir::map::{DefPathData, Node}; use hir; use ich::NodeIdHashingMode; use middle::const_val::ConstVal; -use traits::{self, Reveal}; +use traits; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::fold::TypeVisitor; use ty::subst::{Subst, UnpackedKind}; @@ -182,48 +182,6 @@ pub enum Representability { } impl<'tcx> ty::ParamEnv<'tcx> { - /// Construct a trait environment suitable for contexts where - /// there are no where clauses in scope. Hidden types (like `impl - /// Trait`) are left hidden, so this is suitable for ordinary - /// type-checking. - pub fn empty() -> Self { - Self::new(ty::Slice::empty(), Reveal::UserFacing, ty::UniverseIndex::ROOT) - } - - /// Construct a trait environment with no where clauses in scope - /// where the values of all `impl Trait` and other hidden types - /// are revealed. This is suitable for monomorphized, post-typeck - /// environments like trans or doing optimizations. - /// - /// NB. If you want to have predicates in scope, use `ParamEnv::new`, - /// or invoke `param_env.with_reveal_all()`. - pub fn reveal_all() -> Self { - Self::new(ty::Slice::empty(), Reveal::All, ty::UniverseIndex::ROOT) - } - - /// Construct a trait environment with the given set of predicates. - pub fn new(caller_bounds: &'tcx ty::Slice>, - reveal: Reveal, - universe: ty::UniverseIndex) - -> Self { - ty::ParamEnv { caller_bounds, reveal, universe } - } - - /// Returns a new parameter environment with the same clauses, but - /// which "reveals" the true results of projections in all cases - /// (even for associated types that are specializable). This is - /// the desired behavior during trans and certain other special - /// contexts; normally though we want to use `Reveal::UserFacing`, - /// which is the default. - pub fn with_reveal_all(self) -> Self { - ty::ParamEnv { reveal: Reveal::All, ..self } - } - - /// Returns this same environment but with no caller bounds. - pub fn without_caller_bounds(self) -> Self { - ty::ParamEnv { caller_bounds: ty::Slice::empty(), ..self } - } - pub fn can_type_implement_copy<'a>(self, tcx: TyCtxt<'a, 'tcx, 'tcx>, self_type: Ty<'tcx>, span: Span) From 80b4c45ee47833338164c6eb015f421890712863 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 20 Feb 2018 10:37:35 -0500 Subject: [PATCH 144/830] change `ParamEnv::and` to sometimes keep the environment [VIC] In general, we've been moving towards a semantics where you can have contradictory where-clauses, and we try to honor them. There are already existing run-pass tests where we take that philosophy as well (e.g., `compile-fail/issue-36839.rs`). The current behavior of `and`, where it strips the environment, breaks that code. --- src/librustc/ty/mod.rs | 49 ++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f81a2b9750ae..e3405e0c3b36 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1439,31 +1439,38 @@ impl<'tcx> ParamEnv<'tcx> { } /// Creates a suitable environment in which to perform trait - /// queries on the given value. This will either be `self` *or* - /// the empty environment, depending on whether `value` references - /// type parameters that are in scope. (If it doesn't, then any - /// judgements should be completely independent of the context, - /// and hence we can safely use the empty environment so as to - /// enable more sharing across functions.) + /// queries on the given value. When type-checking, this is simply + /// the pair of the environment plus value. But when reveal is set to + /// All, then if `value` does not reference any type parameters, we will + /// pair it with the empty environment. This improves caching and is generally + /// invisible. /// - /// NB: This is a mildly dubious thing to do, in that a function - /// (or other environment) might have wacky where-clauses like + /// NB: We preserve the environment when type-checking because it + /// is possible for the user to have wacky where-clauses like /// `where Box: Copy`, which are clearly never - /// satisfiable. The code will at present ignore these, - /// effectively, when type-checking the body of said - /// function. This preserves existing behavior in any - /// case. --nmatsakis + /// satisfiable. We generally want to behave as if they were true, + /// although the surrounding function is never reachable. pub fn and>(self, value: T) -> ParamEnvAnd<'tcx, T> { - assert!(!value.needs_infer()); - if value.has_param_types() || value.has_self_ty() { - ParamEnvAnd { - param_env: self, - value, + match self.reveal { + Reveal::UserFacing => { + ParamEnvAnd { + param_env: self, + value, + } } - } else { - ParamEnvAnd { - param_env: self.without_caller_bounds(), - value, + + Reveal::All => { + if value.needs_infer() || value.has_param_types() || value.has_self_ty() { + ParamEnvAnd { + param_env: self, + value, + } + } else { + ParamEnvAnd { + param_env: self.without_caller_bounds(), + value, + } + } } } } From 993c1488cc4b0826c3f1076393bf50eef09ba467 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Feb 2018 10:39:36 -0500 Subject: [PATCH 145/830] add `canonicalize` method to `InferCtxt` [VIC] --- src/librustc/ich/impls_ty.rs | 59 +- src/librustc/infer/canonical.rs | 928 ++++++++++++++++++ src/librustc/infer/combine.rs | 1 + src/librustc/infer/error_reporting/mod.rs | 1 + src/librustc/infer/freshen.rs | 6 +- .../infer/lexical_region_resolve/mod.rs | 2 + src/librustc/infer/mod.rs | 8 +- src/librustc/lib.rs | 2 +- src/librustc/macros.rs | 19 + src/librustc/session/mod.rs | 5 + src/librustc/traits/select.rs | 15 +- src/librustc/ty/context.rs | 33 + src/librustc/ty/error.rs | 1 + src/librustc/ty/flags.rs | 12 +- src/librustc/ty/mod.rs | 9 +- src/librustc/ty/sty.rs | 12 + src/librustc/ty/subst.rs | 1 + src/librustc/ty/util.rs | 3 + src/librustc/util/ppaux.rs | 9 + src/librustc_borrowck/borrowck/check_loans.rs | 1 + .../borrowck/gather_loans/mod.rs | 1 + src/librustc_const_eval/lib.rs | 1 + src/librustc_data_structures/indexed_vec.rs | 2 +- src/librustc_metadata/lib.rs | 2 + .../borrow_check/error_reporting.rs | 1 + src/librustc_save_analysis/lib.rs | 1 + src/librustc_typeck/variance/constraints.rs | 1 + src/librustdoc/clean/mod.rs | 1 + 28 files changed, 1121 insertions(+), 16 deletions(-) create mode 100644 src/librustc/infer/canonical.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index d927a151610e..ae67d592ba30 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -19,6 +19,7 @@ use std::cell::RefCell; use std::hash as std_hash; use std::mem; use middle::region; +use infer; use traits; use ty; use mir; @@ -85,6 +86,9 @@ for ty::RegionKind { ty::ReEmpty => { // No variant fields to hash for these ... } + ty::ReCanonical(c) => { + c.hash_stable(hcx, hasher); + } ty::ReLateBound(db, ty::BrAnon(i)) => { db.depth.hash_stable(hcx, hasher); i.hash_stable(hcx, hasher); @@ -130,6 +134,16 @@ impl<'a> HashStable> for ty::RegionVid { } } +impl<'gcx> HashStable> for ty::CanonicalVar { + #[inline] + fn hash_stable(&self, + hcx: &mut StableHashingContext<'gcx>, + hasher: &mut StableHasher) { + use rustc_data_structures::indexed_vec::Idx; + self.index().hash_stable(hcx, hasher); + } +} + impl<'a, 'gcx> HashStable> for ty::adjustment::AutoBorrow<'gcx> { fn hash_stable(&self, @@ -1229,11 +1243,52 @@ for traits::VtableGeneratorData<'gcx, N> where N: HashStable HashStable> +impl<'a> HashStable> for ty::UniverseIndex { fn hash_stable(&self, - hcx: &mut StableHashingContext<'gcx>, + hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { self.depth().hash_stable(hcx, hasher); } } + +impl_stable_hash_for!( + impl<'tcx, V> for struct infer::canonical::Canonical<'tcx, V> { + variables, value + } +); + +impl_stable_hash_for!( + impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> { + var_values + } +); + +impl_stable_hash_for!(struct infer::canonical::CanonicalVarInfo { + kind +}); + +impl_stable_hash_for!(enum infer::canonical::CanonicalVarKind { + Ty(k), + Region +}); + +impl_stable_hash_for!(enum infer::canonical::CanonicalTyVarKind { + General, + Int, + Float +}); + +impl_stable_hash_for!( + impl<'tcx, R> for struct infer::canonical::QueryResult<'tcx, R> { + var_values, region_constraints, certainty, value + } +); + +impl_stable_hash_for!(struct infer::canonical::QueryRegionConstraints<'tcx> { + region_outlives, ty_outlives +}); + +impl_stable_hash_for!(enum infer::canonical::Certainty { + Proven, Ambiguous +}); diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs new file mode 100644 index 000000000000..c1c7337860e3 --- /dev/null +++ b/src/librustc/infer/canonical.rs @@ -0,0 +1,928 @@ +// Copyright 2014 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. + +//! **Canonicalization** is the key to constructing a query in the +//! middle of type inference. Ordinarily, it is not possible to store +//! types from type inference in query keys, because they contain +//! references to inference variables whose lifetimes are too short +//! and so forth. Canonicalizing a value T1 using `canonicalize_query` +//! produces two things: +//! +//! - a value T2 where each unbound inference variable has been +//! replaced with a **canonical variable**; +//! - a map M (of type `CanonicalVarValues`) from those canonical +//! variables back to the original. +//! +//! We can then do queries using T2. These will give back constriants +//! on the canonical variables which can be translated, using the map +//! M, into constraints in our source context. This process of +//! translating the results back is done by the +//! `instantiate_query_result` method. + +use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin}; +use rustc_data_structures::indexed_vec::Idx; +use std::fmt::Debug; +use syntax::codemap::Span; +use traits::{Obligation, ObligationCause, PredicateObligation}; +use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags}; +use ty::subst::{Kind, UnpackedKind}; +use ty::fold::{TypeFoldable, TypeFolder}; +use util::common::CellUsizeExt; + +use rustc_data_structures::indexed_vec::IndexVec; +use rustc_data_structures::fx::FxHashMap; + +/// A "canonicalized" type `V` is one where all free inference +/// variables have been rewriten to "canonical vars". These are +/// numbered starting from 0 in order of first appearance. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct Canonical<'gcx, V> { + pub variables: CanonicalVarInfos<'gcx>, + pub value: V, +} + +pub type CanonicalVarInfos<'gcx> = &'gcx Slice; + +/// A set of values corresponding to the canonical variables from some +/// `Canonical`. You can give these values to +/// `canonical_value.substitute` to substitute them into the canonical +/// value at the right places. +/// +/// When you canonicalize a value `V`, you get back one of these +/// vectors with the original values that were replaced by canonical +/// variables. +/// +/// You can also use `infcx.fresh_inference_vars_for_canonical_vars` +/// to get back a `CanonicalVarValues` containing fresh inference +/// variables. +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct CanonicalVarValues<'tcx> { + pub var_values: IndexVec>, +} + +/// Information about a canonical variable that is included with the +/// canonical value. This is sufficient information for code to create +/// a copy of the canonical value in some other inference context, +/// with fresh inference variables replacing the canonical values. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct CanonicalVarInfo { + pub kind: CanonicalVarKind, +} + +/// Describes the "kind" of the canonical variable. This is a "kind" +/// in the type-theory sense of the term -- i.e., a "meta" type system +/// that analyzes type-like values. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum CanonicalVarKind { + /// Some kind of type inference variable. + Ty(CanonicalTyVarKind), + + /// Region variable `'?R`. + Region, +} + +/// Rust actually has more than one category of type variables; +/// notably, the type variables we create for literals (e.g., 22 or +/// 22.) can only be instantiated with integral/float types (e.g., +/// usize or f32). In order to faithfully reproduce a type, we need to +/// know what set of types a given type variable can be unified with. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum CanonicalTyVarKind { + /// General type variable `?T` that can be unified with arbitrary types. + General, + + /// Integral type variable `?I` (that can only be unified with integral types). + Int, + + /// Floating-point type variable `?F` (that can only be unified with float types). + Float, +} + +/// After we execute a query with a canonicalized key, we get back a +/// `Canonical>`. You can use +/// `instantiate_query_result` to access the data in this result. +#[derive(Clone, Debug)] +pub struct QueryResult<'tcx, R> { + pub var_values: CanonicalVarValues<'tcx>, + pub region_constraints: QueryRegionConstraints<'tcx>, + pub certainty: Certainty, + pub value: R, +} + +/// Indicates whether or not we were able to prove the query to be +/// true. +#[derive(Copy, Clone, Debug)] +pub enum Certainty { + /// The query is known to be true, presuming that you apply the + /// given `var_values` and the region-constraints are satisfied. + Proven, + + /// The query is not known to be true, but also not known to be + /// false. The `var_values` represent *either* values that must + /// hold in order for the query to be true, or helpful tips that + /// *might* make it true. Currently rustc's trait solver cannot + /// distinguish the two (e.g., due to our preference for where + /// clauses over impls). + /// + /// After some unifiations and things have been done, it makes + /// sense to try and prove again -- of course, at that point, the + /// canonical form will be different, making this a distinct + /// query. + Ambiguous, +} + +impl Certainty { + pub fn is_proven(&self) -> bool { + match self { + Certainty::Proven => true, + Certainty::Ambiguous => false, + } + } + + pub fn is_ambiguous(&self) -> bool { + !self.is_proven() + } +} + +impl<'tcx, R> QueryResult<'tcx, R> { + pub fn is_proven(&self) -> bool { + self.certainty.is_proven() + } + + pub fn is_ambiguous(&self) -> bool { + !self.is_proven() + } +} + +impl<'tcx, R> Canonical<'tcx, QueryResult<'tcx, R>> { + pub fn is_proven(&self) -> bool { + self.value.is_proven() + } + + pub fn is_ambiguous(&self) -> bool { + !self.is_proven() + } +} + +/// Subset of `RegionConstraintData` produced by trait query. +#[derive(Clone, Debug, Default)] +pub struct QueryRegionConstraints<'tcx> { + pub region_outlives: Vec<(Region<'tcx>, Region<'tcx>)>, + pub ty_outlives: Vec<(Ty<'tcx>, Region<'tcx>)>, +} + +/// Trait implemented by values that can be canonicalized. It mainly +/// serves to identify the interning table we will use. +pub trait Canonicalize<'gcx: 'tcx, 'tcx>: TypeFoldable<'tcx> + Lift<'gcx> { + type Canonicalized: 'gcx + Debug; + + /// After a value has been fully canonicalized and lifted, this + /// method will allocate it in a global arena. + fn intern( + gcx: TyCtxt<'_, 'gcx, 'gcx>, + value: Canonical<'gcx, Self::Lifted>, + ) -> Self::Canonicalized; +} + +impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { + /// Creates a substitution S for the canonical value with fresh + /// inference variables and applies it to the canonical value. + /// Returns both the instantiated result *and* the substitution S. + /// + /// This is useful at the start of a query: it basically brings + /// the canonical value "into scope" within your new infcx. At the + /// end of processing, the substitution S (once canonicalized) + /// then represents the values that you computed for each of the + /// canonical inputs to your query. + pub fn instantiate_canonical_with_fresh_inference_vars( + &self, + span: Span, + canonical: &Canonical<'tcx, T>, + ) -> (T, CanonicalVarValues<'tcx>) + where + T: TypeFoldable<'tcx>, + { + let canonical_inference_vars = + self.fresh_inference_vars_for_canonical_vars(span, canonical.variables); + let result = canonical.substitute(self.tcx, &canonical_inference_vars); + (result, canonical_inference_vars) + } + + /// Given the "infos" about the canonical variables from some + /// canonical, creates fresh inference variables with the same + /// characteristics. You can then use `substitute` to instantiate + /// the canonical variable with these inference variables. + pub fn fresh_inference_vars_for_canonical_vars( + &self, + span: Span, + variables: &Slice, + ) -> CanonicalVarValues<'tcx> { + let var_values: IndexVec> = variables + .iter() + .map(|info| self.fresh_inference_var_for_canonical_var(span, *info)) + .collect(); + + CanonicalVarValues { var_values } + } + + /// Given the "info" about a canonical variable, creates a fresh + /// inference variable with the same characteristics. + pub fn fresh_inference_var_for_canonical_var( + &self, + span: Span, + cv_info: CanonicalVarInfo, + ) -> Kind<'tcx> { + match cv_info.kind { + CanonicalVarKind::Ty(ty_kind) => { + let ty = match ty_kind { + CanonicalTyVarKind::General => { + self.next_ty_var( + // FIXME(#48696) this handling of universes is not right. + ty::UniverseIndex::ROOT, + TypeVariableOrigin::MiscVariable(span), + ) + } + + CanonicalTyVarKind::Int => self.tcx.mk_int_var(self.next_int_var_id()), + + CanonicalTyVarKind::Float => self.tcx.mk_float_var(self.next_float_var_id()), + }; + Kind::from(ty) + } + + CanonicalVarKind::Region => { + Kind::from(self.next_region_var(RegionVariableOrigin::MiscVariable(span))) + } + } + } + + /// Given the (canonicalized) result to a canonical query, + /// instantiates the result so it can be used, plugging in the + /// values from the canonical query. (Note that the result may + /// have been ambiguous; you should check the certainty level of + /// the query before applying this function.) + /// + /// It's easiest to explain what is happening here by + /// example. Imagine we start out with the query `?A: Foo<'static, + /// ?B>`. We would canonicalize that by introducing two variables: + /// + /// ?0: Foo<'?1, ?2> + /// + /// (Note that all regions get replaced with variables always, + /// even "known" regions like `'static`.) After canonicalization, + /// we also get back an array with the "original values" for each + /// canonicalized variable: + /// + /// [?A, 'static, ?B] + /// + /// Now we do the query and get back some result R. As part of that + /// result, we'll have an array of values for the canonical inputs. + /// For example, the canonical result might be: + /// + /// ``` + /// for<2> { + /// values = [ Vec, '1, ?0 ] + /// ^^ ^^ ^^ these are variables in the result! + /// ... + /// } + /// ``` + /// + /// Note that this result is itself canonical and may include some + /// variables (in this case, `?0`). + /// + /// What we want to do conceptually is to (a) instantiate each of the + /// canonical variables in the result with a fresh inference variable + /// and then (b) unify the values in the result with the original values. + /// Doing step (a) would yield a result of + /// + /// ``` + /// { + /// values = [ Vec, '?X, ?C ] + /// ^^ ^^^ fresh inference variables in `self` + /// .. + /// } + /// ``` + /// + /// Step (b) would then unify: + /// + /// ``` + /// ?A with Vec + /// 'static with '?X + /// ?B with ?C + /// ``` + /// + /// But what we actually do is a mildly optimized variant of + /// that. Rather than eagerly instantiating all of the canonical + /// values in the result with variables, we instead walk the + /// vector of values, looking for cases where the value is just a + /// canonical variable. In our example, `values[2]` is `?C`, so + /// that we means we can deduce that `?C := ?B and `'?X := + /// 'static`. This gives us a partial set of values. Anything for + /// which we do not find a value, we create an inference variable + /// for. **Then** we unify. + pub fn instantiate_query_result( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + original_values: &CanonicalVarValues<'tcx>, + query_result: &Canonical<'tcx, QueryResult<'tcx, R>>, + ) -> InferResult<'tcx, R> + where + R: Debug + TypeFoldable<'tcx>, + { + debug!( + "instantiate_query_result(original_values={:#?}, query_result={:#?})", + original_values, query_result, + ); + + // Every canonical query result includes values for each of + // the inputs to the query. Therefore, we begin by unifying + // these values with the original inputs that were + // canonicalized. + let result_values = &query_result.value.var_values; + assert_eq!(original_values.len(), result_values.len()); + + // Quickly try to find initial values for the canonical + // variables in the result in terms of the query. We do this + // by iterating down the values that the query gave to each of + // the canonical inputs. If we find that one of those values + // is directly equal to one of the canonical variables in the + // result, then we can type the corresponding value from the + // input. See the example above. + let mut opt_values: IndexVec>> = + IndexVec::from_elem_n(None, query_result.variables.len()); + + // In terms of our example above, we are iterating over pairs like: + // [(?A, Vec), ('static, '?1), (?B, ?0)] + for (original_value, result_value) in original_values.iter().zip(result_values) { + match result_value.unpack() { + UnpackedKind::Type(result_value) => { + // e.g., here `result_value` might be `?0` in the example above... + if let ty::TyInfer(ty::InferTy::CanonicalTy(index)) = result_value.sty { + // in which case we would set `canonical_vars[0]` to `Some(?U)`. + opt_values[index] = Some(original_value); + } + } + UnpackedKind::Lifetime(result_value) => { + // e.g., here `result_value` might be `'?1` in the example above... + if let &ty::RegionKind::ReCanonical(index) = result_value { + // in which case we would set `canonical_vars[0]` to `Some('static)`. + opt_values[index] = Some(original_value); + } + } + } + } + + // Create a result substitution: if we found a value for a + // given variable in the loop above, use that. Otherwise, use + // a fresh inference variable. + let result_subst = &CanonicalVarValues { + var_values: query_result + .variables + .iter() + .enumerate() + .map(|(index, info)| match opt_values[CanonicalVar::new(index)] { + Some(k) => k, + None => self.fresh_inference_var_for_canonical_var(cause.span, *info), + }) + .collect(), + }; + + // Apply the result substitution to the query. + let QueryResult { + var_values: query_values, + region_constraints: query_region_constraints, + certainty: _, + value: user_result, + } = query_result.substitute(self.tcx, result_subst); + + // Unify the original values for the canonical variables in + // the input with the value found in the query + // post-substitution. Often, but not always, this is a no-op, + // because we already found the mapping in the first step. + let mut obligations = + self.unify_canonical_vars(cause, param_env, original_values, &query_values)? + .into_obligations(); + + obligations.extend(self.query_region_constraints_into_obligations( + cause, + param_env, + query_region_constraints, + )); + + Ok(InferOk { + value: user_result, + obligations, + }) + } + + /// Converts the region constraints resulting from a query into an + /// iterator of obligations. + fn query_region_constraints_into_obligations<'a>( + &self, + cause: &'a ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + query_region_constraints: QueryRegionConstraints<'tcx>, + ) -> impl Iterator> + 'a { + let QueryRegionConstraints { + region_outlives, + ty_outlives, + } = query_region_constraints; + + let region_obligations = region_outlives.into_iter().map(move |(r1, r2)| { + Obligation::new( + cause.clone(), + param_env, + ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))), + ) + }); + + let ty_obligations = ty_outlives.into_iter().map(move |(t1, r2)| { + Obligation::new( + cause.clone(), + param_env, + ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))), + ) + }); + + region_obligations.chain(ty_obligations) + } + + /// Given two sets of values for the same set of canonical variables, unify them. + pub fn unify_canonical_vars( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + variables1: &CanonicalVarValues<'tcx>, + variables2: &CanonicalVarValues<'tcx>, + ) -> InferResult<'tcx, ()> { + assert_eq!(variables1.var_values.len(), variables2.var_values.len()); + self.commit_if_ok(|_| { + let mut obligations = vec![]; + for (value1, value2) in variables1.var_values.iter().zip(&variables2.var_values) { + match (value1.unpack(), value2.unpack()) { + (UnpackedKind::Type(v1), UnpackedKind::Type(v2)) => { + obligations + .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations()); + } + ( + UnpackedKind::Lifetime(ty::ReErased), + UnpackedKind::Lifetime(ty::ReErased), + ) => { + // no action needed + } + (UnpackedKind::Lifetime(v1), UnpackedKind::Lifetime(v2)) => { + obligations + .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations()); + } + _ => { + bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,); + } + } + } + Ok(InferOk { + value: (), + obligations, + }) + }) + } + + /// Canonicalizes a query value `V`. When we canonicalize a query, + /// we not only canonicalize unbound inference variables, but we + /// *also* replace all free regions whatsoever. So for example a + /// query like `T: Trait<'static>` would be canonicalized to + /// + /// T: Trait<'?0> + /// + /// with a mapping M that maps `'?0` to `'static`. + pub fn canonicalize_query(&self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'tcx>) + where + V: Canonicalize<'gcx, 'tcx>, + { + self.tcx.sess.perf_stats.queries_canonicalized.increment(); + + Canonicalizer::canonicalize( + value, + Some(self), + self.tcx, + CanonicalizeAllFreeRegions(true), + ) + } + + /// Canonicalizes a query *response* `V`. When we canonicalize a + /// query response, we only canonicalize unbound inference + /// variables, and we leave other free regions alone. So, + /// continuing with the example from `canonicalize_query`, if + /// there was an input query `T: Trait<'static>`, it would have + /// been canonicalized to + /// + /// T: Trait<'?0> + /// + /// with a mapping M that maps `'?0` to `'static`. But if we found that there + /// exists only one possible impl of `Trait`, and it looks like + /// + /// impl Trait<'static> for T { .. } + /// + /// then we would prepare a query result R that (among other + /// things) includes a mapping to `'?0 := 'static`. When + /// canonicalizing this query result R, we would leave this + /// reference to `'static` alone. + pub fn canonicalize_response( + &self, + value: &V, + ) -> (V::Canonicalized, CanonicalVarValues<'tcx>) + where + V: Canonicalize<'gcx, 'tcx>, + { + Canonicalizer::canonicalize( + value, + Some(self), + self.tcx, + CanonicalizeAllFreeRegions(false), + ) + } +} + +impl<'cx, 'gcx> TyCtxt<'cx, 'gcx, 'gcx> { + /// Canonicalize a value that doesn't have any inference variables + /// or other things (and we know it). + pub fn canonicalize_global(self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'gcx>) + where + V: Canonicalize<'gcx, 'gcx>, + { + Canonicalizer::canonicalize(value, None, self, CanonicalizeAllFreeRegions(false)) + } +} + +/// If this flag is true, then all free regions will be replaced with +/// a canonical var. This is used to make queries as generic as +/// possible. For example, the query `F: Foo<'static>` would be +/// canonicalized to `F: Foo<'0>`. +struct CanonicalizeAllFreeRegions(bool); + +struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> { + infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>, + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + variables: IndexVec, + indices: FxHashMap, CanonicalVar>, + var_values: IndexVec>, + canonicalize_all_free_regions: CanonicalizeAllFreeRegions, + needs_canonical_flags: TypeFlags, +} + +impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { + self.tcx + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + match *r { + ty::ReLateBound(..) => { + // leave bound regions alone + r + } + + ty::ReVar(vid) => { + let r = self.infcx + .unwrap() + .borrow_region_constraints() + .opportunistic_resolve_var(self.tcx, vid); + let info = CanonicalVarInfo { + kind: CanonicalVarKind::Region, + }; + debug!( + "canonical: region var found with vid {:?}, \ + opportunistically resolved to {:?}", + vid, r + ); + let cvar = self.canonical_var(info, Kind::from(r)); + self.tcx().mk_region(ty::ReCanonical(cvar)) + } + + ty::ReStatic + | ty::ReEarlyBound(..) + | ty::ReFree(_) + | ty::ReScope(_) + | ty::ReSkolemized(..) + | ty::ReEmpty + | ty::ReErased => { + if self.canonicalize_all_free_regions.0 { + let info = CanonicalVarInfo { + kind: CanonicalVarKind::Region, + }; + let cvar = self.canonical_var(info, Kind::from(r)); + self.tcx().mk_region(ty::ReCanonical(cvar)) + } else { + r + } + } + + ty::ReClosureBound(..) | ty::ReCanonical(_) => { + bug!("canonical region encountered during canonicalization") + } + } + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + match t.sty { + ty::TyInfer(ty::TyVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::General, t), + + ty::TyInfer(ty::IntVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Int, t), + + ty::TyInfer(ty::FloatVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Float, t), + + ty::TyInfer(ty::FreshTy(_)) + | ty::TyInfer(ty::FreshIntTy(_)) + | ty::TyInfer(ty::FreshFloatTy(_)) => { + bug!("encountered a fresh type during canonicalization") + } + + ty::TyInfer(ty::CanonicalTy(_)) => { + bug!("encountered a canonical type during canonicalization") + } + + // Replace a `()` that "would've fallen back" to `!` with just `()`. + ty::TyTuple(ref tys, true) => { + assert!(tys.is_empty()); + self.tcx().mk_nil() + } + + ty::TyClosure(..) + | ty::TyGenerator(..) + | ty::TyGeneratorWitness(..) + | ty::TyBool + | ty::TyChar + | ty::TyInt(..) + | ty::TyUint(..) + | ty::TyFloat(..) + | ty::TyAdt(..) + | ty::TyStr + | ty::TyError + | ty::TyArray(..) + | ty::TySlice(..) + | ty::TyRawPtr(..) + | ty::TyRef(..) + | ty::TyFnDef(..) + | ty::TyFnPtr(_) + | ty::TyDynamic(..) + | ty::TyNever + | ty::TyTuple(_, false) + | ty::TyProjection(..) + | ty::TyForeign(..) + | ty::TyParam(..) + | ty::TyAnon(..) => { + if t.flags.intersects(self.needs_canonical_flags) { + t.super_fold_with(self) + } else { + t + } + } + } + } +} + +impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { + /// The main `canonicalize` method, shared impl of + /// `canonicalize_query` and `canonicalize_response`. + fn canonicalize( + value: &V, + infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>, + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + canonicalize_all_free_regions: CanonicalizeAllFreeRegions, + ) -> (V::Canonicalized, CanonicalVarValues<'tcx>) + where + V: Canonicalize<'gcx, 'tcx>, + { + debug_assert!( + !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS), + "canonicalizing a canonical value: {:?}", + value, + ); + + let needs_canonical_flags = if canonicalize_all_free_regions.0 { + TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX + } else { + TypeFlags::KEEP_IN_LOCAL_TCX + }; + + let gcx = tcx.global_tcx(); + + // Fast path: nothing that needs to be canonicalized. + if !value.has_type_flags(needs_canonical_flags) { + let out_value = gcx.lift(value).unwrap(); + let canon_value = V::intern( + gcx, + Canonical { + variables: Slice::empty(), + value: out_value, + }, + ); + let values = CanonicalVarValues { var_values: IndexVec::default() }; + return (canon_value, values); + } + + let mut canonicalizer = Canonicalizer { + infcx, + tcx, + canonicalize_all_free_regions, + needs_canonical_flags, + variables: IndexVec::default(), + indices: FxHashMap::default(), + var_values: IndexVec::default(), + }; + let out_value = value.fold_with(&mut canonicalizer); + + // Once we have canonicalized `out_value`, it should not + // contain anything that ties it to this inference context + // anymore, so it should live in the global arena. + let out_value = gcx.lift(&out_value).unwrap_or_else(|| { + bug!( + "failed to lift `{:?}`, canonicalized from `{:?}`", + out_value, + value + ) + }); + + let canonical_variables = tcx.intern_canonical_var_infos(&canonicalizer.variables.raw); + + let canonical_value = V::intern( + gcx, + Canonical { + variables: canonical_variables, + value: out_value, + }, + ); + let canonical_var_values = CanonicalVarValues { + var_values: canonicalizer.var_values, + }; + (canonical_value, canonical_var_values) + } + + /// Creates a canonical variable replacing `kind` from the input, + /// or returns an existing variable if `kind` has already been + /// seen. `kind` is expected to be an unbound variable (or + /// potentially a free region). + fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> CanonicalVar { + let Canonicalizer { + indices, + variables, + var_values, + .. + } = self; + + indices + .entry(kind) + .or_insert_with(|| { + let cvar1 = variables.push(info); + let cvar2 = var_values.push(kind); + assert_eq!(cvar1, cvar2); + cvar1 + }) + .clone() + } + + /// Given a type variable `ty_var` of the given kind, first check + /// if `ty_var` is bound to anything; if so, canonicalize + /// *that*. Otherwise, create a new canonical variable for + /// `ty_var`. + fn canonicalize_ty_var(&mut self, ty_kind: CanonicalTyVarKind, ty_var: Ty<'tcx>) -> Ty<'tcx> { + let infcx = self.infcx.expect("encountered ty-var without infcx"); + let bound_to = infcx.shallow_resolve(ty_var); + if bound_to != ty_var { + self.fold_ty(bound_to) + } else { + let info = CanonicalVarInfo { + kind: CanonicalVarKind::Ty(ty_kind), + }; + let cvar = self.canonical_var(info, Kind::from(ty_var)); + self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar)) + } + } +} + +impl<'tcx, V> Canonical<'tcx, V> { + /// Instantiate the wrapped value, replacing each canonical value + /// with the value given in `var_values`. + pub fn substitute(&self, tcx: TyCtxt<'_, '_, 'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V + where + V: TypeFoldable<'tcx>, + { + assert_eq!(self.variables.len(), var_values.var_values.len()); + self.value + .fold_with(&mut CanonicalVarValuesSubst { tcx, var_values }) + } +} + +struct CanonicalVarValuesSubst<'cx, 'gcx: 'tcx, 'tcx: 'cx> { + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + var_values: &'cx CanonicalVarValues<'tcx>, +} + +impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'gcx, 'tcx> { + fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> { + self.tcx + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + match t.sty { + ty::TyInfer(ty::InferTy::CanonicalTy(c)) => { + match self.var_values.var_values[c].unpack() { + UnpackedKind::Type(ty) => ty, + r => bug!("{:?} is a type but value is {:?}", c, r), + } + } + _ => t.super_fold_with(self), + } + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + match r { + ty::RegionKind::ReCanonical(c) => match self.var_values.var_values[*c].unpack() { + UnpackedKind::Lifetime(l) => l, + r => bug!("{:?} is a region but value is {:?}", c, r), + }, + _ => r.super_fold_with(self), + } + } +} + +CloneTypeFoldableAndLiftImpls! { + for <'tcx> { + ::infer::canonical::Certainty, + ::infer::canonical::CanonicalVarInfo, + ::infer::canonical::CanonicalVarInfos<'tcx>, + ::infer::canonical::CanonicalVarKind, + } +} + +BraceStructTypeFoldableImpl! { + impl<'tcx, C> TypeFoldable<'tcx> for Canonical<'tcx, C> { + variables, + value, + } where C: TypeFoldable<'tcx> +} + +impl<'tcx> CanonicalVarValues<'tcx> { + fn iter<'a>(&'a self) -> impl Iterator> + 'a { + self.var_values.iter().cloned() + } + + fn len(&self) -> usize { + self.var_values.len() + } +} + +impl<'a, 'tcx> IntoIterator for &'a CanonicalVarValues<'tcx> { + type Item = Kind<'tcx>; + type IntoIter = ::std::iter::Cloned<::std::slice::Iter<'a, Kind<'tcx>>>; + + fn into_iter(self) -> Self::IntoIter { + self.var_values.iter().cloned() + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for CanonicalVarValues<'a> { + type Lifted = CanonicalVarValues<'tcx>; + var_values, + } +} + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for CanonicalVarValues<'tcx> { + var_values, + } +} + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> { + region_outlives, ty_outlives + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> { + type Lifted = QueryRegionConstraints<'tcx>; + region_outlives, ty_outlives + } +} + +BraceStructTypeFoldableImpl! { + impl<'tcx, R> TypeFoldable<'tcx> for QueryResult<'tcx, R> { + var_values, region_constraints, certainty, value + } where R: TypeFoldable<'tcx>, +} + +BraceStructLiftImpl! { + impl<'a, 'tcx, R> Lift<'tcx> for QueryResult<'a, R> { + type Lifted = QueryResult<'tcx, R::Lifted>; + var_values, region_constraints, certainty, value + } where R: Lift<'tcx> +} diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs index 469cb4591124..1c581c44464e 100644 --- a/src/librustc/infer/combine.rs +++ b/src/librustc/infer/combine.rs @@ -476,6 +476,7 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, ' } } + ty::ReCanonical(..) | ty::ReClosureBound(..) => { span_bug!( self.span, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 07551c4ebd31..96c230988210 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -154,6 +154,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } // We shouldn't encounter an error message with ReClosureBound. + ty::ReCanonical(..) | ty::ReClosureBound(..) => { bug!("encountered unexpected ReClosureBound: {:?}", region,); } diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs index ee0921f4b07a..6074bfd083d4 100644 --- a/src/librustc/infer/freshen.rs +++ b/src/librustc/infer/freshen.rs @@ -114,9 +114,10 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { self.tcx().types.re_erased } + ty::ReCanonical(..) | ty::ReClosureBound(..) => { bug!( - "encountered unexpected ReClosureBound: {:?}", + "encountered unexpected region: {:?}", r, ); } @@ -170,6 +171,9 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> { t } + ty::TyInfer(ty::CanonicalTy(..)) => + bug!("encountered canonical ty during freshening"), + ty::TyGenerator(..) | ty::TyBool | ty::TyChar | diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 3ac4ec5bee41..00b2ac7449f7 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -258,6 +258,8 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { let tcx = self.region_rels.tcx; match (a, b) { + (&ty::ReCanonical(..), _) | + (_, &ty::ReCanonical(..)) | (&ty::ReClosureBound(..), _) | (_, &ty::ReClosureBound(..)) | (&ReLateBound(..), _) | diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 5f0c2d1e76bc..5127807bf70d 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -50,6 +50,7 @@ use self::unify_key::ToType; pub mod anon_types; pub mod at; +pub mod canonical; mod combine; mod equate; pub mod error_reporting; @@ -473,6 +474,12 @@ impl<'tcx, T> InferOk<'tcx, T> { } } +impl<'tcx> InferOk<'tcx, ()> { + pub fn into_obligations(self) -> PredicateObligations<'tcx> { + self.obligations + } +} + #[must_use = "once you start a snapshot, you should always consume it"] pub struct CombinedSnapshot<'a, 'tcx:'a> { projection_cache_snapshot: traits::ProjectionCacheSnapshot, @@ -1644,4 +1651,3 @@ impl<'tcx> fmt::Debug for RegionObligation<'tcx> { self.sup_type) } } - diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2cf176036296..77b3a87c0ed1 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -57,9 +57,9 @@ #![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![cfg_attr(windows, feature(libc))] +#![feature(match_default_bindings)] #![feature(macro_lifetime_matcher)] #![feature(macro_vis_matcher)] -#![feature(match_default_bindings)] #![feature(never_type)] #![feature(non_exhaustive)] #![feature(nonzero)] diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index 6013e3aef81e..d8a723e184d2 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -119,6 +119,25 @@ macro_rules! impl_stable_hash_for { } } }; + + (impl<$tcx:lifetime $(, $T:ident)*> for struct $struct_name:path { + $($field:ident),* $(,)* + }) => { + impl<'a, $tcx, $($T,)*> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name + where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),* + { + #[inline] + fn hash_stable(&self, + __ctx: &mut $crate::ich::StableHashingContext<'a>, + __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher) { + let $struct_name { + $(ref $field),* + } = *self; + + $( $field.hash_stable(__ctx, __hasher));* + } + } + }; } #[macro_export] diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 01e1037b6222..7b4211e487a0 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -173,6 +173,8 @@ pub struct PerfStats { pub symbol_hash_time: Cell, /// The accumulated time spent decoding def path tables from metadata pub decode_def_path_tables_time: Cell, + /// Total number of values canonicalized queries constructed. + pub queries_canonicalized: Cell, } /// Enum to support dispatch of one-time diagnostics (in Session.diag_once) @@ -858,6 +860,8 @@ impl Session { "Total time spent decoding DefPath tables: {}", duration_to_secs_str(self.perf_stats.decode_def_path_tables_time.get()) ); + println!("Total queries canonicalized: {}", + self.perf_stats.queries_canonicalized.get()); } /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n. @@ -1144,6 +1148,7 @@ pub fn build_session_( incr_comp_bytes_hashed: Cell::new(0), symbol_hash_time: Cell::new(Duration::from_secs(0)), decode_def_path_tables_time: Cell::new(Duration::from_secs(0)), + queries_canonicalized: Cell::new(0), }, code_stats: RefCell::new(CodeStats::new()), optimization_fuel_crate, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 728702ef61fd..f2f54dcedfd6 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2083,9 +2083,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyProjection(_) | ty::TyParam(_) | ty::TyAnon(..) => None, ty::TyInfer(ty::TyVar(_)) => Ambiguous, - ty::TyInfer(ty::FreshTy(_)) - | ty::TyInfer(ty::FreshIntTy(_)) - | ty::TyInfer(ty::FreshFloatTy(_)) => { + ty::TyInfer(ty::CanonicalTy(_)) | + ty::TyInfer(ty::FreshTy(_)) | + ty::TyInfer(ty::FreshIntTy(_)) | + ty::TyInfer(ty::FreshFloatTy(_)) => { bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); } @@ -2154,9 +2155,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Ambiguous } - ty::TyInfer(ty::FreshTy(_)) - | ty::TyInfer(ty::FreshIntTy(_)) - | ty::TyInfer(ty::FreshFloatTy(_)) => { + ty::TyInfer(ty::CanonicalTy(_)) | + ty::TyInfer(ty::FreshTy(_)) | + ty::TyInfer(ty::FreshIntTy(_)) | + ty::TyInfer(ty::FreshFloatTy(_)) => { bug!("asked to assemble builtin bounds of unexpected type: {:?}", self_ty); } @@ -2195,6 +2197,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyParam(..) | ty::TyForeign(..) | ty::TyProjection(..) | + ty::TyInfer(ty::CanonicalTy(_)) | ty::TyInfer(ty::TyVar(_)) | ty::TyInfer(ty::FreshTy(_)) | ty::TyInfer(ty::FreshIntTy(_)) | diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index e7d6bdd3383d..24d3b37f804e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -23,6 +23,7 @@ use hir::map as hir_map; use hir::map::DefPathHash; use lint::{self, Lint}; use ich::{StableHashingContext, NodeIdHashingMode}; +use infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; use infer::outlives::free_region_map::FreeRegionMap; use middle::const_val::ConstVal; use middle::cstore::{CrateStore, LinkMeta}; @@ -131,6 +132,7 @@ pub struct CtxtInterners<'tcx> { type_: RefCell>>>, type_list: RefCell>>>>, substs: RefCell>>>, + canonical_var_infos: RefCell>>>, region: RefCell>>, existential_predicates: RefCell>>>>, predicates: RefCell>>>>, @@ -146,6 +148,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { substs: RefCell::new(FxHashSet()), region: RefCell::new(FxHashSet()), existential_predicates: RefCell::new(FxHashSet()), + canonical_var_infos: RefCell::new(FxHashSet()), predicates: RefCell::new(FxHashSet()), const_: RefCell::new(FxHashSet()), } @@ -1838,6 +1841,12 @@ impl<'tcx: 'lcx, 'lcx> Borrow<[Ty<'lcx>]> for Interned<'tcx, Slice>> { } } +impl<'tcx: 'lcx, 'lcx> Borrow<[CanonicalVarInfo]> for Interned<'tcx, Slice> { + fn borrow<'a>(&'a self) -> &'a [CanonicalVarInfo] { + &self.0[..] + } +} + impl<'tcx: 'lcx, 'lcx> Borrow<[Kind<'lcx>]> for Interned<'tcx, Substs<'tcx>> { fn borrow<'a>(&'a self) -> &'a [Kind<'lcx>] { &self.0[..] @@ -1970,6 +1979,22 @@ slice_interners!( substs: _intern_substs(Kind) ); +// This isn't a perfect fit: CanonicalVarInfo slices are always +// allocated in the global arena, so this `intern_method!` macro is +// overly general. But we just return false for the code that checks +// whether they belong in the thread-local arena, so no harm done, and +// seems better than open-coding the rest. +intern_method! { + 'tcx, + canonical_var_infos: _intern_canonical_var_infos( + &[CanonicalVarInfo], + alloc_slice, + Deref::deref, + |xs: &[CanonicalVarInfo]| -> &Slice { unsafe { mem::transmute(xs) } }, + |_xs: &[CanonicalVarInfo]| -> bool { false } + ) -> Slice +} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Given a `fn` type, returns an equivalent `unsafe fn` type; /// that is, a `fn` type that is equivalent in every way for being @@ -2257,6 +2282,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'gcx> { + if ts.len() == 0 { + Slice::empty() + } else { + self.global_tcx()._intern_canonical_var_infos(ts) + } + } + pub fn mk_fn_sig(self, inputs: I, output: I::Item, diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index dcb70a8f86a8..8a0253ed2f11 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -220,6 +220,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { ty::TyInfer(ty::TyVar(_)) => "inferred type".to_string(), ty::TyInfer(ty::IntVar(_)) => "integral variable".to_string(), ty::TyInfer(ty::FloatVar(_)) => "floating-point variable".to_string(), + ty::TyInfer(ty::CanonicalTy(_)) | ty::TyInfer(ty::FreshTy(_)) => "skolemized type".to_string(), ty::TyInfer(ty::FreshIntTy(_)) => "skolemized integral type".to_string(), ty::TyInfer(ty::FreshFloatTy(_)) => "skolemized floating-point type".to_string(), diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index f067789771c5..cae64fd4c95c 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -112,8 +112,16 @@ impl FlagComputation { match infer { ty::FreshTy(_) | ty::FreshIntTy(_) | - ty::FreshFloatTy(_) => {} - _ => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX) + ty::FreshFloatTy(_) | + ty::CanonicalTy(_) => { + self.add_flags(TypeFlags::HAS_CANONICAL_VARS); + } + + ty::TyVar(_) | + ty::IntVar(_) | + ty::FloatVar(_) => { + self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX) + } } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e3405e0c3b36..93d1585cdc83 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -60,7 +60,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, use hir; -pub use self::sty::{Binder, DebruijnIndex}; +pub use self::sty::{Binder, CanonicalVar, DebruijnIndex}; pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig}; pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate}; pub use self::sty::{ClosureSubsts, GeneratorInterior, TypeAndMut}; @@ -452,6 +452,10 @@ bitflags! { // Currently we can't normalize projections w/ bound regions. const HAS_NORMALIZABLE_PROJECTION = 1 << 12; + // Set if this includes a "canonical" type or region var -- + // ought to be true only for the results of canonicalization. + const HAS_CANONICAL_VARS = 1 << 13; + const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits | TypeFlags::HAS_SELF.bits | TypeFlags::HAS_RE_EARLY_BOUND.bits; @@ -470,7 +474,8 @@ bitflags! { TypeFlags::HAS_PROJECTION.bits | TypeFlags::HAS_TY_CLOSURE.bits | TypeFlags::HAS_LOCAL_NAMES.bits | - TypeFlags::KEEP_IN_LOCAL_TCX.bits; + TypeFlags::KEEP_IN_LOCAL_TCX.bits | + TypeFlags::HAS_CANONICAL_VARS.bits; } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 7bcc816b5f03..109422564c84 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1047,6 +1047,9 @@ pub enum RegionKind { /// `ClosureRegionRequirements` that are produced by MIR borrowck. /// See `ClosureRegionRequirements` for more details. ReClosureBound(RegionVid), + + /// Canonicalized region, used only when preparing a trait query. + ReCanonical(CanonicalVar), } impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {} @@ -1091,8 +1094,13 @@ pub enum InferTy { FreshTy(u32), FreshIntTy(u32), FreshFloatTy(u32), + + /// Canonicalized type variable, used only when preparing a trait query. + CanonicalTy(CanonicalVar), } +newtype_index!(CanonicalVar); + /// A `ProjectionPredicate` for an `ExistentialTraitRef`. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct ExistentialProjection<'tcx> { @@ -1213,6 +1221,10 @@ impl RegionKind { } ty::ReErased => { } + ty::ReCanonical(..) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_CANONICAL_VARS; + } ty::ReClosureBound(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index e70c72335aa3..a301049fe1c4 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -40,6 +40,7 @@ const TAG_MASK: usize = 0b11; const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; +#[derive(Debug)] pub enum UnpackedKind<'tcx> { Lifetime(ty::Region<'tcx>), Type(Ty<'tcx>), diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index a7ee8579fb98..e8ce49d39d29 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -834,6 +834,9 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> ty::ReEmpty => { // No variant fields to hash for these ... } + ty::ReCanonical(c) => { + self.hash(c); + } ty::ReLateBound(db, ty::BrAnon(i)) => { self.hash(db.depth); self.hash(i); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 5e2792ee6410..efa53c775ae2 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -721,6 +721,9 @@ define_print! { ty::ReEarlyBound(ref data) => { write!(f, "{}", data.name) } + ty::ReCanonical(_) => { + write!(f, "'_") + } ty::ReLateBound(_, br) | ty::ReFree(ty::FreeRegion { bound_region: br, .. }) | ty::ReSkolemized(_, br) => { @@ -785,6 +788,10 @@ define_print! { write!(f, "{:?}", vid) } + ty::ReCanonical(c) => { + write!(f, "'?{}", c.index()) + } + ty::ReSkolemized(id, ref bound_region) => { write!(f, "ReSkolemized({:?}, {:?})", id, bound_region) } @@ -888,6 +895,7 @@ define_print! { ty::TyVar(_) => write!(f, "_"), ty::IntVar(_) => write!(f, "{}", "{integer}"), ty::FloatVar(_) => write!(f, "{}", "{float}"), + ty::CanonicalTy(_) => write!(f, "_"), ty::FreshTy(v) => write!(f, "FreshTy({})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v) @@ -899,6 +907,7 @@ define_print! { ty::TyVar(ref v) => write!(f, "{:?}", v), ty::IntVar(ref v) => write!(f, "{:?}", v), ty::FloatVar(ref v) => write!(f, "{:?}", v), + ty::CanonicalTy(v) => write!(f, "?{:?}", v.index()), ty::FreshTy(v) => write!(f, "FreshTy({:?})", v), ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v), ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v) diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 9888b2fffc77..a01b3cbf47be 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -427,6 +427,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { // These cannot exist in borrowck RegionKind::ReVar(..) | + RegionKind::ReCanonical(..) | RegionKind::ReSkolemized(..) | RegionKind::ReClosureBound(..) | RegionKind::ReErased => span_bug!(borrow_span, diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 5cbe2822e5c0..49234f4ed7fd 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -366,6 +366,7 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { ty::ReStatic => self.item_ub, + ty::ReCanonical(_) | ty::ReEmpty | ty::ReClosureBound(..) | ty::ReLateBound(..) | diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index 9d636b48bd0c..459aa9ea488f 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -23,6 +23,7 @@ #![feature(slice_patterns)] #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(macro_lifetime_matcher)] #![feature(i128_type)] #![feature(from_ref)] diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index 11c2bd736876..a5b1a7e57ab4 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -330,7 +330,7 @@ macro_rules! newtype_index { ); } -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, Hash)] pub struct IndexVec { pub raw: Vec, _marker: PhantomData diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index da0da622d521..f77c22bd8954 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -18,7 +18,9 @@ #![feature(fs_read_write)] #![feature(i128_type)] #![feature(libc)] +#![feature(macro_lifetime_matcher)] #![feature(proc_macro_internals)] +#![feature(macro_lifetime_matcher)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(specialization)] diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 7ab52e98a0ee..84ba13674505 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -457,6 +457,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { (RegionKind::ReLateBound(_, _), _) | (RegionKind::ReSkolemized(_, _), _) | (RegionKind::ReClosureBound(_), _) + | (RegionKind::ReCanonical(_), _) | (RegionKind::ReErased, _) => { span_bug!(drop_span, "region does not make sense in this context"); } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 490dc4e5ac4a..953747756517 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -13,6 +13,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] #![feature(custom_attribute)] +#![feature(macro_lifetime_matcher)] #![allow(unused_attributes)] #[macro_use] diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 44ac7a10e828..2a4e92034de8 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -423,6 +423,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // way early-bound regions do, so we skip them here. } + ty::ReCanonical(_) | ty::ReFree(..) | ty::ReClosureBound(..) | ty::ReScope(..) | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5d4addce2c43..ff281a53ab7e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1490,6 +1490,7 @@ impl Clean> for ty::RegionKind { ty::ReSkolemized(..) | ty::ReEmpty | ty::ReClosureBound(_) | + ty::ReCanonical(_) | ty::ReErased => None } } From 8c024fdafb6339c5375543ef400a33419d65a19b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 23 Feb 2018 15:30:27 -0500 Subject: [PATCH 146/830] in `Foo(X)` dep-nodes, allow X to be a `ty` not a `tt` Before, the identifier `X` was also used when generating a pattern to match against the dep-node. So `Foo(DefId)` would generate a match pattern like: match foo { Foo(DefId) => ... } This does not scale to more general types like `&'tcx Ty<'tcx>`. Therefore, we now require *exactly one* argument (the macro was internally tupling anyway, and no actual nodes use more than one argument), and then we can generate a fixed pattern like: match foo { Foo(arg) => ... } Huzzah. (Also, hygiene is nice.) --- src/librustc/dep_graph/dep_node.rs | 45 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 7d8709a82f4d..6a2c003179a1 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -80,6 +80,10 @@ macro_rules! erase { ($x:tt) => ({}) } +macro_rules! replace { + ($x:tt with $($y:tt)*) => ($($y)*) +} + macro_rules! is_anon_attr { (anon) => (true); ($attr:ident) => (false); @@ -111,7 +115,7 @@ macro_rules! define_dep_nodes { (<$tcx:tt> $( [$($attr:ident),* ] - $variant:ident $(( $($tuple_arg:tt),* ))* + $variant:ident $(( $tuple_arg_ty:ty $(,)* ))* $({ $($struct_arg_name:ident : $struct_arg_ty:ty),* })* ,)* ) => ( @@ -134,7 +138,7 @@ macro_rules! define_dep_nodes { // tuple args $({ - return <( $($tuple_arg,)* ) as DepNodeParams> + return <$tuple_arg_ty as DepNodeParams> ::CAN_RECONSTRUCT_QUERY_KEY; })* @@ -186,7 +190,7 @@ macro_rules! define_dep_nodes { DepKind :: $variant => { // tuple args $({ - $(erase!($tuple_arg);)* + erase!($tuple_arg_ty); return true; })* @@ -205,7 +209,7 @@ macro_rules! define_dep_nodes { pub enum DepConstructor<$tcx> { $( - $variant $(( $($tuple_arg),* ))* + $variant $(( $tuple_arg_ty ))* $({ $($struct_arg_name : $struct_arg_ty),* })* ),* } @@ -227,15 +231,14 @@ macro_rules! define_dep_nodes { { match dep { $( - DepConstructor :: $variant $(( $($tuple_arg),* ))* + DepConstructor :: $variant $(( replace!(($tuple_arg_ty) with arg) ))* $({ $($struct_arg_name),* })* => { // tuple args $({ - let tupled_args = ( $($tuple_arg,)* ); - let hash = DepNodeParams::to_fingerprint(&tupled_args, - tcx); + erase!($tuple_arg_ty); + let hash = DepNodeParams::to_fingerprint(&arg, tcx); let dep_node = DepNode { kind: DepKind::$variant, hash @@ -247,7 +250,7 @@ macro_rules! define_dep_nodes { tcx.sess.opts.debugging_opts.query_dep_graph) { tcx.dep_graph.register_dep_node_debug_str(dep_node, || { - tupled_args.to_debug_str(tcx) + arg.to_debug_str(tcx) }); } @@ -679,43 +682,43 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T } } -impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) { +impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefId { const CAN_RECONSTRUCT_QUERY_KEY: bool = true; fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint { - tcx.def_path_hash(self.0).0 + tcx.def_path_hash(*self).0 } fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { - tcx.item_path_str(self.0) + tcx.item_path_str(*self) } } -impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIndex,) { +impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for DefIndex { const CAN_RECONSTRUCT_QUERY_KEY: bool = true; fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint { - tcx.hir.definitions().def_path_hash(self.0).0 + tcx.hir.definitions().def_path_hash(*self).0 } fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { - tcx.item_path_str(DefId::local(self.0)) + tcx.item_path_str(DefId::local(*self)) } } -impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (CrateNum,) { +impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for CrateNum { const CAN_RECONSTRUCT_QUERY_KEY: bool = true; fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint { let def_id = DefId { - krate: self.0, + krate: *self, index: CRATE_DEF_INDEX, }; tcx.def_path_hash(def_id).0 } fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { - tcx.crate_name(self.0).as_str().to_string() + tcx.crate_name(*self).as_str().to_string() } } @@ -743,17 +746,17 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, De } } -impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (HirId,) { +impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for HirId { const CAN_RECONSTRUCT_QUERY_KEY: bool = false; // We actually would not need to specialize the implementation of this // method but it's faster to combine the hashes than to instantiate a full // hashing context and stable-hashing state. fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint { - let (HirId { + let HirId { owner, local_id: ItemLocalId(local_id), - },) = *self; + } = *self; let def_path_hash = tcx.def_path_hash(DefId::local(owner)); let local_id = Fingerprint::from_smaller_hash(local_id as u64); From 0d88db1693a07095555d07d14ffdcb373b6bc352 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 13 Mar 2018 16:21:54 +0100 Subject: [PATCH 147/830] Reuse the query caching infrastructure for const eval --- src/librustc/ty/maps/config.rs | 6 +-- src/librustc/ty/maps/on_disk_cache.rs | 63 +++--------------------- src/librustc_mir/interpret/const_eval.rs | 8 ++- 3 files changed, 16 insertions(+), 61 deletions(-) diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 7e2ece1b334b..bcd58e993044 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -158,15 +158,15 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { } #[inline] - fn cache_on_disk(key: Self::Key) -> bool { - key.value.instance.def_id().is_local() + fn cache_on_disk(_key: Self::Key) -> bool { + true } #[inline] fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: SerializedDepNodeIndex) -> Option { - tcx.on_disk_query_result_cache.load_constant(tcx, id).map(Ok) + tcx.on_disk_query_result_cache.try_load_query_result(tcx, id).map(Ok) } } diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index bb0b1975b9e4..35e874b74d9a 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -75,10 +75,6 @@ pub struct OnDiskCache<'sess> { // A map from dep-node to the position of any associated diagnostics in // `serialized_data`. prev_diagnostics_index: FxHashMap, - - // A map from dep-node to the position of any associated constants in - // `serialized_data`. - prev_constants_index: FxHashMap, } // This type is used only for (de-)serialization. @@ -88,10 +84,8 @@ struct Footer { prev_cnums: Vec<(u32, String, CrateDisambiguator)>, query_result_index: EncodedQueryResultIndex, diagnostics_index: EncodedQueryResultIndex, - constants_index: EncodedConstantsIndex, } -type EncodedConstantsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnostics = Vec; @@ -145,7 +139,6 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: RefCell::new(FxHashMap()), query_result_index: footer.query_result_index.into_iter().collect(), prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(), - prev_constants_index: footer.constants_index.into_iter().collect(), synthetic_expansion_infos: RefCell::new(FxHashMap()), } } @@ -161,7 +154,6 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: RefCell::new(FxHashMap()), query_result_index: FxHashMap(), prev_diagnostics_index: FxHashMap(), - prev_constants_index: FxHashMap(), synthetic_expansion_infos: RefCell::new(FxHashMap()), } } @@ -229,46 +221,25 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; - } - // encode successful constant evaluations - let constants_index = { - let mut constants_index = EncodedConstantsIndex::new(); - use ty::maps::queries::const_eval; + // const eval is special, it only encodes successfully evaluated constants use ty::maps::plumbing::GetCacheInternal; - use ty::maps::config::QueryDescription; for (key, entry) in const_eval::get_cache_internal(tcx).map.iter() { - if let Ok(ref constant) = entry.value { - if const_eval::cache_on_disk(key.clone()) { - trace!("caching constant {:?} with value {:#?}", key, constant); + use ty::maps::config::QueryDescription; + if const_eval::cache_on_disk(key.clone()) { + if let Ok(ref value) = entry.value { let dep_node = SerializedDepNodeIndex::new(entry.index.index()); // Record position of the cache entry - constants_index.push(( - dep_node, - AbsoluteBytePos::new(encoder.position()), - )); - let did = key.value.instance.def_id(); - let constant = if key.value.promoted.is_none() - && tcx.is_static(did).is_some() { - // memorize the allocation for the static, too, so - // we can refer to the static, not just read its value - // since we have had a successful query, the cached value must - // exist, so we can unwrap it - let cached = tcx.interpret_interner.get_cached(did).unwrap(); - (constant, Some(cached)) - } else { - (constant, None) - }; + qri.push((dep_node, AbsoluteBytePos::new(enc.position()))); // Encode the type check tables with the SerializedDepNodeIndex // as tag. - encoder.encode_tagged(dep_node, &constant)?; + enc.encode_tagged(dep_node, value)?; } } } - constants_index - }; + } // Encode diagnostics let diagnostics_index = { @@ -303,7 +274,6 @@ impl<'sess> OnDiskCache<'sess> { prev_cnums, query_result_index, diagnostics_index, - constants_index, })?; // Encode the position of the footer as the last 8 bytes of the @@ -326,25 +296,6 @@ impl<'sess> OnDiskCache<'sess> { }) } - /// Load a constant emitted during the previous compilation session. - pub fn load_constant<'a, 'tcx>(&self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - dep_node_index: SerializedDepNodeIndex) - -> Option<&'tcx ty::Const<'tcx>> { - type Encoded<'tcx> = (ty::Const<'tcx>, Option); - let constant: Option> = self.load_indexed( - tcx, - dep_node_index, - &self.prev_constants_index, - "constants"); - - constant.map(|(c, _alloc_id)| { - // the AllocId decoding already registers the AllocId to its DefId - // so we don't need to take additional actions here - tcx.mk_const(c) - }) - } - /// Load a diagnostic emitted during the previous compilation session. pub fn load_diagnostics<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index ee5874be9d70..82eb28287b03 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -110,6 +110,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>( span = mir.span; let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?; let alloc = tcx.interpret_interner.get_cached(cid.instance.def_id()); + let is_static = tcx.is_static(cid.instance.def_id()).is_some(); let alloc = match alloc { Some(alloc) => { assert!(cid.promoted.is_none()); @@ -123,7 +124,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>( layout.align, None, )?; - if tcx.is_static(cid.instance.def_id()).is_some() { + if is_static { tcx.interpret_interner.cache(cid.instance.def_id(), ptr.alloc_id); } let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span); @@ -151,8 +152,11 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>( } }; let ptr = MemoryPointer::new(alloc, 0).into(); + // always try to read the value and report errors let value = match ecx.try_read_value(ptr, layout.align, layout.ty)? { - Some(val) => val, + // if it's a constant (so it needs no address, directly compute its value) + Some(val) if !is_static => val, + // point at the allocation _ => Value::ByRef(ptr, layout.align), }; Ok((value, ptr, layout.ty)) From 3a50b41da4cbb135fc74cdc8ebf2b09edb396f87 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 25 Feb 2018 10:58:54 -0500 Subject: [PATCH 148/830] introduce `infcx.at(..).normalize(..)` operation [VIC] It is backed by the new `normalize_projection_ty` query, which uses canonicalization. --- src/Cargo.lock | 14 + src/librustc/dep_graph/dep_node.rs | 6 +- src/librustc/infer/at.rs | 6 +- src/librustc/infer/mod.rs | 11 + src/librustc/infer/outlives/obligations.rs | 10 + src/librustc/infer/region_constraints/mod.rs | 4 + src/librustc/session/mod.rs | 11 + src/librustc/traits/mod.rs | 2 + src/librustc/traits/query/mod.rs | 31 ++ src/librustc/traits/query/normalize.rs | 268 ++++++++++++++++++ src/librustc/ty/context.rs | 1 + src/librustc/ty/maps/config.rs | 10 + src/librustc/ty/maps/keys.rs | 11 + src/librustc/ty/maps/mod.rs | 12 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_driver/Cargo.toml | 1 + src/librustc_driver/driver.rs | 2 + src/librustc_driver/lib.rs | 1 + .../borrow_check/nll/type_check/mod.rs | 18 +- src/librustc_traits/Cargo.toml | 18 ++ src/librustc_traits/lib.rs | 37 +++ .../normalize_projection_ty.rs | 55 ++++ src/librustc_traits/util.rs | 117 ++++++++ 23 files changed, 637 insertions(+), 10 deletions(-) create mode 100644 src/librustc/traits/query/mod.rs create mode 100644 src/librustc/traits/query/normalize.rs create mode 100644 src/librustc_traits/Cargo.toml create mode 100644 src/librustc_traits/lib.rs create mode 100644 src/librustc_traits/normalize_projection_ty.rs create mode 100644 src/librustc_traits/util.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index f8c04fe9272a..ed32984bb584 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1884,6 +1884,7 @@ dependencies = [ "rustc_privacy 0.0.0", "rustc_resolve 0.0.0", "rustc_save_analysis 0.0.0", + "rustc_traits 0.0.0", "rustc_trans_utils 0.0.0", "rustc_typeck 0.0.0", "serialize 0.0.0", @@ -2068,6 +2069,19 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "rustc_traits" +version = "0.0.0" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "graphviz 0.0.0", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc 0.0.0", + "rustc_data_structures 0.0.0", + "syntax 0.0.0", + "syntax_pos 0.0.0", +] + [[package]] name = "rustc_trans" version = "0.0.0" diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 6a2c003179a1..caef3a8acc44 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -67,11 +67,12 @@ use hir::{HirId, ItemLocalId}; use ich::{Fingerprint, StableHashingContext}; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; -use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty}; -use ty::subst::Substs; use std::fmt; use std::hash::Hash; use syntax_pos::symbol::InternedString; +use traits::query::CanonicalProjectionGoal; +use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty}; +use ty::subst::Substs; // erase!() just makes tokens go away. It's used to specify which macro argument // is repeated (i.e. which sub-expression of the macro we are in) but don't need @@ -635,6 +636,7 @@ define_dep_nodes!( <'tcx> [] CompileCodegenUnit(InternedString), [input] OutputFilenames, [anon] NormalizeTy, + [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>), [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) }, diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs index d9fbf4aa5148..89dbc76c8a65 100644 --- a/src/librustc/infer/at.rs +++ b/src/librustc/infer/at.rs @@ -40,9 +40,9 @@ use super::*; use ty::relate::{Relate, TypeRelation}; pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> { - infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, - cause: &'a ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, + pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, + pub cause: &'a ObligationCause<'tcx>, + pub param_env: ty::ParamEnv<'tcx>, } pub struct Trace<'a, 'gcx: 'tcx, 'tcx: 'a> { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 5127807bf70d..2c58e17b2833 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -69,6 +69,7 @@ pub mod type_variable; pub mod unify_key; #[must_use] +#[derive(Debug)] pub struct InferOk<'tcx, T> { pub value: T, pub obligations: PredicateObligations<'tcx>, @@ -1224,6 +1225,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.borrow_region_constraints().take_and_reset_data() } + /// Gives temporary access to the region constraint data. + #[allow(non_camel_case_types)] // bug with impl trait + pub fn with_region_constraints( + &self, + op: impl FnOnce(&RegionConstraintData<'tcx>) -> R, + ) -> R { + let region_constraints = self.borrow_region_constraints(); + op(region_constraints.data()) + } + /// Takes ownership of the list of variable regions. This implies /// that all the region constriants have already been taken, and /// hence that `resolve_regions_and_report_errors` can never be diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index 36e657f78b4b..e5461685bd47 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -99,6 +99,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { .push((body_id, obligation)); } + /// Trait queries just want to pass back type obligations "as is" + pub fn take_registered_region_obligations( + &self, + ) -> Vec<(ast::NodeId, RegionObligation<'tcx>)> { + ::std::mem::replace( + &mut *self.region_obligations.borrow_mut(), + vec![], + ) + } + /// Process the region obligations that must be proven (during /// `regionck`) for the given `body_id`, given information about /// the region bounds in scope and so forth. This function must be diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index ed89d1d2f57a..0c8e49fda184 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -350,6 +350,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> { mem::replace(data, RegionConstraintData::default()) } + pub fn data(&self) -> &RegionConstraintData<'tcx> { + &self.data + } + fn in_snapshot(&self) -> bool { !self.undo_log.is_empty() } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 7b4211e487a0..b986445ff849 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -175,6 +175,11 @@ pub struct PerfStats { pub decode_def_path_tables_time: Cell, /// Total number of values canonicalized queries constructed. pub queries_canonicalized: Cell, + /// Number of times we canonicalized a value and found that the + /// result had already been canonicalized. + pub canonicalized_values_allocated: Cell, + /// Number of times this query is invoked. + pub normalize_projection_ty: Cell, } /// Enum to support dispatch of one-time diagnostics (in Session.diag_once) @@ -862,6 +867,10 @@ impl Session { ); println!("Total queries canonicalized: {}", self.perf_stats.queries_canonicalized.get()); + println!("Total canonical values interned: {}", + self.perf_stats.canonicalized_values_allocated.get()); + println!("normalize_projection_ty: {}", + self.perf_stats.normalize_projection_ty.get()); } /// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n. @@ -1149,6 +1158,8 @@ pub fn build_session_( symbol_hash_time: Cell::new(Duration::from_secs(0)), decode_def_path_tables_time: Cell::new(Duration::from_secs(0)), queries_canonicalized: Cell::new(0), + canonicalized_values_allocated: Cell::new(0), + normalize_projection_ty: Cell::new(0), }, code_stats: RefCell::new(CodeStats::new()), optimization_fuel_crate, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 4450c60b68d3..3e23e3823470 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -63,6 +63,8 @@ mod structural_impls; pub mod trans; mod util; +pub mod query; + // Whether to enable bug compatibility with issue #43355 #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum IntercrateMode { diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs new file mode 100644 index 000000000000..bba2c1555832 --- /dev/null +++ b/src/librustc/traits/query/mod.rs @@ -0,0 +1,31 @@ +// Copyright 2014 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. + +//! Experimental types for the trait query interface. The methods +//! defined in this module are all based on **canonicalization**, +//! which makes a canonical query by replacing unbound inference +//! variables and regions, so that results can be reused more broadly. +//! The providers for the queries defined here can be found in +//! `librustc_traits`. + +use infer::canonical::Canonical; +use ty; + +pub mod normalize; + +pub type CanonicalProjectionGoal<'tcx> = + Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub struct NoSolution; + +pub type Fallible = Result; + +impl_stable_hash_for!(struct NoSolution { }); diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs new file mode 100644 index 000000000000..030e630f23f8 --- /dev/null +++ b/src/librustc/traits/query/normalize.rs @@ -0,0 +1,268 @@ +// Copyright 2014 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. + +//! Code for the 'normalization' query. This consists of a wrapper +//! which folds deeply, invoking the underlying +//! `normalize_projection_ty` query when it encounters projections. + +use infer::{InferCtxt, InferOk}; +use infer::at::At; +use infer::canonical::{Canonical, Canonicalize, QueryResult}; +use middle::const_val::ConstVal; +use mir::interpret::GlobalId; +use std::rc::Rc; +use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; +use traits::query::CanonicalProjectionGoal; +use traits::project::Normalized; +use ty::{self, Ty, TyCtxt}; +use ty::fold::{TypeFoldable, TypeFolder}; +use ty::subst::{Subst, Substs}; + +use super::NoSolution; + +impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { + /// Normalize `value` in the context of the inference context, + /// yielding a resulting type, or an error if `value` cannot be + /// normalized. If you don't care about regions, you should prefer + /// `normalize_erasing_regions`, which is more efficient. + /// + /// If the normalization succeeds and is unambigious, returns back + /// the normalized value along with various outlives relations (in + /// the form of obligations that must be discharged). + /// + /// NB. This will *eventually* be the main means of + /// normalizing, but for now should be used only when we actually + /// know that normalization will succeed, since error reporting + /// and other details are still "under development". + pub fn normalize(&self, value: &T) -> Result, NoSolution> + where + T: TypeFoldable<'tcx>, + { + let mut normalizer = QueryNormalizer { + infcx: self.infcx, + cause: self.cause, + param_env: self.param_env, + obligations: vec![], + error: false, + anon_depth: 0, + }; + if !value.has_projections() { + return Ok(Normalized { + value: value.clone(), + obligations: vec![], + }); + } + + let value1 = value.fold_with(&mut normalizer); + if normalizer.error { + Err(NoSolution) + } else { + Ok(Normalized { + value: value1, + obligations: normalizer.obligations, + }) + } + } +} + +/// Result from the `normalize_projection_ty` query. +#[derive(Clone, Debug)] +pub struct NormalizationResult<'tcx> { + /// Result of normalization. + pub normalized_ty: Ty<'tcx>, +} + +struct QueryNormalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> { + infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>, + cause: &'cx ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + obligations: Vec>, + error: bool, + anon_depth: usize, +} + +impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx> { + fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'tcx> { + self.infcx.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + let ty = ty.super_fold_with(self); + match ty.sty { + ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => { + // (*) + // Only normalize `impl Trait` after type-checking, usually in trans. + match self.param_env.reveal { + Reveal::UserFacing => ty, + + Reveal::All => { + let recursion_limit = self.tcx().sess.recursion_limit.get(); + if self.anon_depth >= recursion_limit { + let obligation = Obligation::with_depth( + self.cause.clone(), + recursion_limit, + self.param_env, + ty, + ); + self.infcx.report_overflow_error(&obligation, true); + } + + let generic_ty = self.tcx().type_of(def_id); + let concrete_ty = generic_ty.subst(self.tcx(), substs); + self.anon_depth += 1; + let folded_ty = self.fold_ty(concrete_ty); + self.anon_depth -= 1; + folded_ty + } + } + } + + ty::TyProjection(ref data) if !data.has_escaping_regions() => { + // (*) + // (*) This is kind of hacky -- we need to be able to + // handle normalization within binders because + // otherwise we wind up a need to normalize when doing + // trait matching (since you can have a trait + // obligation like `for<'a> T::B : Fn(&'a int)`), but + // we can't normalize with bound regions in scope. So + // far now we just ignore binders but only normalize + // if all bound regions are gone (and then we still + // have to renormalize whenever we instantiate a + // binder). It would be better to normalize in a + // binding-aware fashion. + + let gcx = self.infcx.tcx.global_tcx(); + + let (c_data, orig_values) = + self.infcx.canonicalize_query(&self.param_env.and(*data)); + debug!("QueryNormalizer: c_data = {:#?}", c_data); + debug!("QueryNormalizer: orig_values = {:#?}", orig_values); + match gcx.normalize_projection_ty(c_data) { + Ok(result) => { + // We don't expect ambiguity. + if result.is_ambiguous() { + self.error = true; + return ty; + } + + match self.infcx.instantiate_query_result( + self.cause, + self.param_env, + &orig_values, + &result, + ) { + Ok(InferOk { + value: result, + obligations, + }) => { + debug!("QueryNormalizer: result = {:#?}", result); + debug!("QueryNormalizer: obligations = {:#?}", obligations); + self.obligations.extend(obligations); + return result.normalized_ty; + } + + Err(_) => { + self.error = true; + return ty; + } + } + } + + Err(NoSolution) => { + self.error = true; + ty + } + } + } + + _ => ty, + } + } + + fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + if let ConstVal::Unevaluated(def_id, substs) = constant.val { + let tcx = self.infcx.tcx.global_tcx(); + if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) { + if substs.needs_infer() { + let identity_substs = Substs::identity_for_item(tcx, def_id); + let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs); + if let Some(instance) = instance { + let cid = GlobalId { + instance, + promoted: None, + }; + match tcx.const_eval(param_env.and(cid)) { + Ok(evaluated) => { + let evaluated = evaluated.subst(self.tcx(), substs); + return self.fold_const(evaluated); + } + Err(_) => {} + } + } + } else { + if let Some(substs) = self.tcx().lift_to_global(&substs) { + let instance = ty::Instance::resolve(tcx, param_env, def_id, substs); + if let Some(instance) = instance { + let cid = GlobalId { + instance, + promoted: None, + }; + match tcx.const_eval(param_env.and(cid)) { + Ok(evaluated) => return self.fold_const(evaluated), + Err(_) => {} + } + } + } + } + } + } + constant + } +} + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for NormalizationResult<'tcx> { + normalized_ty + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for NormalizationResult<'a> { + type Lifted = NormalizationResult<'tcx>; + normalized_ty + } +} + +impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>> { + type Canonicalized = CanonicalProjectionGoal<'gcx>; + + fn intern( + _gcx: TyCtxt<'_, 'gcx, 'gcx>, + value: Canonical<'gcx, Self::Lifted>, + ) -> Self::Canonicalized { + value + } +} + +impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> { + // we ought to intern this, but I'm too lazy just now + type Canonicalized = Rc>>>; + + fn intern( + _gcx: TyCtxt<'_, 'gcx, 'gcx>, + value: Canonical<'gcx, Self::Lifted>, + ) -> Self::Canonicalized { + Rc::new(value) + } +} + +impl_stable_hash_for!(struct NormalizationResult<'tcx> { + normalized_ty +}); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 24d3b37f804e..d85a95e87ea8 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -106,6 +106,7 @@ pub struct GlobalArenas<'tcx> { tables: TypedArena>, /// miri allocations const_allocs: TypedArena, + } impl<'tcx> GlobalArenas<'tcx> { diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 21affcbc9ede..95865d5eab0b 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -11,6 +11,7 @@ use dep_graph::SerializedDepNodeIndex; use hir::def_id::{CrateNum, DefId, DefIndex}; use mir::interpret::{GlobalId}; +use traits::query::CanonicalProjectionGoal; use ty::{self, Ty, TyCtxt}; use ty::subst::Substs; use ty::maps::queries; @@ -51,6 +52,15 @@ impl<'tcx, M: QueryConfig> QueryDescription<'tcx> for M { } } +impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> { + fn describe( + _tcx: TyCtxt, + goal: CanonicalProjectionGoal<'tcx>, + ) -> String { + format!("normalizing `{:?}`", goal) + } +} + impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> { fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { format!("computing whether `{}` is `Copy`", env.value) diff --git a/src/librustc/ty/maps/keys.rs b/src/librustc/ty/maps/keys.rs index 8fb1ad0da823..1f040522fda9 100644 --- a/src/librustc/ty/maps/keys.rs +++ b/src/librustc/ty/maps/keys.rs @@ -11,6 +11,7 @@ //! Defines the set of legal keys that can be used in queries. use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; +use traits::query::CanonicalProjectionGoal; use ty::{self, Ty, TyCtxt}; use ty::subst::Substs; use ty::fast_reject::SimplifiedType; @@ -170,3 +171,13 @@ impl Key for InternedString { DUMMY_SP } } + +impl<'tcx> Key for CanonicalProjectionGoal<'tcx> { + fn map_crate(&self) -> CrateNum { + LOCAL_CRATE + } + + fn default_span(&self, _tcx: TyCtxt) -> Span { + DUMMY_SP + } +} diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 0ded759fec73..2dc6cd7a4eb4 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -14,6 +14,7 @@ use hir::def_id::{CrateNum, DefId, DefIndex}; use hir::def::{Def, Export}; use hir::{self, TraitCandidate, ItemLocalId, TransFnAttrs}; use hir::svh::Svh; +use infer::canonical::{Canonical, QueryResult}; use lint; use middle::borrowck::BorrowCheckResult; use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, @@ -33,6 +34,8 @@ use mir::interpret::{GlobalId}; use session::{CompileResult, CrateDisambiguator}; use session::config::OutputFilenames; use traits::Vtable; +use traits::query::{CanonicalProjectionGoal, NoSolution}; +use traits::query::normalize::NormalizationResult; use traits::specialization_graph; use ty::{self, CrateInherentImpls, Ty, TyCtxt}; use ty::steal::Steal; @@ -380,6 +383,14 @@ define_maps! { <'tcx> [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>, [] fn fully_normalize_monormophic_ty: normalize_ty_node(Ty<'tcx>) -> Ty<'tcx>, + /// Do not call this query directly: invoke `normalize` instead. + [] fn normalize_projection_ty: NormalizeProjectionTy( + CanonicalProjectionGoal<'tcx> + ) -> Result< + Lrc>>>, + NoSolution, + >, + [] fn substitute_normalize_and_test_predicates: substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool, @@ -537,6 +548,7 @@ fn output_filenames_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructor<'tcx> { DepConstructor::VtableMethods{ trait_ref } } + fn normalize_ty_node<'tcx>(_: Ty<'tcx>) -> DepConstructor<'tcx> { DepConstructor::NormalizeTy } diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 68d108889020..2124b6296aab 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -773,6 +773,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::VtableMethods | DepKind::EraseRegionsTy | DepKind::NormalizeTy | + DepKind::NormalizeProjectionTy | DepKind::SubstituteNormalizeAndTestPredicates | DepKind::InstanceDefSizeEstimate | diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 6a1d9e565342..3bff79ed3a6f 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -28,6 +28,7 @@ rustc_plugin = { path = "../librustc_plugin" } rustc_privacy = { path = "../librustc_privacy" } rustc_resolve = { path = "../librustc_resolve" } rustc_save_analysis = { path = "../librustc_save_analysis" } +rustc_traits = { path = "../librustc_traits" } rustc_trans_utils = { path = "../librustc_trans_utils" } rustc_typeck = { path = "../librustc_typeck" } serialize = { path = "../libserialize" } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 485ee1130d30..542f818c3818 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -31,6 +31,7 @@ use rustc_incremental; use rustc_resolve::{MakeGlobMap, Resolver, ResolverArenas}; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::{self, CStore}; +use rustc_traits; use rustc_trans_utils::trans_crate::TransCrate; use rustc_typeck as typeck; use rustc_privacy; @@ -942,6 +943,7 @@ pub fn default_provide(providers: &mut ty::maps::Providers) { traits::provide(providers); reachable::provide(providers); rustc_passes::provide(providers); + rustc_traits::provide(providers); middle::region::provide(providers); cstore::provide(providers); lint::provide(providers); diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f6aa58213fc9..746f2db4767f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -46,6 +46,7 @@ extern crate rustc_metadata; extern crate rustc_mir; extern crate rustc_resolve; extern crate rustc_save_analysis; +extern crate rustc_traits; extern crate rustc_trans_utils; extern crate rustc_typeck; extern crate serialize; diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index c474cabdb3c5..06e6be5cd56a 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -20,7 +20,8 @@ use dataflow::move_paths::MoveData; use rustc::hir::def_id::DefId; use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult}; use rustc::infer::region_constraints::{GenericKind, RegionConstraintData}; -use rustc::traits::{self, FulfillmentContext}; +use rustc::traits::{self, Normalized, FulfillmentContext}; +use rustc::traits::query::NoSolution; use rustc::ty::error::TypeError; use rustc::ty::fold::TypeFoldable; use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeVariants}; @@ -1553,10 +1554,17 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { { debug!("normalize(value={:?}, location={:?})", value, location); self.fully_perform_op(location.at_self(), |this| { - let mut selcx = traits::SelectionContext::new(this.infcx); - let cause = this.misc(this.last_span); - let traits::Normalized { value, obligations } = - traits::normalize(&mut selcx, this.param_env, cause, value); + let Normalized { value, obligations } = this.infcx + .at(&this.misc(this.last_span), this.param_env) + .normalize(value) + .unwrap_or_else(|NoSolution| { + span_bug!( + this.last_span, + "normalization of `{:?}` failed at {:?}", + value, + location, + ); + }); Ok(InferOk { value, obligations }) }).unwrap() } diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml new file mode 100644 index 000000000000..dc2a21cdab25 --- /dev/null +++ b/src/librustc_traits/Cargo.toml @@ -0,0 +1,18 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_traits" +version = "0.0.0" + +[lib] +name = "rustc_traits" +path = "lib.rs" +crate-type = ["dylib"] + +[dependencies] +bitflags = "1.0" +graphviz = { path = "../libgraphviz" } +log = { version = "0.4" } +rustc = { path = "../librustc" } +rustc_data_structures = { path = "../librustc_data_structures" } +syntax = { path = "../libsyntax" } +syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs new file mode 100644 index 000000000000..0d92404d24b0 --- /dev/null +++ b/src/librustc_traits/lib.rs @@ -0,0 +1,37 @@ +// Copyright 2014 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. + +//! New recursive solver modeled on Chalk's recursive solver. Most of +//! the guts are broken up into modules; see the comments in those modules. + +#![deny(warnings)] + +#![feature(crate_visibility_modifier)] +#![feature(match_default_bindings)] +#![feature(underscore_lifetimes)] + +#[macro_use] +extern crate log; +extern crate rustc; +extern crate rustc_data_structures; +extern crate syntax; +extern crate syntax_pos; + +mod normalize_projection_ty; +mod util; + +use rustc::ty::maps::Providers; + +pub fn provide(p: &mut Providers) { + *p = Providers { + normalize_projection_ty: normalize_projection_ty::normalize_projection_ty, + ..*p + }; +} diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs new file mode 100644 index 000000000000..55785d9586cc --- /dev/null +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -0,0 +1,55 @@ +// Copyright 2014 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::infer::canonical::{Canonical, QueryResult}; +use rustc::traits::{self, FulfillmentContext, Normalized, ObligationCause, + SelectionContext}; +use rustc::traits::query::{CanonicalProjectionGoal, NoSolution, normalize::NormalizationResult}; +use rustc::ty::{ParamEnvAnd, TyCtxt}; +use rustc::util::common::CellUsizeExt; +use std::rc::Rc; +use syntax::ast::DUMMY_NODE_ID; +use syntax_pos::DUMMY_SP; +use util; + +crate fn normalize_projection_ty<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + goal: CanonicalProjectionGoal<'tcx>, +) -> Result>>>, NoSolution> { + debug!("normalize_provider(goal={:#?})", goal); + + tcx.sess.perf_stats.normalize_projection_ty.increment(); + tcx.infer_ctxt().enter(|ref infcx| { + let ( + ParamEnvAnd { + param_env, + value: goal, + }, + canonical_inference_vars, + ) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal); + let fulfill_cx = &mut FulfillmentContext::new(); + let selcx = &mut SelectionContext::new(infcx); + let cause = ObligationCause::misc(DUMMY_SP, DUMMY_NODE_ID); + let Normalized { + value: answer, + obligations, + } = traits::normalize_projection_type(selcx, param_env, goal, cause, 0); + fulfill_cx.register_predicate_obligations(infcx, obligations); + + // Now that we have fulfilled as much as we can, create a solution + // from what we've learned. + util::make_query_response( + infcx, + canonical_inference_vars, + NormalizationResult { normalized_ty: answer }, + fulfill_cx, + ) + }) +} diff --git a/src/librustc_traits/util.rs b/src/librustc_traits/util.rs new file mode 100644 index 000000000000..976eb442a0d1 --- /dev/null +++ b/src/librustc_traits/util.rs @@ -0,0 +1,117 @@ +// Copyright 2014 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::infer::InferCtxt; +use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraints, + QueryResult}; +use rustc::infer::region_constraints::{Constraint, RegionConstraintData}; +use rustc::traits::FulfillmentContext; +use rustc::traits::query::NoSolution; +use rustc::ty; +use std::fmt::Debug; + +/// The canonicalization form of `QueryResult<'tcx, T>`. +type CanonicalizedQueryResult<'gcx, 'tcx, T> = + as Canonicalize<'gcx, 'tcx>>::Canonicalized; + +crate fn make_query_response<'gcx, 'tcx, T>( + infcx: &InferCtxt<'_, 'gcx, 'tcx>, + inference_vars: CanonicalVarValues<'tcx>, + answer: T, + fulfill_cx: &mut FulfillmentContext<'tcx>, +) -> Result, NoSolution> +where + T: Debug, + QueryResult<'tcx, T>: Canonicalize<'gcx, 'tcx>, +{ + let tcx = infcx.tcx; + + debug!( + "make_query_response(\ + inference_vars={:?}, \ + answer={:?})", + inference_vars, answer, + ); + + // Select everything, returning errors. + let true_errors = match fulfill_cx.select_where_possible(infcx) { + Ok(()) => vec![], + Err(errors) => errors, + }; + debug!("true_errors = {:#?}", true_errors); + + if !true_errors.is_empty() { + // FIXME -- we don't indicate *why* we failed to solve + debug!("make_query_response: true_errors={:#?}", true_errors); + return Err(NoSolution); + } + + // Anything left unselected *now* must be an ambiguity. + let ambig_errors = match fulfill_cx.select_all_or_error(infcx) { + Ok(()) => vec![], + Err(errors) => errors, + }; + debug!("ambig_errors = {:#?}", ambig_errors); + + let region_obligations = infcx.take_registered_region_obligations(); + + let (region_outlives, ty_outlives) = infcx.with_region_constraints(|region_constraints| { + let RegionConstraintData { + constraints, + verifys, + givens, + } = region_constraints; + + assert!(verifys.is_empty()); + assert!(givens.is_empty()); + + let region_outlives: Vec<_> = constraints + .into_iter() + .map(|(k, _)| match *k { + Constraint::VarSubVar(v1, v2) => { + (tcx.mk_region(ty::ReVar(v1)), tcx.mk_region(ty::ReVar(v2))) + } + Constraint::VarSubReg(v1, r2) => (tcx.mk_region(ty::ReVar(v1)), r2), + Constraint::RegSubVar(r1, v2) => (r1, tcx.mk_region(ty::ReVar(v2))), + Constraint::RegSubReg(r1, r2) => (r1, r2), + }) + .collect(); + + let ty_outlives: Vec<_> = region_obligations + .into_iter() + .map(|(_, r_o)| (r_o.sup_type, r_o.sub_region)) + .collect(); + + (region_outlives, ty_outlives) + }); + + let certainty = if ambig_errors.is_empty() { + Certainty::Proven + } else { + Certainty::Ambiguous + }; + + let (canonical_result, _) = infcx.canonicalize_response(&QueryResult { + var_values: inference_vars, + region_constraints: QueryRegionConstraints { + region_outlives, + ty_outlives, + }, + certainty, + value: answer, + }); + + debug!( + "make_query_response: canonical_result = {:#?}", + canonical_result + ); + + Ok(canonical_result) +} From ca87d24467c46c07961f1b6450dabfb9674913da Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Feb 2018 10:55:16 -0500 Subject: [PATCH 149/830] introduce `infcx.at(..).dropck_outlives(..)` operaton [VIC] Backed by a canonicalized query. This computes all the types/regions that need to be live when the destructor runs (i.e., that the dtor may access). --- src/librustc/dep_graph/dep_node.rs | 4 +- src/librustc/ich/impls_ty.rs | 6 - src/librustc/traits/query/dropck_outlives.rs | 193 ++++++++++++ src/librustc/traits/query/mod.rs | 5 +- src/librustc/ty/context.rs | 1 - src/librustc/ty/maps/config.rs | 8 +- src/librustc/ty/maps/keys.rs | 12 +- src/librustc/ty/maps/mod.rs | 15 +- src/librustc/ty/maps/plumbing.rs | 1 + src/librustc/ty/maps/values.rs | 6 - src/librustc/ty/mod.rs | 80 +---- src/librustc/ty/util.rs | 95 +----- .../borrow_check/nll/type_check/liveness.rs | 87 ++---- src/librustc_traits/dropck_outlives.rs | 285 ++++++++++++++++++ src/librustc_traits/lib.rs | 3 + src/librustc_typeck/check/dropck.rs | 50 +-- src/librustc_typeck/check/regionck.rs | 6 +- 17 files changed, 558 insertions(+), 299 deletions(-) create mode 100644 src/librustc/traits/query/dropck_outlives.rs create mode 100644 src/librustc_traits/dropck_outlives.rs diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index caef3a8acc44..130fbc192677 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -70,7 +70,7 @@ use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use std::fmt; use std::hash::Hash; use syntax_pos::symbol::InternedString; -use traits::query::CanonicalProjectionGoal; +use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal}; use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty}; use ty::subst::Substs; @@ -637,6 +637,8 @@ define_dep_nodes!( <'tcx> [input] OutputFilenames, [anon] NormalizeTy, [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>), + [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>), + [] DropckOutlives(CanonicalTyGoal<'tcx>), [] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) }, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index ae67d592ba30..4eb4f0edafe4 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1017,12 +1017,6 @@ impl_stable_hash_for!(struct ty::Destructor { did }); -impl_stable_hash_for!(struct ty::DtorckConstraint<'tcx> { - outlives, - dtorck_types -}); - - impl<'a> HashStable> for ty::CrateVariancesMap { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs new file mode 100644 index 000000000000..5c964f6559a3 --- /dev/null +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -0,0 +1,193 @@ +// Copyright 2014 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 infer::at::At; +use infer::canonical::{Canonical, Canonicalize, QueryResult}; +use infer::InferOk; +use std::iter::FromIterator; +use traits::query::CanonicalTyGoal; +use ty::{self, Ty, TyCtxt}; +use ty::subst::Kind; +use std::rc::Rc; + +impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { + /// Given a type `ty` of some value being dropped, computes a set + /// of "kinds" (types, regions) that must be outlive the execution + /// of the destructor. These basically correspond to data that the + /// destructor might access. This is used during regionck to + /// impose "outlives" constraints on any lifetimes referenced + /// within. + /// + /// The rules here are given by the "dropck" RFCs, notably [#1238] + /// and [#1327]. This is a fixed-point computation, where we + /// explore all the data that will be dropped (transitively) when + /// a value of type `ty` is dropped. For each type T that will be + /// dropped and which has a destructor, we must assume that all + /// the types/regions of T are live during the destructor, unless + /// they are marked with a special attribute (`#[may_dangle]`). + /// + /// [#1238]: https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md + /// [#1327]: https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md + pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec>> { + debug!( + "dropck_outlives(ty={:?}, param_env={:?})", + ty, self.param_env, + ); + + let tcx = self.infcx.tcx; + let gcx = tcx.global_tcx(); + let (c_ty, orig_values) = self.infcx.canonicalize_query(&self.param_env.and(ty)); + let span = self.cause.span; + match &gcx.dropck_outlives(c_ty) { + Ok(result) if result.is_proven() => { + match self.infcx.instantiate_query_result( + self.cause, + self.param_env, + &orig_values, + result, + ) { + Ok(InferOk { + value: DropckOutlivesResult { kinds, overflows }, + obligations, + }) => { + for overflow_ty in overflows.into_iter().take(1) { + let mut err = struct_span_err!( + tcx.sess, + span, + E0320, + "overflow while adding drop-check rules for {}", + self.infcx.resolve_type_vars_if_possible(&ty), + ); + err.note(&format!("overflowed on {}", overflow_ty)); + err.emit(); + } + + return InferOk { + value: kinds, + obligations, + }; + } + + Err(_) => { /* fallthrough to error-handling code below */ } + } + } + + _ => { /* fallthrough to error-handling code below */ } + } + + // Errors and ambiuity in dropck occur in two cases: + // - unresolved inference variables at the end of typeck + // - non well-formed types where projections cannot be resolved + // Either of these should hvae created an error before. + tcx.sess + .delay_span_bug(span, "dtorck encountered internal error"); + return InferOk { + value: vec![], + obligations: vec![], + }; + } +} + +#[derive(Clone, Debug)] +pub struct DropckOutlivesResult<'tcx> { + pub kinds: Vec>, + pub overflows: Vec>, +} + +/// A set of constraints that need to be satisfied in order for +/// a type to be valid for destruction. +#[derive(Clone, Debug)] +pub struct DtorckConstraint<'tcx> { + /// Types that are required to be alive in order for this + /// type to be valid for destruction. + pub outlives: Vec>, + + /// Types that could not be resolved: projections and params. + pub dtorck_types: Vec>, + + /// If, during the computation of the dtorck constraint, we + /// overflow, that gets recorded here. The caller is expected to + /// report an error. + pub overflows: Vec>, +} + +impl<'tcx> DtorckConstraint<'tcx> { + pub fn empty() -> DtorckConstraint<'tcx> { + DtorckConstraint { + outlives: vec![], + dtorck_types: vec![], + overflows: vec![], + } + } +} + +impl<'tcx> FromIterator> for DtorckConstraint<'tcx> { + fn from_iter>>(iter: I) -> Self { + let mut result = Self::empty(); + + for DtorckConstraint { + outlives, + dtorck_types, + overflows, + } in iter + { + result.outlives.extend(outlives); + result.dtorck_types.extend(dtorck_types); + result.overflows.extend(overflows); + } + + result + } +} +impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, Ty<'tcx>> { + type Canonicalized = CanonicalTyGoal<'gcx>; + + fn intern( + _gcx: TyCtxt<'_, 'gcx, 'gcx>, + value: Canonical<'gcx, Self::Lifted>, + ) -> Self::Canonicalized { + value + } +} + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for DropckOutlivesResult<'tcx> { + kinds, overflows + } +} + +BraceStructLiftImpl! { + impl<'a, 'tcx> Lift<'tcx> for DropckOutlivesResult<'a> { + type Lifted = DropckOutlivesResult<'tcx>; + kinds, overflows + } +} + +impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { + kinds, overflows +}); + +impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, DropckOutlivesResult<'tcx>> { + // we ought to intern this, but I'm too lazy just now + type Canonicalized = Rc>>>; + + fn intern( + _gcx: TyCtxt<'_, 'gcx, 'gcx>, + value: Canonical<'gcx, Self::Lifted>, + ) -> Self::Canonicalized { + Rc::new(value) + } +} + +impl_stable_hash_for!(struct DtorckConstraint<'tcx> { + outlives, + dtorck_types, + overflows +}); diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index bba2c1555832..607344f9c678 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -16,13 +16,16 @@ //! `librustc_traits`. use infer::canonical::Canonical; -use ty; +use ty::{self, Ty}; +pub mod dropck_outlives; pub mod normalize; pub type CanonicalProjectionGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>; +pub type CanonicalTyGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, Ty<'tcx>>>; + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct NoSolution; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d85a95e87ea8..24d3b37f804e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -106,7 +106,6 @@ pub struct GlobalArenas<'tcx> { tables: TypedArena>, /// miri allocations const_allocs: TypedArena, - } impl<'tcx> GlobalArenas<'tcx> { diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 95865d5eab0b..bcd6a5ace627 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -11,7 +11,7 @@ use dep_graph::SerializedDepNodeIndex; use hir::def_id::{CrateNum, DefId, DefIndex}; use mir::interpret::{GlobalId}; -use traits::query::CanonicalProjectionGoal; +use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal}; use ty::{self, Ty, TyCtxt}; use ty::subst::Substs; use ty::maps::queries; @@ -61,6 +61,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::dropck_outlives<'tcx> { + fn describe(_tcx: TyCtxt, goal: CanonicalTyGoal<'tcx>) -> String { + format!("computing dropck types for `{:?}`", goal) + } +} + impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> { fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { format!("computing whether `{}` is `Copy`", env.value) diff --git a/src/librustc/ty/maps/keys.rs b/src/librustc/ty/maps/keys.rs index 1f040522fda9..b8167ec91863 100644 --- a/src/librustc/ty/maps/keys.rs +++ b/src/librustc/ty/maps/keys.rs @@ -11,7 +11,7 @@ //! Defines the set of legal keys that can be used in queries. use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; -use traits::query::CanonicalProjectionGoal; +use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal}; use ty::{self, Ty, TyCtxt}; use ty::subst::Substs; use ty::fast_reject::SimplifiedType; @@ -181,3 +181,13 @@ impl<'tcx> Key for CanonicalProjectionGoal<'tcx> { DUMMY_SP } } + +impl<'tcx> Key for CanonicalTyGoal<'tcx> { + fn map_crate(&self) -> CrateNum { + LOCAL_CRATE + } + + fn default_span(&self, _tcx: TyCtxt) -> Span { + DUMMY_SP + } +} diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2dc6cd7a4eb4..4df15b2e76be 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -34,7 +34,8 @@ use mir::interpret::{GlobalId}; use session::{CompileResult, CrateDisambiguator}; use session::config::OutputFilenames; use traits::Vtable; -use traits::query::{CanonicalProjectionGoal, NoSolution}; +use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal, NoSolution}; +use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; use traits::query::normalize::NormalizationResult; use traits::specialization_graph; use ty::{self, CrateInherentImpls, Ty, TyCtxt}; @@ -114,7 +115,9 @@ define_maps! { <'tcx> [] fn adt_def: AdtDefOfItem(DefId) -> &'tcx ty::AdtDef, [] fn adt_destructor: AdtDestructor(DefId) -> Option, [] fn adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>], - [] fn adt_dtorck_constraint: DtorckConstraint(DefId) -> ty::DtorckConstraint<'tcx>, + [] fn adt_dtorck_constraint: DtorckConstraint( + DefId + ) -> Result, NoSolution>, /// True if this is a const fn [] fn is_const_fn: IsConstFn(DefId) -> bool, @@ -391,6 +394,14 @@ define_maps! { <'tcx> NoSolution, >, + /// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead. + [] fn dropck_outlives: DropckOutlives( + CanonicalTyGoal<'tcx> + ) -> Result< + Lrc>>>, + NoSolution, + >, + [] fn substitute_normalize_and_test_predicates: substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 2124b6296aab..64b17922049a 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -774,6 +774,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::EraseRegionsTy | DepKind::NormalizeTy | DepKind::NormalizeProjectionTy | + DepKind::DropckOutlives | DepKind::SubstituteNormalizeAndTestPredicates | DepKind::InstanceDefSizeEstimate | diff --git a/src/librustc/ty/maps/values.rs b/src/librustc/ty/maps/values.rs index 165798d19f19..8d38d7dbbbbf 100644 --- a/src/librustc/ty/maps/values.rs +++ b/src/librustc/ty/maps/values.rs @@ -35,12 +35,6 @@ impl<'tcx> Value<'tcx> for Ty<'tcx> { } } -impl<'tcx> Value<'tcx> for ty::DtorckConstraint<'tcx> { - fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self { - Self::empty() - } -} - impl<'tcx> Value<'tcx> for ty::SymbolName { fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> Self { ty::SymbolName { name: Symbol::intern("").as_str() } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 93d1585cdc83..fc1d26b0e091 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -34,15 +34,13 @@ use ty; use ty::subst::{Subst, Substs}; use ty::util::{IntTypeExt, Discr}; use ty::walk::TypeWalker; -use util::common::ErrorReported; -use util::nodemap::{NodeSet, DefIdMap, FxHashMap, FxHashSet}; +use util::nodemap::{NodeSet, DefIdMap, FxHashMap}; use serialize::{self, Encodable, Encoder}; use std::cell::RefCell; use std::cmp; use std::fmt; use std::hash::{Hash, Hasher}; -use std::iter::FromIterator; use std::ops::Deref; use rustc_data_structures::sync::Lrc; use std::slice; @@ -2661,38 +2659,6 @@ fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result } -/// Calculates the dtorck constraint for a type. -fn adt_dtorck_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId) - -> DtorckConstraint<'tcx> { - let def = tcx.adt_def(def_id); - let span = tcx.def_span(def_id); - debug!("dtorck_constraint: {:?}", def); - - if def.is_phantom_data() { - let result = DtorckConstraint { - outlives: vec![], - dtorck_types: vec![ - tcx.mk_param_from_def(&tcx.generics_of(def_id).types[0]) - ] - }; - debug!("dtorck_constraint: {:?} => {:?}", def, result); - return result; - } - - let mut result = def.all_fields() - .map(|field| tcx.type_of(field.did)) - .map(|fty| tcx.dtorck_constraint_for_ty(span, fty, 0, fty)) - .collect::>() - .unwrap_or(DtorckConstraint::empty()); - result.outlives.extend(tcx.destructor_constraints(def)); - result.dedup(); - - debug!("dtorck_constraint: {:?} => {:?}", def, result); - - result -} - fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Lrc> { @@ -2808,7 +2774,6 @@ pub fn provide(providers: &mut ty::maps::Providers) { associated_item, associated_item_def_ids, adt_sized_constraint, - adt_dtorck_constraint, def_span, param_env, trait_of_item, @@ -2831,49 +2796,6 @@ pub struct CrateInherentImpls { pub inherent_impls: DefIdMap>>, } -/// A set of constraints that need to be satisfied in order for -/// a type to be valid for destruction. -#[derive(Clone, Debug)] -pub struct DtorckConstraint<'tcx> { - /// Types that are required to be alive in order for this - /// type to be valid for destruction. - pub outlives: Vec>, - /// Types that could not be resolved: projections and params. - pub dtorck_types: Vec>, -} - -impl<'tcx> FromIterator> for DtorckConstraint<'tcx> -{ - fn from_iter>>(iter: I) -> Self { - let mut result = Self::empty(); - - for constraint in iter { - result.outlives.extend(constraint.outlives); - result.dtorck_types.extend(constraint.dtorck_types); - } - - result - } -} - - -impl<'tcx> DtorckConstraint<'tcx> { - fn empty() -> DtorckConstraint<'tcx> { - DtorckConstraint { - outlives: vec![], - dtorck_types: vec![] - } - } - - fn dedup<'a>(&mut self) { - let mut outlives = FxHashSet(); - let mut dtorck_types = FxHashSet(); - - self.outlives.retain(|&val| outlives.replace(val).is_none()); - self.dtorck_types.retain(|&val| dtorck_types.replace(val).is_none()); - } -} - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)] pub struct SymbolName { // FIXME: we don't rely on interning or equality here - better have diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index e8ce49d39d29..753f89d8cd29 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -19,7 +19,7 @@ use middle::const_val::ConstVal; use traits; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::fold::TypeVisitor; -use ty::subst::{Subst, UnpackedKind}; +use ty::subst::UnpackedKind; use ty::maps::TyCtxtAt; use ty::TypeVariants::*; use ty::layout::Integer; @@ -537,99 +537,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { result } - /// Return a set of constraints that needs to be satisfied in - /// order for `ty` to be valid for destruction. - pub fn dtorck_constraint_for_ty(self, - span: Span, - for_ty: Ty<'tcx>, - depth: usize, - ty: Ty<'tcx>) - -> Result, ErrorReported> - { - debug!("dtorck_constraint_for_ty({:?}, {:?}, {:?}, {:?})", - span, for_ty, depth, ty); - - if depth >= self.sess.recursion_limit.get() { - let mut err = struct_span_err!( - self.sess, span, E0320, - "overflow while adding drop-check rules for {}", for_ty); - err.note(&format!("overflowed on {}", ty)); - err.emit(); - return Err(ErrorReported); - } - - let result = match ty.sty { - ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | - ty::TyFloat(_) | ty::TyStr | ty::TyNever | ty::TyForeign(..) | - ty::TyRawPtr(..) | ty::TyRef(..) | ty::TyFnDef(..) | ty::TyFnPtr(_) | - ty::TyGeneratorWitness(..) => { - // these types never have a destructor - Ok(ty::DtorckConstraint::empty()) - } - - ty::TyArray(ety, _) | ty::TySlice(ety) => { - // single-element containers, behave like their element - self.dtorck_constraint_for_ty(span, for_ty, depth+1, ety) - } - - ty::TyTuple(tys, _) => { - tys.iter().map(|ty| { - self.dtorck_constraint_for_ty(span, for_ty, depth+1, ty) - }).collect() - } - - ty::TyClosure(def_id, substs) => { - substs.upvar_tys(def_id, self).map(|ty| { - self.dtorck_constraint_for_ty(span, for_ty, depth+1, ty) - }).collect() - } - - ty::TyGenerator(def_id, substs, _) => { - // Note that the interior types are ignored here. - // Any type reachable inside the interior must also be reachable - // through the upvars. - substs.upvar_tys(def_id, self).map(|ty| { - self.dtorck_constraint_for_ty(span, for_ty, depth+1, ty) - }).collect() - } - - ty::TyAdt(def, substs) => { - let ty::DtorckConstraint { - dtorck_types, outlives - } = self.at(span).adt_dtorck_constraint(def.did); - Ok(ty::DtorckConstraint { - // FIXME: we can try to recursively `dtorck_constraint_on_ty` - // there, but that needs some way to handle cycles. - dtorck_types: dtorck_types.subst(self, substs), - outlives: outlives.subst(self, substs) - }) - } - - // Objects must be alive in order for their destructor - // to be called. - ty::TyDynamic(..) => Ok(ty::DtorckConstraint { - outlives: vec![ty.into()], - dtorck_types: vec![], - }), - - // Types that can't be resolved. Pass them forward. - ty::TyProjection(..) | ty::TyAnon(..) | ty::TyParam(..) => { - Ok(ty::DtorckConstraint { - outlives: vec![], - dtorck_types: vec![ty], - }) - } - - ty::TyInfer(..) | ty::TyError => { - self.sess.delay_span_bug(span, "unresolved type in dtorck"); - Err(ErrorReported) - } - }; - - debug!("dtorck_constraint_for_ty({:?}) = {:?}", ty, result); - result - } - pub fn is_closure(self, def_id: DefId) -> bool { self.def_key(def_id).disambiguated_data.data == DefPathData::ClosureExpr } diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs index 5b3f439e0ebb..d19fd2bb5969 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs @@ -14,13 +14,9 @@ use dataflow::MaybeInitializedPlaces; use dataflow::move_paths::{HasMoveData, MoveData}; use rustc::mir::{BasicBlock, Location, Mir}; use rustc::mir::Local; -use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use rustc::traits; +use rustc::ty::{Ty, TyCtxt, TypeFoldable}; use rustc::infer::InferOk; -use rustc::util::common::ErrorReported; use borrow_check::nll::type_check::AtLocation; -use rustc_data_structures::fx::FxHashSet; -use syntax::codemap::DUMMY_SP; use util::liveness::LivenessResults; use super::TypeChecker; @@ -193,73 +189,34 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo // // For this reason, we avoid calling TypeChecker.normalize, instead doing all normalization // ourselves in one large 'fully_perform_op' callback. - let (type_constraints, kind_constraints) = self.cx.fully_perform_op(location.at_self(), - |cx| { + let kind_constraints = self.cx + .fully_perform_op(location.at_self(), |cx| { + let span = cx.last_span; - let tcx = cx.infcx.tcx; - let mut selcx = traits::SelectionContext::new(cx.infcx); - let cause = cx.misc(cx.last_span); + let mut final_obligations = Vec::new(); + let mut kind_constraints = Vec::new(); - let mut types = vec![(dropped_ty, 0)]; - let mut final_obligations = Vec::new(); - let mut type_constraints = Vec::new(); - let mut kind_constraints = Vec::new(); - - let mut known = FxHashSet(); - - while let Some((ty, depth)) = types.pop() { - let span = DUMMY_SP; // FIXME - let result = match tcx.dtorck_constraint_for_ty(span, dropped_ty, depth, ty) { - Ok(result) => result, - Err(ErrorReported) => { - continue; - } - }; - - let ty::DtorckConstraint { - outlives, - dtorck_types, - } = result; - - // All things in the `outlives` array may be touched by - // the destructor and must be live at this point. - for outlive in outlives { + let InferOk { + value: kinds, + obligations, + } = cx.infcx + .at(&cx.misc(span), cx.param_env) + .dropck_outlives(dropped_ty); + for kind in kinds { + // All things in the `outlives` array may be touched by + // the destructor and must be live at this point. let cause = Cause::DropVar(dropped_local, location); - kind_constraints.push((outlive, location, cause)); + kind_constraints.push((kind, location, cause)); } - // However, there may also be some types that - // `dtorck_constraint_for_ty` could not resolve (e.g., - // associated types and parameters). We need to normalize - // associated types here and possibly recursively process. - for ty in dtorck_types { - let traits::Normalized { value: ty, obligations } = - traits::normalize(&mut selcx, cx.param_env, cause.clone(), &ty); + final_obligations.extend(obligations); - final_obligations.extend(obligations); - - let ty = cx.infcx.resolve_type_and_region_vars_if_possible(&ty); - match ty.sty { - ty::TyParam(..) | ty::TyProjection(..) | ty::TyAnon(..) => { - let cause = Cause::DropVar(dropped_local, location); - type_constraints.push((ty, location, cause)); - } - - _ => if known.insert(ty) { - types.push((ty, depth + 1)); - }, - } - } - } - - Ok(InferOk { - value: (type_constraints, kind_constraints), obligations: final_obligations + Ok(InferOk { + value: kind_constraints, + obligations: final_obligations, + }) }) - }).unwrap(); - - for (ty, location, cause) in type_constraints { - self.push_type_live_constraint(ty, location, cause); - } + .unwrap(); for (kind, location, cause) in kind_constraints { self.push_type_live_constraint(kind, location, cause); diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs new file mode 100644 index 000000000000..2274f3942bdb --- /dev/null +++ b/src/librustc_traits/dropck_outlives.rs @@ -0,0 +1,285 @@ +// Copyright 2014 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::infer::canonical::{Canonical, QueryResult}; +use rustc::hir::def_id::DefId; +use rustc::traits::{FulfillmentContext, Normalized, ObligationCause}; +use rustc::traits::query::{CanonicalTyGoal, NoSolution}; +use rustc::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; +use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; +use rustc::ty::subst::Subst; +use rustc::util::nodemap::FxHashSet; +use std::rc::Rc; +use syntax::codemap::{Span, DUMMY_SP}; +use util; + +crate fn dropck_outlives<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + goal: CanonicalTyGoal<'tcx>, +) -> Result>>>, NoSolution> { + debug!("dropck_outlives(goal={:#?})", goal); + + tcx.infer_ctxt().enter(|ref infcx| { + let tcx = infcx.tcx; + let ( + ParamEnvAnd { + param_env, + value: for_ty, + }, + canonical_inference_vars, + ) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal); + + let mut result = DropckOutlivesResult { kinds: vec![], overflows: vec![] }; + + // A stack of types left to process. Each round, we pop + // something from the stack and invoke + // `dtorck_constraint_for_ty`. This may produce new types that + // have to be pushed on the stack. This continues until we have explored + // all the reachable types from the type `for_ty`. + // + // Example: Imagine that we have the following code: + // + // ```rust + // struct A { + // value: B, + // children: Vec, + // } + // + // struct B { + // value: u32 + // } + // + // fn f() { + // let a: A = ...; + // .. + // } // here, `a` is dropped + // ``` + // + // at the point where `a` is dropped, we need to figure out + // which types inside of `a` contain region data that may be + // accessed by any destructors in `a`. We begin by pushing `A` + // onto the stack, as that is the type of `a`. We will then + // invoke `dtorck_constraint_for_ty` which will expand `A` + // into the types of its fields `(B, Vec)`. These will get + // pushed onto the stack. Eventually, expanding `Vec` will + // lead to us trying to push `A` a second time -- to prevent + // infinite recusion, we notice that `A` was already pushed + // once and stop. + let mut ty_stack = vec![(for_ty, 0)]; + + // Set used to detect infinite recursion. + let mut ty_set = FxHashSet(); + + let fulfill_cx = &mut FulfillmentContext::new(); + + let cause = ObligationCause::dummy(); + while let Some((ty, depth)) = ty_stack.pop() { + let DtorckConstraint { + dtorck_types, + outlives, + overflows, + } = dtorck_constraint_for_ty(tcx, DUMMY_SP, for_ty, depth, ty)?; + + // "outlives" represent types/regions that may be touched + // by a destructor. + result.kinds.extend(outlives); + result.overflows.extend(overflows); + + // dtorck types are "types that will get dropped but which + // do not themselves define a destructor", more or less. We have + // to push them onto the stack to be expanded. + for ty in dtorck_types { + match infcx.at(&cause, param_env).normalize(&ty) { + Ok(Normalized { + value: ty, + obligations, + }) => { + fulfill_cx.register_predicate_obligations(infcx, obligations); + + debug!("dropck_outlives: ty from dtorck_types = {:?}", ty); + + match ty.sty { + // All parameters live for the duration of the + // function. + ty::TyParam(..) => {} + + // A projection that we couldn't resolve - it + // might have a destructor. + ty::TyProjection(..) | ty::TyAnon(..) => { + result.kinds.push(ty.into()); + } + + _ => { + if ty_set.insert(ty) { + ty_stack.push((ty, depth + 1)); + } + } + } + } + + // We don't actually expect to fail to normalize. + // That implies a WF error somewhere else. + Err(NoSolution) => { + return Err(NoSolution); + } + } + } + } + + debug!("dropck_outlives: result = {:#?}", result); + + util::make_query_response(infcx, canonical_inference_vars, result, fulfill_cx) + }) +} + +/// Return a set of constraints that needs to be satisfied in +/// order for `ty` to be valid for destruction. +fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( + tcx: TyCtxt<'a, 'gcx, 'tcx>, + span: Span, + for_ty: Ty<'tcx>, + depth: usize, + ty: Ty<'tcx>, +) -> Result, NoSolution> { + debug!( + "dtorck_constraint_for_ty({:?}, {:?}, {:?}, {:?})", + span, for_ty, depth, ty + ); + + if depth >= tcx.sess.recursion_limit.get() { + return Ok(DtorckConstraint { + outlives: vec![], + dtorck_types: vec![], + overflows: vec![ty], + }); + } + + let result = match ty.sty { + ty::TyBool + | ty::TyChar + | ty::TyInt(_) + | ty::TyUint(_) + | ty::TyFloat(_) + | ty::TyStr + | ty::TyNever + | ty::TyForeign(..) + | ty::TyRawPtr(..) + | ty::TyRef(..) + | ty::TyFnDef(..) + | ty::TyFnPtr(_) + | ty::TyGeneratorWitness(..) => { + // these types never have a destructor + Ok(DtorckConstraint::empty()) + } + + ty::TyArray(ety, _) | ty::TySlice(ety) => { + // single-element containers, behave like their element + dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ety) + } + + ty::TyTuple(tys, _) => tys.iter() + .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty)) + .collect(), + + ty::TyClosure(def_id, substs) => substs + .upvar_tys(def_id, tcx) + .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty)) + .collect(), + + ty::TyGenerator(def_id, substs, _) => { + // Note that the interior types are ignored here. + // Any type reachable inside the interior must also be reachable + // through the upvars. + substs + .upvar_tys(def_id, tcx) + .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty)) + .collect() + } + + ty::TyAdt(def, substs) => { + let DtorckConstraint { + dtorck_types, + outlives, + overflows, + } = tcx.at(span).adt_dtorck_constraint(def.did)?; + Ok(DtorckConstraint { + // FIXME: we can try to recursively `dtorck_constraint_on_ty` + // there, but that needs some way to handle cycles. + dtorck_types: dtorck_types.subst(tcx, substs), + outlives: outlives.subst(tcx, substs), + overflows: overflows.subst(tcx, substs), + }) + } + + // Objects must be alive in order for their destructor + // to be called. + ty::TyDynamic(..) => Ok(DtorckConstraint { + outlives: vec![ty.into()], + dtorck_types: vec![], + overflows: vec![], + }), + + // Types that can't be resolved. Pass them forward. + ty::TyProjection(..) | ty::TyAnon(..) | ty::TyParam(..) => Ok(DtorckConstraint { + outlives: vec![], + dtorck_types: vec![ty], + overflows: vec![], + }), + + ty::TyInfer(..) | ty::TyError => { + // By the time this code runs, all type variables ought to + // be fully resolved. + Err(NoSolution) + } + }; + + debug!("dtorck_constraint_for_ty({:?}) = {:?}", ty, result); + result +} + +/// Calculates the dtorck constraint for a type. +crate fn adt_dtorck_constraint<'a, 'tcx>( + tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, +) -> Result, NoSolution> { + let def = tcx.adt_def(def_id); + let span = tcx.def_span(def_id); + debug!("dtorck_constraint: {:?}", def); + + if def.is_phantom_data() { + let result = DtorckConstraint { + outlives: vec![], + dtorck_types: vec![tcx.mk_param_from_def(&tcx.generics_of(def_id).types[0])], + overflows: vec![], + }; + debug!("dtorck_constraint: {:?} => {:?}", def, result); + return Ok(result); + } + + let mut result = def.all_fields() + .map(|field| tcx.type_of(field.did)) + .map(|fty| dtorck_constraint_for_ty(tcx, span, fty, 0, fty)) + .collect::>()?; + result.outlives.extend(tcx.destructor_constraints(def)); + dedup_dtorck_constraint(&mut result); + + debug!("dtorck_constraint: {:?} => {:?}", def, result); + + Ok(result) +} + +fn dedup_dtorck_constraint<'tcx>(c: &mut DtorckConstraint<'tcx>) { + let mut outlives = FxHashSet(); + let mut dtorck_types = FxHashSet(); + + c.outlives.retain(|&val| outlives.replace(val).is_none()); + c.dtorck_types + .retain(|&val| dtorck_types.replace(val).is_none()); +} diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 0d92404d24b0..59083dcfbf0f 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -24,6 +24,7 @@ extern crate rustc_data_structures; extern crate syntax; extern crate syntax_pos; +mod dropck_outlives; mod normalize_projection_ty; mod util; @@ -31,6 +32,8 @@ use rustc::ty::maps::Providers; pub fn provide(p: &mut Providers) { *p = Providers { + dropck_outlives: dropck_outlives::dropck_outlives, + adt_dtorck_constraint: dropck_outlives::adt_dtorck_constraint, normalize_projection_ty: normalize_projection_ty::normalize_projection_ty, ..*p }; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index f33536227a0b..67c9832cbf9f 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -18,8 +18,8 @@ use rustc::ty::subst::{Subst, Substs, UnpackedKind}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::traits::{self, ObligationCause}; use util::common::ErrorReported; -use util::nodemap::FxHashSet; +use syntax::ast; use syntax_pos::Span; /// check_drop_impl confirms that the Drop implementation identified by @@ -282,6 +282,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( rcx: &mut RegionCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>, span: Span, + body_id: ast::NodeId, scope: region::Scope) -> Result<(), ErrorReported> { @@ -297,46 +298,15 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( }; let parent_scope = rcx.tcx.mk_region(ty::ReScope(parent_scope)); let origin = || infer::SubregionOrigin::SafeDestructor(span); - - let ty = rcx.fcx.resolve_type_vars_if_possible(&ty); - let for_ty = ty; - let mut types = vec![(ty, 0)]; - let mut known = FxHashSet(); - while let Some((ty, depth)) = types.pop() { - let ty::DtorckConstraint { - dtorck_types, outlives - } = rcx.tcx.dtorck_constraint_for_ty(span, for_ty, depth, ty)?; - - for ty in dtorck_types { - let ty = rcx.fcx.normalize_associated_types_in(span, &ty); - let ty = rcx.fcx.resolve_type_vars_with_obligations(ty); - let ty = rcx.fcx.resolve_type_and_region_vars_if_possible(&ty); - match ty.sty { - // All parameters live for the duration of the - // function. - ty::TyParam(..) => {} - - // A projection that we couldn't resolve - it - // might have a destructor. - ty::TyProjection(..) | ty::TyAnon(..) => { - rcx.type_must_outlive(origin(), ty, parent_scope); - } - - _ => { - if let None = known.replace(ty) { - types.push((ty, depth+1)); - } - } - } - } - - for outlive in outlives { - match outlive.unpack() { - UnpackedKind::Lifetime(lt) => rcx.sub_regions(origin(), parent_scope, lt), - UnpackedKind::Type(ty) => rcx.type_must_outlive(origin(), ty, parent_scope), - } + let cause = &ObligationCause::misc(span, body_id); + let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty); + debug!("dropck_outlives = {:#?}", infer_ok); + let kinds = rcx.fcx.register_infer_ok_obligations(infer_ok); + for kind in kinds { + match kind.unpack() { + UnpackedKind::Lifetime(r) => rcx.sub_regions(origin(), parent_scope, r), + UnpackedKind::Type(ty) => rcx.type_must_outlive(origin(), ty, parent_scope), } } - Ok(()) } diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index cfe8aa99bfa0..9ed4ab45a1ba 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -411,8 +411,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { self.type_of_node_must_outlive(origin, hir_id, var_region); let typ = self.resolve_node_type(hir_id); + let body_id = self.body_id; let _ = dropck::check_safety_of_destructor_if_necessary( - self, typ, span, var_scope); + self, typ, span, body_id, var_scope); }) } } @@ -884,8 +885,9 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { match *region { ty::ReScope(rvalue_scope) => { let typ = self.resolve_type(cmt.ty); + let body_id = self.body_id; let _ = dropck::check_safety_of_destructor_if_necessary( - self, typ, span, rvalue_scope); + self, typ, span, body_id, rvalue_scope); } ty::ReStatic => {} _ => { From 211d9ad7db19fcb23f0200786595b8b170382609 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Feb 2018 11:24:13 -0500 Subject: [PATCH 150/830] introduce `tcx.normalize_erasing_regions(..)` operaton [VIC] --- src/librustc/session/mod.rs | 5 ++ src/librustc/traits/query/mod.rs | 1 + .../traits/query/normalize_erasing_regions.rs | 81 +++++++++++++++++++ src/librustc/ty/maps/config.rs | 8 +- src/librustc/ty/maps/mod.rs | 7 +- src/librustc/ty/maps/plumbing.rs | 3 +- src/librustc_traits/lib.rs | 4 + .../normalize_erasing_regions.rs | 37 +++++++++ 8 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 src/librustc/traits/query/normalize_erasing_regions.rs create mode 100644 src/librustc_traits/normalize_erasing_regions.rs diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b986445ff849..3f52ecfc0999 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -179,6 +179,8 @@ pub struct PerfStats { /// result had already been canonicalized. pub canonicalized_values_allocated: Cell, /// Number of times this query is invoked. + pub normalize_ty_after_erasing_regions: Cell, + /// Number of times this query is invoked. pub normalize_projection_ty: Cell, } @@ -869,6 +871,8 @@ impl Session { self.perf_stats.queries_canonicalized.get()); println!("Total canonical values interned: {}", self.perf_stats.canonicalized_values_allocated.get()); + println!("normalize_ty_after_erasing_regions: {}", + self.perf_stats.normalize_ty_after_erasing_regions.get()); println!("normalize_projection_ty: {}", self.perf_stats.normalize_projection_ty.get()); } @@ -1159,6 +1163,7 @@ pub fn build_session_( decode_def_path_tables_time: Cell::new(Duration::from_secs(0)), queries_canonicalized: Cell::new(0), canonicalized_values_allocated: Cell::new(0), + normalize_ty_after_erasing_regions: Cell::new(0), normalize_projection_ty: Cell::new(0), }, code_stats: RefCell::new(CodeStats::new()), diff --git a/src/librustc/traits/query/mod.rs b/src/librustc/traits/query/mod.rs index 607344f9c678..f1f9256f8253 100644 --- a/src/librustc/traits/query/mod.rs +++ b/src/librustc/traits/query/mod.rs @@ -20,6 +20,7 @@ use ty::{self, Ty}; pub mod dropck_outlives; pub mod normalize; +pub mod normalize_erasing_regions; pub type CanonicalProjectionGoal<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>; diff --git a/src/librustc/traits/query/normalize_erasing_regions.rs b/src/librustc/traits/query/normalize_erasing_regions.rs new file mode 100644 index 000000000000..d2d8da88e2de --- /dev/null +++ b/src/librustc/traits/query/normalize_erasing_regions.rs @@ -0,0 +1,81 @@ +// Copyright 2014 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. + +//! Methods for normalizing when you don't care about regions (and +//! aren't doing type inference). If either of those things don't +//! apply to you, use `infcx.normalize(...)`. +//! +//! The methods in this file use a `TypeFolder` to recursively process +//! contents, invoking the underlying +//! `normalize_ty_after_erasing_regions` query for each type found +//! within. (This underlying query is what is cached.) + +use ty::{self, Ty, TyCtxt}; +use ty::fold::{TypeFoldable, TypeFolder}; + +impl<'cx, 'tcx> TyCtxt<'cx, 'tcx, 'tcx> { + /// Erase the regions in `value` and then fully normalize all the + /// types found within. The result will also have regions erased. + /// + /// This is appropriate to use only after type-check: it assumes + /// that normalization will succeed, for example. + pub fn normalize_erasing_regions(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T + where + T: TypeFoldable<'tcx>, + { + // Erase first before we do the real query -- this keeps the + // cache from being too polluted. + let value = self.erase_regions(&value); + if !value.has_projections() { + value + } else { + value.fold_with(&mut NormalizeAfterErasingRegionsFolder { + tcx: self, + param_env: param_env, + }) + } + } + + /// If you have a `Binder`, you can do this to strip out the + /// late-bound regions and then normalize the result, yielding up + /// a `T` (with regions erased). This is appropriate when the + /// binder is being instantiated at the call site. + /// + /// NB. Currently, higher-ranked type bounds inhibit + /// normalization. Therefore, each time we erase them in + /// translation, we need to normalize the contents. + pub fn normalize_erasing_late_bound_regions( + self, + param_env: ty::ParamEnv<'tcx>, + value: &ty::Binder, + ) -> T + where + T: TypeFoldable<'tcx>, + { + assert!(!value.needs_subst()); + let value = self.erase_late_bound_regions(value); + self.normalize_erasing_regions(param_env, value) + } +} + +struct NormalizeAfterErasingRegionsFolder<'cx, 'tcx: 'cx> { + tcx: TyCtxt<'cx, 'tcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, +} + +impl<'cx, 'tcx> TypeFolder<'tcx, 'tcx> for NormalizeAfterErasingRegionsFolder<'cx, 'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + self.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.tcx.normalize_ty_after_erasing_regions(self.param_env.and(ty)) + } +} diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index bcd6a5ace627..487bcf1f96ac 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -12,7 +12,7 @@ use dep_graph::SerializedDepNodeIndex; use hir::def_id::{CrateNum, DefId, DefIndex}; use mir::interpret::{GlobalId}; use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal}; -use ty::{self, Ty, TyCtxt}; +use ty::{self, ParamEnvAnd, Ty, TyCtxt}; use ty::subst::Substs; use ty::maps::queries; @@ -67,6 +67,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::dropck_outlives<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::normalize_ty_after_erasing_regions<'tcx> { + fn describe(_tcx: TyCtxt, goal: ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { + format!("normalizing `{:?}`", goal) + } +} + impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> { fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String { format!("computing whether `{}` is `Copy`", env.value) diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 4df15b2e76be..15e309c13d53 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -38,7 +38,7 @@ use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal, NoSolution}; use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; use traits::query::normalize::NormalizationResult; use traits::specialization_graph; -use ty::{self, CrateInherentImpls, Ty, TyCtxt}; +use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use ty::steal::Steal; use ty::subst::Substs; use util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet}; @@ -394,6 +394,11 @@ define_maps! { <'tcx> NoSolution, >, + /// Do not call this query directly: invoke `normalize_erasing_regions` instead. + [] fn normalize_ty_after_erasing_regions: NormalizeTyAfterErasingRegions( + ParamEnvAnd<'tcx, Ty<'tcx>> + ) -> Ty<'tcx>, + /// Do not call this query directly: invoke `infcx.at().dropck_outlives()` instead. [] fn dropck_outlives: DropckOutlives( CanonicalTyGoal<'tcx> diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 64b17922049a..53a3bcdba336 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -772,8 +772,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::FulfillObligation | DepKind::VtableMethods | DepKind::EraseRegionsTy | - DepKind::NormalizeTy | DepKind::NormalizeProjectionTy | + DepKind::NormalizeTyAfterErasingRegions | + DepKind::NormalizeTy | DepKind::DropckOutlives | DepKind::SubstituteNormalizeAndTestPredicates | DepKind::InstanceDefSizeEstimate | diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 59083dcfbf0f..45d23a2733a2 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -19,6 +19,7 @@ #[macro_use] extern crate log; +#[macro_use] extern crate rustc; extern crate rustc_data_structures; extern crate syntax; @@ -26,6 +27,7 @@ extern crate syntax_pos; mod dropck_outlives; mod normalize_projection_ty; +mod normalize_erasing_regions; mod util; use rustc::ty::maps::Providers; @@ -35,6 +37,8 @@ pub fn provide(p: &mut Providers) { dropck_outlives: dropck_outlives::dropck_outlives, adt_dtorck_constraint: dropck_outlives::adt_dtorck_constraint, normalize_projection_ty: normalize_projection_ty::normalize_projection_ty, + normalize_ty_after_erasing_regions: + normalize_erasing_regions::normalize_ty_after_erasing_regions, ..*p }; } diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/src/librustc_traits/normalize_erasing_regions.rs new file mode 100644 index 000000000000..805bf1030b3f --- /dev/null +++ b/src/librustc_traits/normalize_erasing_regions.rs @@ -0,0 +1,37 @@ +// Copyright 2014 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::traits::{Normalized, ObligationCause}; +use rustc::traits::query::NoSolution; +use rustc::ty::{ParamEnvAnd, Ty, TyCtxt}; +use rustc::util::common::CellUsizeExt; + +crate fn normalize_ty_after_erasing_regions<'tcx>( + tcx: TyCtxt<'_, 'tcx, 'tcx>, + goal: ParamEnvAnd<'tcx, Ty<'tcx>>, +) -> Ty<'tcx> { + let ParamEnvAnd { param_env, value } = goal; + tcx.sess.perf_stats.normalize_ty_after_erasing_regions.increment(); + tcx.infer_ctxt().enter(|infcx| { + let cause = ObligationCause::dummy(); + match infcx.at(&cause, param_env).normalize(&value) { + Ok(Normalized { value: normalized_value, obligations: _ }) => { + // ^^^^^^^^^^^ + // We don't care about the `obligations`, + // they are always only region relations, + // and we are about to erase those anyway. + let normalized_value = infcx.resolve_type_vars_if_possible(&normalized_value); + let normalized_value = infcx.tcx.erase_regions(&normalized_value); + tcx.lift_to_global(&normalized_value).unwrap() + } + Err(NoSolution) => bug!("could not fully normalize `{:?}`", value), + } + }) +} From e4728e494e50a3c07ff3a7d3f16369903ac70d49 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sat, 3 Mar 2018 08:23:28 -0500 Subject: [PATCH 151/830] transition various normalization functions to the new methods In particular: - `fully_normalize_monormophic_ty` => `normalize_erasing_regions` - `normalize_associated_type_in_env` => `normalize_erasing_regions` - `fully_normalize_associated_types_in` => `normalize_erasing_regions` - `erase_late_bound_regions_and_normalize` => `normalize_erasing_late_bound_regions` --- src/librustc/dep_graph/dep_node.rs | 1 - src/librustc/infer/mod.rs | 136 +------------------ src/librustc/traits/mod.rs | 5 +- src/librustc/traits/trans/mod.rs | 80 +---------- src/librustc/ty/context.rs | 3 - src/librustc/ty/instance.rs | 2 +- src/librustc/ty/layout.rs | 12 +- src/librustc/ty/maps/config.rs | 6 - src/librustc/ty/maps/mod.rs | 5 - src/librustc/ty/maps/plumbing.rs | 1 - src/librustc_lint/types.rs | 19 +-- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 6 +- src/librustc_mir/interpret/terminator/mod.rs | 15 +- src/librustc_mir/monomorphize/item.rs | 5 +- src/librustc_mir/monomorphize/mod.rs | 2 +- src/librustc_mir/shim.rs | 9 +- src/librustc_mir/util/elaborate_drops.rs | 9 +- src/librustc_trans/abi.rs | 2 +- src/librustc_trans/base.rs | 2 +- src/librustc_trans/debuginfo/metadata.rs | 9 +- src/librustc_trans/debuginfo/mod.rs | 6 +- src/librustc_trans/debuginfo/type_names.rs | 8 +- src/librustc_trans/declare.rs | 4 +- src/librustc_trans/intrinsic.rs | 7 +- src/librustc_trans/mir/block.rs | 10 +- src/librustc_trans/mir/mod.rs | 3 +- src/librustc_trans/type_of.rs | 5 +- 28 files changed, 91 insertions(+), 283 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 130fbc192677..8d7fef90b754 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -635,7 +635,6 @@ define_dep_nodes!( <'tcx> [] CodegenUnit(InternedString), [] CompileCodegenUnit(InternedString), [input] OutputFilenames, - [anon] NormalizeTy, [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>), [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>), [] DropckOutlives(CanonicalTyGoal<'tcx>), diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 2c58e17b2833..217a157cb33e 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -21,7 +21,6 @@ use hir::def_id::DefId; use middle::free_region::RegionRelations; use middle::region; use middle::lang_items; -use mir::tcx::PlaceTy; use ty::subst::Substs; use ty::{TyVid, IntVid, FloatVid}; use ty::{self, Ty, TyCtxt}; @@ -35,7 +34,7 @@ use std::collections::BTreeMap; use std::fmt; use syntax::ast; use errors::DiagnosticBuilder; -use syntax_pos::{self, Span, DUMMY_SP}; +use syntax_pos::{self, Span}; use util::nodemap::FxHashMap; use arena::DroplessArena; @@ -493,140 +492,7 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> { _in_progress_tables: Option>>, } -/// Helper trait for shortening the lifetimes inside a -/// value for post-type-checking normalization. -/// -/// This trait offers a normalization method where the inputs and -/// outputs both have the `'gcx` lifetime; the implementations -/// internally create inference contexts and/or lift as needed. -pub trait TransNormalize<'gcx>: TypeFoldable<'gcx> { - fn trans_normalize<'a, 'tcx>(&self, - infcx: &InferCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>) - -> Self; -} - -macro_rules! items { ($($item:item)+) => ($($item)+) } -macro_rules! impl_trans_normalize { - ($lt_gcx:tt, $($ty:ty),+) => { - items!($(impl<$lt_gcx> TransNormalize<$lt_gcx> for $ty { - fn trans_normalize<'a, 'tcx>(&self, - infcx: &InferCtxt<'a, $lt_gcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>) - -> Self { - infcx.normalize_projections_in(param_env, self) - } - })+); - } -} - -impl_trans_normalize!('gcx, - Ty<'gcx>, - &'gcx ty::Const<'gcx>, - &'gcx Substs<'gcx>, - ty::FnSig<'gcx>, - ty::PolyFnSig<'gcx>, - ty::ClosureSubsts<'gcx>, - ty::PolyTraitRef<'gcx>, - ty::ExistentialTraitRef<'gcx> -); - -impl<'gcx> TransNormalize<'gcx> for PlaceTy<'gcx> { - fn trans_normalize<'a, 'tcx>(&self, - infcx: &InferCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>) - -> Self { - match *self { - PlaceTy::Ty { ty } => PlaceTy::Ty { ty: ty.trans_normalize(infcx, param_env) }, - PlaceTy::Downcast { adt_def, substs, variant_index } => { - PlaceTy::Downcast { - adt_def, - substs: substs.trans_normalize(infcx, param_env), - variant_index, - } - } - } - } -} - -// NOTE: Callable from trans only! -impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { - /// Currently, higher-ranked type bounds inhibit normalization. Therefore, - /// each time we erase them in translation, we need to normalize - /// the contents. - pub fn erase_late_bound_regions_and_normalize(self, value: &ty::Binder) - -> T - where T: TransNormalize<'tcx> - { - assert!(!value.needs_subst()); - let value = self.erase_late_bound_regions(value); - self.fully_normalize_associated_types_in(&value) - } - - /// Fully normalizes any associated types in `value`, using an - /// empty environment and `Reveal::All` mode (therefore, suitable - /// only for monomorphized code during trans, basically). - pub fn fully_normalize_associated_types_in(self, value: &T) -> T - where T: TransNormalize<'tcx> - { - debug!("fully_normalize_associated_types_in(t={:?})", value); - - let param_env = ty::ParamEnv::reveal_all(); - let value = self.erase_regions(value); - - if !value.has_projections() { - return value; - } - - self.infer_ctxt().enter(|infcx| { - value.trans_normalize(&infcx, param_env) - }) - } - - /// Does a best-effort to normalize any associated types in - /// `value`; this includes revealing specializable types, so this - /// should be not be used during type-checking, but only during - /// optimization and code generation. - pub fn normalize_associated_type_in_env( - self, value: &T, env: ty::ParamEnv<'tcx> - ) -> T - where T: TransNormalize<'tcx> - { - debug!("normalize_associated_type_in_env(t={:?})", value); - - let value = self.erase_regions(value); - - if !value.has_projections() { - return value; - } - - self.infer_ctxt().enter(|infcx| { - value.trans_normalize(&infcx, env.with_reveal_all()) - }) - } -} - impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { - fn normalize_projections_in(&self, param_env: ty::ParamEnv<'tcx>, value: &T) -> T::Lifted - where T: TypeFoldable<'tcx> + ty::Lift<'gcx> - { - let mut selcx = traits::SelectionContext::new(self); - let cause = traits::ObligationCause::dummy(); - let traits::Normalized { value: result, obligations } = - traits::normalize(&mut selcx, param_env, cause, value); - - debug!("normalize_projections_in: result={:?} obligations={:?}", - result, obligations); - - let mut fulfill_cx = traits::FulfillmentContext::new(); - - for obligation in obligations { - fulfill_cx.register_predicate_obligation(self, obligation); - } - - self.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result) - } - /// Finishes processes any obligations that remain in the /// fulfillment context, and then returns the result with all type /// variables removed and regions erased. Because this is intended diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 3e23e3823470..a2a5aa246cf7 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -770,7 +770,10 @@ fn vtable_methods<'a, 'tcx>( // the trait type may have higher-ranked lifetimes in it; // so erase them if they appear, so that we get the type // at some particular call site - let substs = tcx.erase_late_bound_regions_and_normalize(&ty::Binder(substs)); + let substs = tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &ty::Binder(substs), + ); // It's possible that the method relies on where clauses that // do not hold for this particular set of type parameters. diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs index c873580e3ad6..c97f6f199d2f 100644 --- a/src/librustc/traits/trans/mod.rs +++ b/src/librustc/traits/trans/mod.rs @@ -14,14 +14,13 @@ // general routines. use dep_graph::{DepKind, DepTrackingMapConfig}; -use infer::TransNormalize; use std::marker::PhantomData; use syntax_pos::DUMMY_SP; use hir::def_id::DefId; use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, Vtable}; use ty::{self, Ty, TyCtxt}; use ty::subst::{Subst, Substs}; -use ty::fold::{TypeFoldable, TypeFolder}; +use ty::fold::TypeFoldable; /// Attempts to resolve an obligation to a vtable.. The result is /// a shallow vtable resolution -- meaning that we do not @@ -93,12 +92,11 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { param_substs: &Substs<'tcx>, value: &T) -> T - where T: TransNormalize<'tcx> + where T: TypeFoldable<'tcx> { debug!("apply_param_substs(param_substs={:?}, value={:?})", param_substs, value); let substituted = value.subst(self, param_substs); - let substituted = self.erase_regions(&substituted); - AssociatedTypeNormalizer::new(self).fold(&substituted) + self.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted) } pub fn trans_apply_param_substs_env( @@ -108,7 +106,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { value: &T, ) -> T where - T: TransNormalize<'tcx>, + T: TypeFoldable<'tcx>, { debug!( "apply_param_substs_env(param_substs={:?}, value={:?}, param_env={:?})", @@ -117,8 +115,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { param_env, ); let substituted = value.subst(self, param_substs); - let substituted = self.erase_regions(&substituted); - AssociatedTypeNormalizerEnv::new(self, param_env).fold(&substituted) + self.normalize_erasing_regions(param_env, substituted) } pub fn trans_impl_self_ty(&self, def_id: DefId, substs: &'tcx Substs<'tcx>) @@ -128,73 +125,6 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } } -struct AssociatedTypeNormalizer<'a, 'gcx: 'a> { - tcx: TyCtxt<'a, 'gcx, 'gcx>, -} - -impl<'a, 'gcx> AssociatedTypeNormalizer<'a, 'gcx> { - fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) -> Self { - AssociatedTypeNormalizer { tcx } - } - - fn fold>(&mut self, value: &T) -> T { - if !value.has_projections() { - value.clone() - } else { - value.fold_with(self) - } - } -} - -impl<'a, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizer<'a, 'gcx> { - fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'gcx> { - self.tcx - } - - fn fold_ty(&mut self, ty: Ty<'gcx>) -> Ty<'gcx> { - if !ty.has_projections() { - ty - } else { - debug!("AssociatedTypeNormalizer: ty={:?}", ty); - self.tcx.fully_normalize_monormophic_ty(ty) - } - } -} - -struct AssociatedTypeNormalizerEnv<'a, 'gcx: 'a> { - tcx: TyCtxt<'a, 'gcx, 'gcx>, - param_env: ty::ParamEnv<'gcx>, -} - -impl<'a, 'gcx> AssociatedTypeNormalizerEnv<'a, 'gcx> { - fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>, param_env: ty::ParamEnv<'gcx>) -> Self { - Self { tcx, param_env } - } - - fn fold>(&mut self, value: &T) -> T { - if !value.has_projections() { - value.clone() - } else { - value.fold_with(self) - } - } -} - -impl<'a, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizerEnv<'a, 'gcx> { - fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'gcx> { - self.tcx - } - - fn fold_ty(&mut self, ty: Ty<'gcx>) -> Ty<'gcx> { - if !ty.has_projections() { - ty - } else { - debug!("AssociatedTypeNormalizerEnv: ty={:?}", ty); - self.tcx.normalize_associated_type_in_env(&ty, self.param_env) - } - } -} - // Implement DepTrackingMapConfig for `trait_cache` pub struct TraitSelectionCache<'tcx> { data: PhantomData<&'tcx ()> diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 24d3b37f804e..9a687028b582 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2537,9 +2537,6 @@ pub fn provide(providers: &mut ty::maps::Providers) { assert_eq!(cnum, LOCAL_CRATE); tcx.features().clone_closures }; - providers.fully_normalize_monormophic_ty = |tcx, ty| { - tcx.fully_normalize_associated_types_in(&ty) - }; providers.features_query = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); Lrc::new(tcx.sess.features_untracked().clone()) diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index ebb058c5d292..180fb9cabd3f 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -352,7 +352,7 @@ fn fn_once_adapter_instance<'a, 'tcx>( closure_did, substs); let sig = substs.closure_sig(closure_did, tcx); - let sig = tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); assert_eq!(sig.inputs().len(), 1); let substs = tcx.mk_substs([Kind::from(self_ty), sig.inputs()[0].into()].iter().cloned()); diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 9ce232ba1730..04353d2ece19 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1213,7 +1213,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { data_ptr.valid_range.start = 1; } - let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env); + let pointee = tcx.normalize_erasing_regions(param_env, pointee); if pointee.is_sized(tcx.at(DUMMY_SP), param_env) { return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr))); } @@ -1241,7 +1241,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { // Arrays and slices. ty::TyArray(element, mut count) => { if count.has_projections() { - count = tcx.normalize_associated_type_in_env(&count, param_env); + count = tcx.normalize_erasing_regions(param_env, count); if count.has_projections() { return Err(LayoutError::Unknown(ty)); } @@ -1686,7 +1686,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { // Types with no meaningful known layout. ty::TyProjection(_) | ty::TyAnon(..) => { - let normalized = tcx.normalize_associated_type_in_env(&ty, param_env); + let normalized = tcx.normalize_erasing_regions(param_env, ty); if ty == normalized { return Err(LayoutError::Unknown(ty)); } @@ -1953,7 +1953,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> { } ty::TyProjection(_) | ty::TyAnon(..) => { - let normalized = tcx.normalize_associated_type_in_env(&ty, param_env); + let normalized = tcx.normalize_erasing_regions(param_env, ty); if ty == normalized { Err(err) } else { @@ -2059,7 +2059,7 @@ impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { /// executes in "reveal all" mode. fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { let param_env = self.param_env.with_reveal_all(); - let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env); + let ty = self.tcx.normalize_erasing_regions(param_env, ty); let details = self.tcx.layout_raw(param_env.and(ty))?; let layout = TyLayout { ty, @@ -2085,7 +2085,7 @@ impl<'a, 'tcx> LayoutOf> for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx /// executes in "reveal all" mode. fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { let param_env = self.param_env.with_reveal_all(); - let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env); + let ty = self.tcx.normalize_erasing_regions(param_env, ty); let details = self.tcx.layout_raw(param_env.and(ty))?; let layout = TyLayout { ty, diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 487bcf1f96ac..dbfe7770bbde 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -610,12 +610,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::has_copy_closures<'tcx> { } } -impl<'tcx> QueryDescription<'tcx> for queries::fully_normalize_monormophic_ty<'tcx> { - fn describe(_tcx: TyCtxt, _: Ty) -> String { - format!("normalizing types") - } -} - impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> { fn describe(_tcx: TyCtxt, _: CrateNum) -> String { format!("looking up enabled feature gates") diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 15e309c13d53..7d726d2e3cd5 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -384,7 +384,6 @@ define_maps! { <'tcx> // Normally you would just use `tcx.erase_regions(&value)`, // however, which uses this query as a kind of cache. [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>, - [] fn fully_normalize_monormophic_ty: normalize_ty_node(Ty<'tcx>) -> Ty<'tcx>, /// Do not call this query directly: invoke `normalize` instead. [] fn normalize_projection_ty: NormalizeProjectionTy( @@ -565,10 +564,6 @@ fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructo DepConstructor::VtableMethods{ trait_ref } } -fn normalize_ty_node<'tcx>(_: Ty<'tcx>) -> DepConstructor<'tcx> { - DepConstructor::NormalizeTy -} - fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs<'tcx>)) -> DepConstructor<'tcx> { DepConstructor::SubstituteNormalizeAndTestPredicates { key } diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 53a3bcdba336..bc7186f781a8 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -774,7 +774,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::EraseRegionsTy | DepKind::NormalizeProjectionTy | DepKind::NormalizeTyAfterErasingRegions | - DepKind::NormalizeTy | DepKind::DropckOutlives | DepKind::SubstituteNormalizeAndTestPredicates | DepKind::InstanceDefSizeEstimate | diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 266f322e3977..445fe0cc4019 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -12,7 +12,7 @@ use rustc::hir::map as hir_map; use rustc::ty::subst::Substs; -use rustc::ty::{self, AdtKind, Ty, TyCtxt}; +use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc::ty::layout::{self, LayoutOf}; use util::nodemap::FxHashSet; use lint::{LateContext, LintContext, LintArray}; @@ -509,8 +509,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // make sure the fields are actually safe. let mut all_phantom = true; for field in &def.non_enum_variant().fields { - let field_ty = cx.fully_normalize_associated_types_in( - &field.ty(cx, substs) + let field_ty = cx.normalize_erasing_regions( + ParamEnv::reveal_all(), + field.ty(cx, substs), ); // repr(transparent) types are allowed to have arbitrary ZSTs, not just // PhantomData -- skip checking all ZST fields @@ -556,8 +557,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { let mut all_phantom = true; for field in &def.non_enum_variant().fields { - let field_ty = cx.fully_normalize_associated_types_in( - &field.ty(cx, substs) + let field_ty = cx.normalize_erasing_regions( + ParamEnv::reveal_all(), + field.ty(cx, substs), ); let r = self.check_type_for_ffi(cache, field_ty); match r { @@ -596,8 +598,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { // Check the contained variants. for variant in &def.variants { for field in &variant.fields { - let arg = cx.fully_normalize_associated_types_in( - &field.ty(cx, substs) + let arg = cx.normalize_erasing_regions( + ParamEnv::reveal_all(), + field.ty(cx, substs), ); let r = self.check_type_for_ffi(cache, arg); match r { @@ -716,7 +719,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) { // it is only OK to use this function because extern fns cannot have // any generic types right now: - let ty = self.cx.tcx.fully_normalize_associated_types_in(&ty); + let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); match self.check_type_for_ffi(&mut FxHashSet(), ty) { FfiResult::FfiSafe => {} diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 3f111ebcb780..8da7c497973e 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -732,7 +732,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { for (index, field) in def.all_fields().enumerate() { let gcx = self.tcx.global_tcx(); let field_ty = field.ty(gcx, substs); - let field_ty = gcx.normalize_associated_type_in_env(&field_ty, self.param_env); + let field_ty = gcx.normalize_erasing_regions(self.param_env, field_ty); let place = drop_place.clone().field(Field::new(index), field_ty); self.visit_terminator_drop(loc, term, flow_state, &place, field_ty, span); diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index d766ea3e2bd0..abe45267a1f9 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -285,10 +285,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M pub fn monomorphize(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> { // miri doesn't care about lifetimes, and will choke on some crazy ones // let's simply get rid of them - let without_lifetimes = self.tcx.erase_regions(&ty); - let substituted = without_lifetimes.subst(*self.tcx, substs); - let substituted = self.tcx.fully_normalize_monormophic_ty(&substituted); - substituted + let substituted = ty.subst(*self.tcx, substs); + self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted) } /// Return the size and aligment of the value at the given type. diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index babc78470147..a729e3a5dda8 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -75,8 +75,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { match instance_ty.sty { ty::TyFnDef(..) => { let real_sig = instance_ty.fn_sig(*self.tcx); - let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig); - let real_sig = self.tcx.erase_late_bound_regions_and_normalize(&real_sig); + let sig = self.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &sig, + ); + let real_sig = self.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &real_sig, + ); if !self.check_sig_compat(sig, real_sig)? { return err!(FunctionPointerTyMismatch(real_sig, sig)); } @@ -95,7 +101,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { } }; let args = self.operands_to_args(args)?; - let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = self.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &sig, + ); self.eval_fn_call( fn_def, destination, diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 1f7f1237ba78..10e2a84038de 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -347,7 +347,10 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { output.push_str("fn("); - let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = self.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &sig, + ); if !sig.inputs().is_empty() { for ¶meter_type in sig.inputs() { diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs index 4c9789782a6e..5c38735d9203 100644 --- a/src/librustc_mir/monomorphize/mod.rs +++ b/src/librustc_mir/monomorphize/mod.rs @@ -88,7 +88,7 @@ fn fn_once_adapter_instance<'a, 'tcx>( closure_did, substs); let sig = substs.closure_sig(closure_did, tcx); - let sig = tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); assert_eq!(sig.inputs().len(), 1); let substs = tcx.mk_substs([ Kind::from(self_ty), diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 9aff7fa2a2c7..62af09cc4910 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -832,14 +832,11 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, let tcx = infcx.tcx; let gcx = tcx.global_tcx(); let def_id = tcx.hir.local_def_id(ctor_id); - let sig = gcx.fn_sig(def_id).no_late_bound_regions() - .expect("LBR in ADT constructor signature"); - let sig = gcx.erase_regions(&sig); let param_env = gcx.param_env(def_id); - // Normalize the sig now that we have liberated the late-bound - // regions. - let sig = gcx.normalize_associated_type_in_env(&sig, param_env); + // Normalize the sig. + let sig = gcx.fn_sig(def_id).no_late_bound_regions().expect("LBR in ADT constructor signature"); + let sig = gcx.normalize_erasing_regions(param_env, sig); let (adt_def, substs) = match sig.output().sty { ty::TyAdt(adt_def, substs) => (adt_def, substs), diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 458dd488409e..3f5208dd2d4b 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -206,11 +206,10 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let field = Field::new(i); let subpath = self.elaborator.field_subpath(variant_path, field); - let field_ty = - self.tcx().normalize_associated_type_in_env( - &f.ty(self.tcx(), substs), - self.elaborator.param_env() - ); + let field_ty = self.tcx().normalize_erasing_regions( + self.elaborator.param_env(), + f.ty(self.tcx(), substs), + ); (base_place.clone().field(field, field_ty), subpath) }).collect() } diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index ee0f2415bd80..c1dc8c6684a1 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -650,7 +650,7 @@ impl<'a, 'tcx> FnType<'tcx> { -> Self { let fn_ty = instance.ty(cx.tcx); let sig = ty_fn_sig(cx, fn_ty); - let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); FnType::new(cx, sig, &[]) } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 76e05ae7dcb8..4da082e9d50f 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -462,7 +462,7 @@ pub fn trans_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tc let fn_ty = instance.ty(cx.tcx); let sig = common::ty_fn_sig(cx, fn_ty); - let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); let lldecl = match cx.instances.borrow().get(&instance) { Some(&val) => val, diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index d20b51ca0fdf..20cc57522b5d 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -30,7 +30,7 @@ use rustc::ty::util::TypeIdHasher; use rustc::ich::Fingerprint; use rustc::ty::Instance; use common::CodegenCx; -use rustc::ty::{self, AdtKind, Ty, TyCtxt}; +use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; use rustc::session::config; use rustc::util::nodemap::FxHashMap; @@ -353,7 +353,10 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, span: Span) -> MetadataCreationResult { - let signature = cx.tcx.erase_late_bound_regions_and_normalize(&signature); + let signature = cx.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &signature, + ); let mut signature_metadata: Vec = Vec::with_capacity(signature.inputs().len() + 1); @@ -589,7 +592,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } ty::TyGenerator(def_id, substs, _) => { let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| { - cx.tcx.fully_normalize_associated_types_in(&t) + cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t) }).collect(); prepare_tuple_metadata(cx, t, diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 16279f31836a..683e1835968f 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -30,7 +30,7 @@ use abi::Abi; use common::CodegenCx; use builder::Builder; use monomorphize::Instance; -use rustc::ty::{self, Ty}; +use rustc::ty::{self, ParamEnv, Ty}; use rustc::mir; use rustc::session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; @@ -378,7 +378,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name_to_append_suffix_to.push_str(","); } - let actual_type = cx.tcx.fully_normalize_associated_types_in(&actual_type); + let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), actual_type); // Add actual type name to <...> clause of function name let actual_type_name = compute_debuginfo_type_name(cx, actual_type, @@ -391,7 +391,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo { let names = get_type_parameter_names(cx, generics); substs.types().zip(names).map(|(ty, name)| { - let actual_type = cx.tcx.fully_normalize_associated_types_in(&ty); + let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP); let name = CString::new(name.as_str().as_bytes()).unwrap(); unsafe { diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index a88eb9ae3547..211de95c96ed 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -117,8 +117,10 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, }, ty::TyDynamic(ref trait_data, ..) => { if let Some(principal) = trait_data.principal() { - let principal = cx.tcx.erase_late_bound_regions_and_normalize( - &principal); + let principal = cx.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &principal, + ); push_item_name(cx, principal.def_id, false, output); push_type_params(cx, principal.substs, output); } @@ -138,7 +140,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, output.push_str("fn("); - let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); if !sig.inputs().is_empty() { for ¶meter_type in sig.inputs() { push_debuginfo_type_name(cx, parameter_type, true, output); diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index aa1cd0c27e79..c2010feb1b63 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -22,7 +22,7 @@ use llvm::{self, ValueRef}; use llvm::AttributePlace::Function; -use rustc::ty::Ty; +use rustc::ty::{self, Ty}; use rustc::session::config::Sanitizer; use rustc_back::PanicStrategy; use abi::{Abi, FnType}; @@ -127,7 +127,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str, fn_type: Ty<'tcx>) -> ValueRef { debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type); let sig = common::ty_fn_sig(cx, fn_type); - let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); debug!("declare_rust_fn (after region erasure) sig={:?}", sig); let fty = FnType::new(cx, sig, &[]); diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 3f87ce7e0479..4cef7470c62d 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -100,7 +100,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, }; let sig = callee_ty.fn_sig(tcx); - let sig = tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); let arg_tys = sig.inputs(); let ret_ty = sig.output(); let name = &*tcx.item_name(def_id); @@ -1035,7 +1035,10 @@ fn generic_simd_intrinsic<'a, 'tcx>( let tcx = bx.tcx(); - let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig(tcx)); + let sig = tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &callee_ty.fn_sig(tcx), + ); let arg_tys = sig.inputs(); // every intrinsic takes a SIMD vector as its first argument diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 606c1396c1da..96c5bb3b91d2 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -281,7 +281,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { ty::TyDynamic(..) => { let fn_ty = drop_fn.ty(bx.cx.tcx); let sig = common::ty_fn_sig(bx.cx, fn_ty); - let sig = bx.tcx().erase_late_bound_regions_and_normalize(&sig); + let sig = bx.tcx().normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &sig, + ); let fn_ty = FnType::new_vtable(bx.cx, sig, &[]); args = &args[..1]; (meth::DESTRUCTOR.get_fn(&bx, place.llextra, &fn_ty), fn_ty) @@ -430,7 +433,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { }; let def = instance.map(|i| i.def); let sig = callee.layout.ty.fn_sig(bx.tcx()); - let sig = bx.tcx().erase_late_bound_regions_and_normalize(&sig); + let sig = bx.tcx().normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &sig, + ); let abi = sig.abi; // Handle intrinsics old trans wants Expr's for, ourselves. diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index a1044ac87e4c..a92a59edfde1 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -16,7 +16,6 @@ use rustc::ty::{self, TypeFoldable}; use rustc::ty::layout::{LayoutOf, TyLayout}; use rustc::mir::{self, Mir}; use rustc::ty::subst::Substs; -use rustc::infer::TransNormalize; use rustc::session::config::FullDebugInfo; use base; use builder::Builder; @@ -108,7 +107,7 @@ pub struct FunctionCx<'a, 'tcx:'a> { impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn monomorphize(&self, value: &T) -> T - where T: TransNormalize<'tcx> + where T: TypeFoldable<'tcx> { self.cx.tcx.trans_apply_param_substs(self.param_substs, value) } diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index af957500f700..f37114ee4acd 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -258,7 +258,10 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> { cx.layout_of(self.ty.boxed_ty()).llvm_type(cx).ptr_to() } ty::TyFnPtr(sig) => { - let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig); + let sig = cx.tcx.normalize_erasing_late_bound_regions( + ty::ParamEnv::reveal_all(), + &sig, + ); FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to() } _ => self.scalar_llvm_type_at(cx, scalar, Size::from_bytes(0)) From 0a2ac85e3fa8c1c05a7e2b5b412c073ce7853f23 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 13 Feb 2018 09:15:01 -0500 Subject: [PATCH 152/830] move `drain_fulfillment_cx_or_panic` to be private to traits::trans --- src/librustc/infer/mod.rs | 40 ----------------------------- src/librustc/traits/trans/mod.rs | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 217a157cb33e..fe919775da0b 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -493,46 +493,6 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> { } impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { - /// Finishes processes any obligations that remain in the - /// fulfillment context, and then returns the result with all type - /// variables removed and regions erased. Because this is intended - /// for use after type-check has completed, if any errors occur, - /// it will panic. It is used during normalization and other cases - /// where processing the obligations in `fulfill_cx` may cause - /// type inference variables that appear in `result` to be - /// unified, and hence we need to process those obligations to get - /// the complete picture of the type. - pub fn drain_fulfillment_cx_or_panic(&self, - span: Span, - fulfill_cx: &mut traits::FulfillmentContext<'tcx>, - result: &T) - -> T::Lifted - where T: TypeFoldable<'tcx> + ty::Lift<'gcx> - { - debug!("drain_fulfillment_cx_or_panic()"); - - // In principle, we only need to do this so long as `result` - // contains unbound type parameters. It could be a slight - // optimization to stop iterating early. - match fulfill_cx.select_all_or_error(self) { - Ok(()) => { } - Err(errors) => { - span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking", - errors); - } - } - - let result = self.resolve_type_vars_if_possible(result); - let result = self.tcx.erase_regions(&result); - - match self.tcx.lift_to_global(&result) { - Some(result) => result, - None => { - span_bug!(span, "Uninferred types/regions in `{:?}`", result); - } - } - } - pub fn is_in_snapshot(&self) -> bool { self.in_snapshot.get() } diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs index c97f6f199d2f..86f9d168ad30 100644 --- a/src/librustc/traits/trans/mod.rs +++ b/src/librustc/traits/trans/mod.rs @@ -17,6 +17,8 @@ use dep_graph::{DepKind, DepTrackingMapConfig}; use std::marker::PhantomData; use syntax_pos::DUMMY_SP; use hir::def_id::DefId; +use infer::InferCtxt; +use syntax_pos::Span; use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, Vtable}; use ty::{self, Ty, TyCtxt}; use ty::subst::{Subst, Substs}; @@ -151,3 +153,45 @@ impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> { DepKind::TraitSelect } } + +impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { + /// Finishes processes any obligations that remain in the + /// fulfillment context, and then returns the result with all type + /// variables removed and regions erased. Because this is intended + /// for use after type-check has completed, if any errors occur, + /// it will panic. It is used during normalization and other cases + /// where processing the obligations in `fulfill_cx` may cause + /// type inference variables that appear in `result` to be + /// unified, and hence we need to process those obligations to get + /// the complete picture of the type. + fn drain_fulfillment_cx_or_panic(&self, + span: Span, + fulfill_cx: &mut FulfillmentContext<'tcx>, + result: &T) + -> T::Lifted + where T: TypeFoldable<'tcx> + ty::Lift<'gcx> + { + debug!("drain_fulfillment_cx_or_panic()"); + + // In principle, we only need to do this so long as `result` + // contains unbound type parameters. It could be a slight + // optimization to stop iterating early. + match fulfill_cx.select_all_or_error(self) { + Ok(()) => { } + Err(errors) => { + span_bug!(span, "Encountered errors `{:?}` resolving bounds after type-checking", + errors); + } + } + + let result = self.resolve_type_vars_if_possible(result); + let result = self.tcx.erase_regions(&result); + + match self.tcx.lift_to_global(&result) { + Some(result) => result, + None => { + span_bug!(span, "Uninferred types/regions in `{:?}`", result); + } + } + } +} From 36e5092dfa7fcc676c7d6b63f8dd692edd3399a5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 26 Feb 2018 11:14:16 -0500 Subject: [PATCH 153/830] add some debug output --- src/librustc/traits/query/dropck_outlives.rs | 3 ++- src/librustc/traits/query/normalize.rs | 6 ++++++ src/librustc/traits/query/normalize_erasing_regions.rs | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 5c964f6559a3..cfcd951d4906 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -38,7 +38,8 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec>> { debug!( "dropck_outlives(ty={:?}, param_env={:?})", - ty, self.param_env, + ty, + self.param_env, ); let tcx = self.infcx.tcx; diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 030e630f23f8..70c5cf5f3902 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -45,6 +45,12 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { where T: TypeFoldable<'tcx>, { + debug!( + "normalize::<{}>(value={:?}, param_env={:?})", + unsafe { ::std::intrinsics::type_name::() }, + value, + self.param_env, + ); let mut normalizer = QueryNormalizer { infcx: self.infcx, cause: self.cause, diff --git a/src/librustc/traits/query/normalize_erasing_regions.rs b/src/librustc/traits/query/normalize_erasing_regions.rs index d2d8da88e2de..a9734e9c2986 100644 --- a/src/librustc/traits/query/normalize_erasing_regions.rs +++ b/src/librustc/traits/query/normalize_erasing_regions.rs @@ -30,6 +30,13 @@ impl<'cx, 'tcx> TyCtxt<'cx, 'tcx, 'tcx> { where T: TypeFoldable<'tcx>, { + debug!( + "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", + unsafe { ::std::intrinsics::type_name::() }, + value, + param_env, + ); + // Erase first before we do the real query -- this keeps the // cache from being too polluted. let value = self.erase_regions(&value); From 1e4e632ad8be2be00a1894c6c5946b730e12a5bd Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 27 Feb 2018 16:14:41 -0500 Subject: [PATCH 154/830] add regression tests for various MIR bugs that get fixed Fixes #31567 Fixes #47470 Fixes #48132 Fixes #48179 --- src/test/ui/issue-48132.rs | 42 ++++++++++++++++++++++++ src/test/ui/issue-48179.rs | 51 ++++++++++++++++++++++++++++++ src/test/ui/nll/issue-31567.rs | 37 ++++++++++++++++++++++ src/test/ui/nll/issue-31567.stderr | 18 +++++++++++ src/test/ui/nll/issue-47470.rs | 34 ++++++++++++++++++++ src/test/ui/nll/issue-47470.stderr | 17 ++++++++++ 6 files changed, 199 insertions(+) create mode 100644 src/test/ui/issue-48132.rs create mode 100644 src/test/ui/issue-48179.rs create mode 100644 src/test/ui/nll/issue-31567.rs create mode 100644 src/test/ui/nll/issue-31567.stderr create mode 100644 src/test/ui/nll/issue-47470.rs create mode 100644 src/test/ui/nll/issue-47470.stderr diff --git a/src/test/ui/issue-48132.rs b/src/test/ui/issue-48132.rs new file mode 100644 index 000000000000..87fee986de76 --- /dev/null +++ b/src/test/ui/issue-48132.rs @@ -0,0 +1,42 @@ +// Copyright 2015 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 #48132. This was failing due to problems around +// the projection caching and dropck type enumeration. + +// run-pass + +#![feature(nll)] +#![allow(warnings)] + +struct Inner { + iterator: I, + item: V, +} + +struct Outer { + inner: Inner, +} + +fn outer(iterator: I) -> Outer +where I: Iterator, + I::Item: Default, +{ + Outer { + inner: Inner { + iterator: iterator, + item: Default::default(), + } + } +} + +fn main() { + outer(std::iter::once(&1).cloned()); +} diff --git a/src/test/ui/issue-48179.rs b/src/test/ui/issue-48179.rs new file mode 100644 index 000000000000..745b59e0658f --- /dev/null +++ b/src/test/ui/issue-48179.rs @@ -0,0 +1,51 @@ +// Copyright 2015 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 #48132. This was failing due to problems around +// the projection caching and dropck type enumeration. + +// run-pass + +#![feature(nll)] +#![allow(warnings)] + +pub struct Container { + value: Option, +} + +impl Container { + pub fn new(iter: T) -> Self { + panic!() + } +} + +pub struct Wrapper<'a> { + content: &'a Content, +} + +impl<'a, 'de> Wrapper<'a> { + pub fn new(content: &'a Content) -> Self { + Wrapper { + content: content, + } + } +} + +pub struct Content; + +fn crash_it(content: Content) { + let items = vec![content]; + let map = items.iter().map(|ref o| Wrapper::new(o)); + + let mut map_visitor = Container::new(map); + +} + +fn main() {} diff --git a/src/test/ui/nll/issue-31567.rs b/src/test/ui/nll/issue-31567.rs new file mode 100644 index 000000000000..a0d1faf1f0e8 --- /dev/null +++ b/src/test/ui/nll/issue-31567.rs @@ -0,0 +1,37 @@ +// 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. + +// Regression test for #31567: cached results of projections were +// causing region relations not to be enforced at all the places where +// they have to be enforced. + +#![feature(nll)] + +struct VecWrapper<'a>(&'a mut S); + +struct S(Box); + +fn get_dangling<'a>(v: VecWrapper<'a>) -> &'a u32 { + let s_inner: &'a S = &*v.0; //~ ERROR `*v.0` does not live long enough + &s_inner.0 +} + +impl<'a> Drop for VecWrapper<'a> { + fn drop(&mut self) { + *self.0 = S(Box::new(0)); + } +} + +fn main() { + let mut s = S(Box::new(11)); + let vw = VecWrapper(&mut s); + let dangling = get_dangling(vw); + println!("{}", dangling); +} diff --git a/src/test/ui/nll/issue-31567.stderr b/src/test/ui/nll/issue-31567.stderr new file mode 100644 index 000000000000..e0ff653e2b4d --- /dev/null +++ b/src/test/ui/nll/issue-31567.stderr @@ -0,0 +1,18 @@ +error[E0597]: `*v.0` does not live long enough + --> $DIR/issue-31567.rs:22:26 + | +LL | let s_inner: &'a S = &*v.0; //~ ERROR `*v.0` does not live long enough + | ^^^^^ borrowed value does not live long enough +LL | &s_inner.0 +LL | } + | - borrowed value only lives until here + | +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 21:1... + --> $DIR/issue-31567.rs:21:1 + | +LL | fn get_dangling<'a>(v: VecWrapper<'a>) -> &'a u32 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0597" diff --git a/src/test/ui/nll/issue-47470.rs b/src/test/ui/nll/issue-47470.rs new file mode 100644 index 000000000000..c962f193cd5b --- /dev/null +++ b/src/test/ui/nll/issue-47470.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. + +// Regression test for #47470: cached results of projections were +// causing region relations not to be enforced at all the places where +// they have to be enforced. + +#![feature(nll)] + +struct Foo<'a>(&'a ()); +trait Bar { + type Assoc; + fn get(self) -> Self::Assoc; +} + +impl<'a> Bar for Foo<'a> { + type Assoc = &'a u32; + fn get(self) -> Self::Assoc { + let local = 42; + &local //~ ERROR `local` does not live long enough + } +} + +fn main() { + let f = Foo(&()).get(); + println!("{}", f); +} diff --git a/src/test/ui/nll/issue-47470.stderr b/src/test/ui/nll/issue-47470.stderr new file mode 100644 index 000000000000..1356461a6e41 --- /dev/null +++ b/src/test/ui/nll/issue-47470.stderr @@ -0,0 +1,17 @@ +error[E0597]: `local` does not live long enough + --> $DIR/issue-47470.rs:27:9 + | +LL | &local //~ ERROR `local` does not live long enough + | ^^^^^^ borrowed value does not live long enough +LL | } + | - borrowed value only lives until here + | +note: borrowed value must be valid for the lifetime 'a as defined on the impl at 23:1... + --> $DIR/issue-47470.rs:23:1 + | +LL | impl<'a> Bar for Foo<'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0597" From 03c5428be37eedd09f1f3b627c03c3de1beb0674 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 7 Mar 2018 13:34:48 -0500 Subject: [PATCH 155/830] short-circuit `dropck_outlives` for simple cases --- src/librustc/traits/query/dropck_outlives.rs | 74 +++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index cfcd951d4906..0fe4daa36ed4 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -38,11 +38,16 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { pub fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec>> { debug!( "dropck_outlives(ty={:?}, param_env={:?})", - ty, - self.param_env, + ty, self.param_env, ); + // Quick check: there are a number of cases that we know do not require + // any destructor. let tcx = self.infcx.tcx; + if trivial_dropck_outlives(tcx, ty) { + return InferOk { value: vec![], obligations: vec![] }; + } + let gcx = tcx.global_tcx(); let (c_ty, orig_values) = self.infcx.canonicalize_query(&self.param_env.and(ty)); let span = self.cause.span; @@ -192,3 +197,68 @@ impl_stable_hash_for!(struct DtorckConstraint<'tcx> { dtorck_types, overflows }); + +/// This returns true if the type `ty` is "trivial" for +/// dropck-outlives -- that is, if it doesn't require any types to +/// outlive. This is similar but not *quite* the same as the +/// `needs_drop` test in the compiler already -- that is, for every +/// type T for which this function return true, needs-drop would +/// return false. But the reverse does not hold: in particular, +/// `needs_drop` returns false for `PhantomData`, but it is not +/// trivial for dropck-outlives. +/// +/// Note also that `needs_drop` requires a "global" type (i.e., one +/// with erased regions), but this funtcion does not. +fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>) -> bool { + match ty.sty { + // None of these types have a destructor and hence they do not + // require anything in particular to outlive the dtor's + // execution. + ty::TyInfer(ty::FreshIntTy(_)) + | ty::TyInfer(ty::FreshFloatTy(_)) + | ty::TyBool + | ty::TyInt(_) + | ty::TyUint(_) + | ty::TyFloat(_) + | ty::TyNever + | ty::TyFnDef(..) + | ty::TyFnPtr(_) + | ty::TyChar + | ty::TyGeneratorWitness(..) + | ty::TyRawPtr(_) + | ty::TyRef(..) + | ty::TyStr + | ty::TyForeign(..) + | ty::TyError => true, + + // [T; N] and [T] have same properties as T. + ty::TyArray(ty, _) | ty::TySlice(ty) => trivial_dropck_outlives(tcx, ty), + + // (T1..Tn) and closures have same properties as T1..Tn -- + // check if *any* of those are trivial. + ty::TyTuple(ref tys, _) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)), + ty::TyClosure(def_id, ref substs) => substs + .upvar_tys(def_id, tcx) + .all(|t| trivial_dropck_outlives(tcx, t)), + + ty::TyAdt(def, _) => { + if def.is_union() { + // Unions never run have a dtor. + true + } else { + // Other types might. Moreover, PhantomData doesn't + // have a dtor, but it is considered to own its + // content, so it is non-trivial. + false + } + } + + // The following *might* require a destructor: it would deeper inspection to tell. + ty::TyDynamic(..) + | ty::TyProjection(..) + | ty::TyParam(_) + | ty::TyAnon(..) + | ty::TyInfer(_) + | ty::TyGenerator(..) => false, + } +} From 0d17f95465ae3f0c865153fc902eae55ea94e2a9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 7 Mar 2018 14:08:21 -0500 Subject: [PATCH 156/830] short-circuit work when instantiating query responses Also, perform substitution in smaller parts. --- src/librustc/infer/canonical.rs | 108 +++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index c1c7337860e3..83194b5e504e 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -29,6 +29,7 @@ use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin}; use rustc_data_structures::indexed_vec::Idx; use std::fmt::Debug; +use std::ops::Index; use syntax::codemap::Span; use traits::{Obligation, ObligationCause, PredicateObligation}; use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags}; @@ -395,28 +396,27 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { .collect(), }; - // Apply the result substitution to the query. - let QueryResult { - var_values: query_values, - region_constraints: query_region_constraints, - certainty: _, - value: user_result, - } = query_result.substitute(self.tcx, result_subst); - // Unify the original values for the canonical variables in // the input with the value found in the query // post-substitution. Often, but not always, this is a no-op, // because we already found the mapping in the first step. + let substituted_values = |index: CanonicalVar| -> Kind<'tcx> { + query_result.substitute_projected(self.tcx, result_subst, |v| &v.var_values[index]) + }; let mut obligations = - self.unify_canonical_vars(cause, param_env, original_values, &query_values)? + self.unify_canonical_vars(cause, param_env, original_values, substituted_values)? .into_obligations(); obligations.extend(self.query_region_constraints_into_obligations( cause, param_env, - query_region_constraints, + &query_result.value.region_constraints, + result_subst, )); + let user_result: R = + query_result.substitute_projected(self.tcx, result_subst, |q_r| &q_r.value); + Ok(InferOk { value: user_result, obligations, @@ -426,17 +426,20 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// Converts the region constraints resulting from a query into an /// iterator of obligations. fn query_region_constraints_into_obligations<'a>( - &self, + &'a self, cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - query_region_constraints: QueryRegionConstraints<'tcx>, + unsubstituted_region_constraints: &'a QueryRegionConstraints<'tcx>, + result_subst: &'a CanonicalVarValues<'tcx>, ) -> impl Iterator> + 'a { let QueryRegionConstraints { region_outlives, ty_outlives, - } = query_region_constraints; + } = unsubstituted_region_constraints; - let region_obligations = region_outlives.into_iter().map(move |(r1, r2)| { + let region_obligations = region_outlives.iter().map(move |(r1, r2)| { + let r1 = substitute_value(self.tcx, result_subst, r1); + let r2 = substitute_value(self.tcx, result_subst, r2); Obligation::new( cause.clone(), param_env, @@ -444,7 +447,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { ) }); - let ty_obligations = ty_outlives.into_iter().map(move |(t1, r2)| { + let ty_obligations = ty_outlives.iter().map(move |(t1, r2)| { + let t1 = substitute_value(self.tcx, result_subst, t1); + let r2 = substitute_value(self.tcx, result_subst, r2); Obligation::new( cause.clone(), param_env, @@ -456,17 +461,19 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { } /// Given two sets of values for the same set of canonical variables, unify them. - pub fn unify_canonical_vars( + /// The second set is produced lazilly by supplying indices from the first set. + fn unify_canonical_vars( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, variables1: &CanonicalVarValues<'tcx>, - variables2: &CanonicalVarValues<'tcx>, + variables2: impl Fn(CanonicalVar) -> Kind<'tcx>, ) -> InferResult<'tcx, ()> { - assert_eq!(variables1.var_values.len(), variables2.var_values.len()); self.commit_if_ok(|_| { let mut obligations = vec![]; - for (value1, value2) in variables1.var_values.iter().zip(&variables2.var_values) { + for (index, value1) in variables1.var_values.iter_enumerated() { + let value2 = variables2(index); + match (value1.unpack(), value2.unpack()) { (UnpackedKind::Type(v1), UnpackedKind::Type(v2)) => { obligations @@ -724,7 +731,9 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { value: out_value, }, ); - let values = CanonicalVarValues { var_values: IndexVec::default() }; + let values = CanonicalVarValues { + var_values: IndexVec::default(), + }; return (canon_value, values); } @@ -810,13 +819,50 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> { impl<'tcx, V> Canonical<'tcx, V> { /// Instantiate the wrapped value, replacing each canonical value /// with the value given in `var_values`. - pub fn substitute(&self, tcx: TyCtxt<'_, '_, 'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V + fn substitute(&self, tcx: TyCtxt<'_, '_, 'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where V: TypeFoldable<'tcx>, + { + self.substitute_projected(tcx, var_values, |value| value) + } + + /// Invoke `projection_fn` with `self.value` to get a value V that + /// is expressed in terms of the same canonical variables bound in + /// `self`. Apply the substitution `var_values` to this value V, + /// replacing each of the canonical variables. + fn substitute_projected( + &self, + tcx: TyCtxt<'_, '_, 'tcx>, + var_values: &CanonicalVarValues<'tcx>, + projection_fn: impl FnOnce(&V) -> &T, + ) -> T + where + T: TypeFoldable<'tcx>, { assert_eq!(self.variables.len(), var_values.var_values.len()); - self.value - .fold_with(&mut CanonicalVarValuesSubst { tcx, var_values }) + let value = projection_fn(&self.value); + substitute_value(tcx, var_values, value) + } +} + +/// Substitute the values from `var_values` into `value`. `var_values` +/// must be values for the set of cnaonical variables that appear in +/// `value`. +fn substitute_value<'a, 'tcx, T>( + tcx: TyCtxt<'_, '_, 'tcx>, + var_values: &CanonicalVarValues<'tcx>, + value: &'a T, +) -> T +where + T: TypeFoldable<'tcx>, +{ + if var_values.var_values.is_empty() { + debug_assert!(!value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS)); + value.clone() + } else if !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) { + value.clone() + } else { + value.fold_with(&mut CanonicalVarValuesSubst { tcx, var_values }) } } @@ -838,7 +884,13 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g r => bug!("{:?} is a type but value is {:?}", c, r), } } - _ => t.super_fold_with(self), + _ => { + if !t.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) { + t + } else { + t.super_fold_with(self) + } + } } } @@ -926,3 +978,11 @@ BraceStructLiftImpl! { var_values, region_constraints, certainty, value } where R: Lift<'tcx> } + +impl<'tcx> Index for CanonicalVarValues<'tcx> { + type Output = Kind<'tcx>; + + fn index(&self, value: CanonicalVar) -> &Kind<'tcx> { + &self.var_values[value] + } +} From 6288faa3a31844a38b703b2a20a7f3cb9e15ed31 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Mar 2018 12:53:17 -0500 Subject: [PATCH 157/830] `trans_apply_param_substs` => `subst_and_normalize_erasing_regions` Consolidate `trans_apply_param_substs` and `trans_apply_param_substs_env`. Also remove `trans_impl_self_ty` --- src/librustc/traits/trans/mod.rs | 32 ++++--------- src/librustc/ty/instance.rs | 12 ++++- src/librustc_mir/interpret/eval_context.rs | 12 ++++- src/librustc_mir/interpret/terminator/mod.rs | 6 ++- src/librustc_mir/monomorphize/collector.rs | 47 ++++++++++++++----- src/librustc_mir/monomorphize/partitioning.rs | 6 ++- src/librustc_mir/transform/inline.rs | 34 +++----------- src/librustc_trans/debuginfo/mod.rs | 6 ++- src/librustc_trans/mir/mod.rs | 6 ++- 9 files changed, 91 insertions(+), 70 deletions(-) diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs index 86f9d168ad30..cc8b74e0ee23 100644 --- a/src/librustc/traits/trans/mod.rs +++ b/src/librustc/traits/trans/mod.rs @@ -16,7 +16,6 @@ use dep_graph::{DepKind, DepTrackingMapConfig}; use std::marker::PhantomData; use syntax_pos::DUMMY_SP; -use hir::def_id::DefId; use infer::InferCtxt; use syntax_pos::Span; use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, Vtable}; @@ -88,30 +87,23 @@ pub fn trans_fulfill_obligation<'a, 'tcx>(ty: TyCtxt<'a, 'tcx, 'tcx>, } impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { - /// Monomorphizes a type from the AST by first applying the in-scope - /// substitutions and then normalizing any associated types. - pub fn trans_apply_param_substs(self, - param_substs: &Substs<'tcx>, - value: &T) - -> T - where T: TypeFoldable<'tcx> - { - debug!("apply_param_substs(param_substs={:?}, value={:?})", param_substs, value); - let substituted = value.subst(self, param_substs); - self.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted) - } - - pub fn trans_apply_param_substs_env( + /// Monomorphizes a type from the AST by first applying the + /// in-scope substitutions and then normalizing any associated + /// types. + pub fn subst_and_normalize_erasing_regions( self, param_substs: &Substs<'tcx>, param_env: ty::ParamEnv<'tcx>, - value: &T, + value: &T ) -> T where T: TypeFoldable<'tcx>, { debug!( - "apply_param_substs_env(param_substs={:?}, value={:?}, param_env={:?})", + "subst_and_normalize_erasing_regions(\ + param_substs={:?}, \ + value={:?}, \ + param_env={:?})", param_substs, value, param_env, @@ -119,12 +111,6 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { let substituted = value.subst(self, param_substs); self.normalize_erasing_regions(param_env, substituted) } - - pub fn trans_impl_self_ty(&self, def_id: DefId, substs: &'tcx Substs<'tcx>) - -> Ty<'tcx> - { - self.trans_apply_param_substs(substs, &self.type_of(def_id)) - } } // Implement DepTrackingMapConfig for `trait_cache` diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 180fb9cabd3f..76f7a0b59a2a 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -51,7 +51,11 @@ impl<'a, 'tcx> Instance<'tcx> { -> Ty<'tcx> { let ty = tcx.type_of(self.def.def_id()); - tcx.trans_apply_param_substs(self.substs, &ty) + tcx.subst_and_normalize_erasing_regions( + self.substs, + ty::ParamEnv::reveal_all(), + &ty, + ) } } @@ -184,7 +188,11 @@ impl<'a, 'b, 'tcx> Instance<'tcx> { resolve_associated_item(tcx, &item, param_env, trait_def_id, substs) } else { let ty = tcx.type_of(def_id); - let item_type = tcx.trans_apply_param_substs_env(substs, param_env, &ty); + let item_type = tcx.subst_and_normalize_erasing_regions( + substs, + param_env, + &ty, + ); let def = match item_type.sty { ty::TyFnDef(..) if { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index abe45267a1f9..c236ce2abc5f 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -249,7 +249,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M trace!("resolve: {:?}, {:#?}", def_id, substs); trace!("substs: {:#?}", self.substs()); trace!("param_env: {:#?}", self.param_env); - let substs = self.tcx.trans_apply_param_substs_env(self.substs(), self.param_env, &substs); + let substs = self.tcx.subst_and_normalize_erasing_regions( + self.substs(), + self.param_env, + &substs, + ); ty::Instance::resolve( *self.tcx, self.param_env, @@ -722,7 +726,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M ClosureFnPointer => { match self.eval_operand(operand)?.ty.sty { ty::TyClosure(def_id, substs) => { - let substs = self.tcx.trans_apply_param_substs(self.substs(), &substs); + let substs = self.tcx.subst_and_normalize_erasing_regions( + self.substs(), + ty::ParamEnv::reveal_all(), + &substs, + ); let instance = ty::Instance::resolve_closure( *self.tcx, def_id, diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index a729e3a5dda8..be34b8705eb1 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -122,7 +122,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { // FIXME(CTFE): forbid drop in const eval let place = self.eval_place(location)?; let ty = self.place_ty(location); - let ty = self.tcx.trans_apply_param_substs(self.substs(), &ty); + let ty = self.tcx.subst_and_normalize_erasing_regions( + self.substs(), + ty::ParamEnv::reveal_all(), + &ty, + ); trace!("TerminatorKind::drop: {:?}, type {}", location, ty); let instance = ::monomorphize::resolve_drop_in_place(*self.tcx, ty); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 561500a3f3c5..7fd2ea265de8 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -523,11 +523,17 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { // have to instantiate all methods of the trait being cast to, so we // can build the appropriate vtable. mir::Rvalue::Cast(mir::CastKind::Unsize, ref operand, target_ty) => { - let target_ty = self.tcx.trans_apply_param_substs(self.param_substs, - &target_ty); + let target_ty = self.tcx.subst_and_normalize_erasing_regions( + self.param_substs, + ty::ParamEnv::reveal_all(), + &target_ty, + ); let source_ty = operand.ty(self.mir, self.tcx); - let source_ty = self.tcx.trans_apply_param_substs(self.param_substs, - &source_ty); + let source_ty = self.tcx.subst_and_normalize_erasing_regions( + self.param_substs, + ty::ParamEnv::reveal_all(), + &source_ty, + ); let (source_ty, target_ty) = find_vtable_types_for_unsizing(self.tcx, source_ty, target_ty); @@ -543,14 +549,20 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { } mir::Rvalue::Cast(mir::CastKind::ReifyFnPointer, ref operand, _) => { let fn_ty = operand.ty(self.mir, self.tcx); - let fn_ty = self.tcx.trans_apply_param_substs(self.param_substs, - &fn_ty); + let fn_ty = self.tcx.subst_and_normalize_erasing_regions( + self.param_substs, + ty::ParamEnv::reveal_all(), + &fn_ty, + ); visit_fn_use(self.tcx, fn_ty, false, &mut self.output); } mir::Rvalue::Cast(mir::CastKind::ClosureFnPointer, ref operand, _) => { let source_ty = operand.ty(self.mir, self.tcx); - let source_ty = self.tcx.trans_apply_param_substs(self.param_substs, - &source_ty); + let source_ty = self.tcx.subst_and_normalize_erasing_regions( + self.param_substs, + ty::ParamEnv::reveal_all(), + &source_ty, + ); match source_ty.sty { ty::TyClosure(def_id, substs) => { let instance = monomorphize::resolve_closure( @@ -595,14 +607,22 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match *kind { mir::TerminatorKind::Call { ref func, .. } => { let callee_ty = func.ty(self.mir, tcx); - let callee_ty = tcx.trans_apply_param_substs(self.param_substs, &callee_ty); + let callee_ty = tcx.subst_and_normalize_erasing_regions( + self.param_substs, + ty::ParamEnv::reveal_all(), + &callee_ty, + ); visit_fn_use(self.tcx, callee_ty, true, &mut self.output); } mir::TerminatorKind::Drop { ref location, .. } | mir::TerminatorKind::DropAndReplace { ref location, .. } => { let ty = location.ty(self.mir, self.tcx) .to_ty(self.tcx); - let ty = tcx.trans_apply_param_substs(self.param_substs, &ty); + let ty = tcx.subst_and_normalize_erasing_regions( + self.param_substs, + ty::ParamEnv::reveal_all(), + &ty, + ); visit_drop_use(self.tcx, ty, true, self.output); } mir::TerminatorKind::Goto { .. } | @@ -1155,8 +1175,11 @@ fn collect_const<'a, 'tcx>( let val = match constant.val { ConstVal::Unevaluated(def_id, substs) => { let param_env = ty::ParamEnv::reveal_all(); - let substs = tcx.trans_apply_param_substs(param_substs, - &substs); + let substs = tcx.subst_and_normalize_erasing_regions( + param_substs, + param_env, + &substs, + ); let instance = ty::Instance::resolve(tcx, param_env, def_id, diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index d65c1e03298a..3789342b3891 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -645,7 +645,11 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(impl_def_id) = tcx.impl_of_method(def_id) { // This is a method within an inherent impl, find out what the // self-type is: - let impl_self_ty = tcx.trans_impl_self_ty(impl_def_id, instance.substs); + let impl_self_ty = tcx.subst_and_normalize_erasing_regions( + instance.substs, + ty::ParamEnv::reveal_all(), + &tcx.type_of(impl_def_id), + ); if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) { return Some(def_id); } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index b8a0e0f89073..6380d2a5c15f 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::*; use rustc::mir::visit::*; -use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Instance, Ty, TyCtxt}; use rustc::ty::subst::{Subst,Substs}; use std::collections::VecDeque; @@ -129,8 +129,12 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { let callee_mir = match ty::queries::optimized_mir::try_get(self.tcx, callsite.location.span, callsite.callee) { - Ok(ref callee_mir) if self.should_inline(callsite, callee_mir) => { - subst_and_normalize(callee_mir, self.tcx, &callsite.substs, param_env) + Ok(callee_mir) if self.should_inline(callsite, callee_mir) => { + self.tcx.subst_and_normalize_erasing_regions( + &callsite.substs, + param_env, + callee_mir, + ) } Ok(_) => continue, @@ -664,30 +668,6 @@ fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes()) } -fn subst_and_normalize<'a, 'tcx: 'a>( - mir: &Mir<'tcx>, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - substs: &'tcx ty::subst::Substs<'tcx>, - param_env: ty::ParamEnv<'tcx>, -) -> Mir<'tcx> { - struct Folder<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - param_env: ty::ParamEnv<'tcx>, - substs: &'tcx ty::subst::Substs<'tcx>, - } - impl<'a, 'tcx: 'a> ty::fold::TypeFolder<'tcx, 'tcx> for Folder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> { - self.tcx - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - self.tcx.trans_apply_param_substs_env(&self.substs, self.param_env, &t) - } - } - let mut f = Folder { tcx, param_env, substs }; - mir.fold_with(&mut f) -} - /** * Integrator. * diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 683e1835968f..c13b91eb3b6b 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -429,7 +429,11 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| { // If the method does *not* belong to a trait, proceed if cx.tcx.trait_id_of_impl(impl_def_id).is_none() { - let impl_self_ty = cx.tcx.trans_impl_self_ty(impl_def_id, instance.substs); + let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions( + instance.substs, + ty::ParamEnv::reveal_all(), + &cx.tcx.type_of(impl_def_id), + ); // Only "class" methods are generally understood by LLVM, // so avoid methods on other types (e.g. `<*mut T>::null`). diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index a92a59edfde1..0533b04a0c1d 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -109,7 +109,11 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { pub fn monomorphize(&self, value: &T) -> T where T: TypeFoldable<'tcx> { - self.cx.tcx.trans_apply_param_substs(self.param_substs, value) + self.cx.tcx.subst_and_normalize_erasing_regions( + self.param_substs, + ty::ParamEnv::reveal_all(), + value, + ) } pub fn set_debug_loc(&mut self, bx: &Builder, source_info: mir::SourceInfo) { From fc04c41a4075cef1cc9c84911fbdc17b5b9265b7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 9 Mar 2018 16:44:20 -0500 Subject: [PATCH 158/830] add a debug assertion that only outlives-oblig. result from norm. --- .../normalize_erasing_regions.rs | 39 +++++++++++++++---- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/src/librustc_traits/normalize_erasing_regions.rs index 805bf1030b3f..14f8694dbf72 100644 --- a/src/librustc_traits/normalize_erasing_regions.rs +++ b/src/librustc_traits/normalize_erasing_regions.rs @@ -10,7 +10,7 @@ use rustc::traits::{Normalized, ObligationCause}; use rustc::traits::query::NoSolution; -use rustc::ty::{ParamEnvAnd, Ty, TyCtxt}; +use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc::util::common::CellUsizeExt; crate fn normalize_ty_after_erasing_regions<'tcx>( @@ -18,15 +18,27 @@ crate fn normalize_ty_after_erasing_regions<'tcx>( goal: ParamEnvAnd<'tcx, Ty<'tcx>>, ) -> Ty<'tcx> { let ParamEnvAnd { param_env, value } = goal; - tcx.sess.perf_stats.normalize_ty_after_erasing_regions.increment(); + tcx.sess + .perf_stats + .normalize_ty_after_erasing_regions + .increment(); tcx.infer_ctxt().enter(|infcx| { let cause = ObligationCause::dummy(); match infcx.at(&cause, param_env).normalize(&value) { - Ok(Normalized { value: normalized_value, obligations: _ }) => { - // ^^^^^^^^^^^ - // We don't care about the `obligations`, - // they are always only region relations, - // and we are about to erase those anyway. + Ok(Normalized { + value: normalized_value, + obligations: normalized_obligations, + }) => { + // We don't care about the `obligations`; they are + // always only region relations, and we are about to + // erase those anyway: + debug_assert_eq!( + normalized_obligations + .iter() + .find(|p| not_outlives_predicate(&p.predicate)), + None, + ); + let normalized_value = infcx.resolve_type_vars_if_possible(&normalized_value); let normalized_value = infcx.tcx.erase_regions(&normalized_value); tcx.lift_to_global(&normalized_value).unwrap() @@ -35,3 +47,16 @@ crate fn normalize_ty_after_erasing_regions<'tcx>( } }) } + +fn not_outlives_predicate(p: &ty::Predicate<'_>) -> bool { + match p { + ty::Predicate::RegionOutlives(..) | ty::Predicate::TypeOutlives(..) => false, + ty::Predicate::Trait(..) + | ty::Predicate::Projection(..) + | ty::Predicate::WellFormed(..) + | ty::Predicate::ObjectSafe(..) + | ty::Predicate::ClosureKind(..) + | ty::Predicate::Subtype(..) + | ty::Predicate::ConstEvaluatable(..) => true, + } +} From d32673858698b8e733c9b42d82ad01f16c487eed Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 11 Mar 2018 07:08:52 -0400 Subject: [PATCH 159/830] replace inline docs with references to rustc-guide --- src/librustc/infer/canonical.rs | 75 ++++++++------------------------- 1 file changed, 18 insertions(+), 57 deletions(-) diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 83194b5e504e..73fb2a92de6e 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -25,6 +25,11 @@ //! M, into constraints in our source context. This process of //! translating the results back is done by the //! `instantiate_query_result` method. +//! +//! For a more detailed look at what is happening here, check +//! out the [chapter in the rustc guide][c]. +//! +//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html use infer::{InferCtxt, InferOk, InferResult, RegionVariableOrigin, TypeVariableOrigin}; use rustc_data_structures::indexed_vec::Idx; @@ -270,64 +275,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// have been ambiguous; you should check the certainty level of /// the query before applying this function.) /// - /// It's easiest to explain what is happening here by - /// example. Imagine we start out with the query `?A: Foo<'static, - /// ?B>`. We would canonicalize that by introducing two variables: + /// To get a good understanding of what is happening here, check + /// out the [chapter in the rustc guide][c]. /// - /// ?0: Foo<'?1, ?2> - /// - /// (Note that all regions get replaced with variables always, - /// even "known" regions like `'static`.) After canonicalization, - /// we also get back an array with the "original values" for each - /// canonicalized variable: - /// - /// [?A, 'static, ?B] - /// - /// Now we do the query and get back some result R. As part of that - /// result, we'll have an array of values for the canonical inputs. - /// For example, the canonical result might be: - /// - /// ``` - /// for<2> { - /// values = [ Vec, '1, ?0 ] - /// ^^ ^^ ^^ these are variables in the result! - /// ... - /// } - /// ``` - /// - /// Note that this result is itself canonical and may include some - /// variables (in this case, `?0`). - /// - /// What we want to do conceptually is to (a) instantiate each of the - /// canonical variables in the result with a fresh inference variable - /// and then (b) unify the values in the result with the original values. - /// Doing step (a) would yield a result of - /// - /// ``` - /// { - /// values = [ Vec, '?X, ?C ] - /// ^^ ^^^ fresh inference variables in `self` - /// .. - /// } - /// ``` - /// - /// Step (b) would then unify: - /// - /// ``` - /// ?A with Vec - /// 'static with '?X - /// ?B with ?C - /// ``` - /// - /// But what we actually do is a mildly optimized variant of - /// that. Rather than eagerly instantiating all of the canonical - /// values in the result with variables, we instead walk the - /// vector of values, looking for cases where the value is just a - /// canonical variable. In our example, `values[2]` is `?C`, so - /// that we means we can deduce that `?C := ?B and `'?X := - /// 'static`. This gives us a partial set of values. Anything for - /// which we do not find a value, we create an inference variable - /// for. **Then** we unify. + /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#processing-the-canonicalized-query-result pub fn instantiate_query_result( &self, cause: &ObligationCause<'tcx>, @@ -509,6 +460,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// T: Trait<'?0> /// /// with a mapping M that maps `'?0` to `'static`. + /// + /// To get a good understanding of what is happening here, check + /// out the [chapter in the rustc guide][c]. + /// + /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query pub fn canonicalize_query(&self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'tcx>) where V: Canonicalize<'gcx, 'tcx>, @@ -541,6 +497,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// things) includes a mapping to `'?0 := 'static`. When /// canonicalizing this query result R, we would leave this /// reference to `'static` alone. + /// + /// To get a good understanding of what is happening here, check + /// out the [chapter in the rustc guide][c]. + /// + /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query-result pub fn canonicalize_response( &self, value: &V, From 29dc902beb037c4cdcad3569d3fc7b72424e8779 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 11 Mar 2018 07:09:06 -0400 Subject: [PATCH 160/830] remove dead code --- src/librustc/infer/canonical.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 73fb2a92de6e..21d60bb8b36f 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -518,17 +518,6 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { } } -impl<'cx, 'gcx> TyCtxt<'cx, 'gcx, 'gcx> { - /// Canonicalize a value that doesn't have any inference variables - /// or other things (and we know it). - pub fn canonicalize_global(self, value: &V) -> (V::Canonicalized, CanonicalVarValues<'gcx>) - where - V: Canonicalize<'gcx, 'gcx>, - { - Canonicalizer::canonicalize(value, None, self, CanonicalizeAllFreeRegions(false)) - } -} - /// If this flag is true, then all free regions will be replaced with /// a canonical var. This is used to make queries as generic as /// possible. For example, the query `F: Foo<'static>` would be From 17c4103f3f0cc8bd4dea9de5e7ef155daf363cfe Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 11 Mar 2018 07:13:14 -0400 Subject: [PATCH 161/830] add "text" sections for things that seem likely to be a problem --- src/librustc/infer/canonical.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 21d60bb8b36f..9519baa3ff7b 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -457,7 +457,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// *also* replace all free regions whatsoever. So for example a /// query like `T: Trait<'static>` would be canonicalized to /// - /// T: Trait<'?0> + /// ```text + /// T: Trait<'?0> + /// ``` /// /// with a mapping M that maps `'?0` to `'static`. /// @@ -486,7 +488,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { /// there was an input query `T: Trait<'static>`, it would have /// been canonicalized to /// - /// T: Trait<'?0> + /// ```text + /// T: Trait<'?0> + /// ``` /// /// with a mapping M that maps `'?0` to `'static`. But if we found that there /// exists only one possible impl of `Trait`, and it looks like From 1999a3fb4154961329ecfff7d70a6303471b996a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 12 Mar 2018 13:35:46 -0700 Subject: [PATCH 162/830] rustbuild: Tweak CFLAGS to various libstd pieces * Pass `opt_level(2)` when calculating CFLAGS to get the right flags on iOS * Unconditionally pass `-O2` when compiling libbacktrace This should... Close #48903 Close #48906 --- src/bootstrap/cc_detect.rs | 4 ++-- src/libstd/build.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index 9e1b1f7db2f9..8f393a4c5737 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -77,7 +77,7 @@ pub fn find(build: &mut Build) { .collect::>(); for target in targets.into_iter() { let mut cfg = cc::Build::new(); - cfg.cargo_metadata(false).opt_level(0).warnings(false).debug(false) + cfg.cargo_metadata(false).opt_level(2).warnings(false).debug(false) .target(&target).host(&build.build); if target.contains("msvc") { cfg.static_crt(true); @@ -109,7 +109,7 @@ pub fn find(build: &mut Build) { let hosts = build.hosts.iter().cloned().chain(iter::once(build.build)).collect::>(); for host in hosts.into_iter() { let mut cfg = cc::Build::new(); - cfg.cargo_metadata(false).opt_level(0).warnings(false).debug(false).cpp(true) + cfg.cargo_metadata(false).opt_level(2).warnings(false).debug(false).cpp(true) .target(&host).host(&build.build); let config = build.config.target_config.get(&host); if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { diff --git a/src/libstd/build.rs b/src/libstd/build.rs index a41c155f3fb5..b3c71f4d81b2 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -98,7 +98,7 @@ fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> { .arg("--disable-host-shared") .arg(format!("--host={}", build_helper::gnu_target(target))) .arg(format!("--build={}", build_helper::gnu_target(host))) - .env("CFLAGS", env::var("CFLAGS").unwrap_or_default() + " -fvisibility=hidden")); + .env("CFLAGS", env::var("CFLAGS").unwrap_or_default() + " -fvisibility=hidden -O2")); run(Command::new(build_helper::make(host)) .current_dir(&native.out_dir) From 0e0f74bcf93341ff3b1d8b59f3639416a159a140 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 9 Mar 2018 07:25:54 -0800 Subject: [PATCH 163/830] rustc: Embed LLVM bitcode by default on iOS This commit updates rustc to embed bitcode in each object file generated by default when compiling for iOS. This was determined in #35968 as a step towards better compatibility with the iOS toolchain, so let's give it a spin and see how it turns out! Note that this also updates the `cc` dependency which should propagate this change of embedding bitcode for C dependencies as well. --- src/librustc/session/config.rs | 2 + src/librustc_back/target/mod.rs | 6 +++ src/librustc_trans/back/write.rs | 78 +++++++++++++++++++++++++++++++- src/libstd/build.rs | 3 +- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1c5cfa87ef46..3e894abd17c9 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1288,6 +1288,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "run `dsymutil` and delete intermediate object files"), ui_testing: bool = (false, parse_bool, [UNTRACKED], "format compiler diagnostics in a way that's better suitable for UI testing"), + embed_bitcode: bool = (false, parse_bool, [TRACKED], + "embed LLVM bitcode in object files"), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 250d85d45203..f53eeb86a9c5 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -473,6 +473,9 @@ pub struct TargetOptions { /// The default visibility for symbols in this target should be "hidden" /// rather than "default" pub default_hidden_visibility: bool, + + /// Whether or not bitcode is embedded in object files + pub embed_bitcode: bool, } impl Default for TargetOptions { @@ -544,6 +547,7 @@ impl Default for TargetOptions { i128_lowering: false, codegen_backend: "llvm".to_string(), default_hidden_visibility: false, + embed_bitcode: false, } } } @@ -792,6 +796,7 @@ impl Target { key!(no_builtins, bool); key!(codegen_backend); key!(default_hidden_visibility, bool); + key!(embed_bitcode, bool); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -990,6 +995,7 @@ impl ToJson for Target { target_option_val!(no_builtins); target_option_val!(codegen_backend); target_option_val!(default_hidden_visibility); + target_option_val!(embed_bitcode); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 7651a8e748e3..3e7422557e9b 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -42,6 +42,7 @@ use syntax_pos::MultiSpan; use syntax_pos::symbol::Symbol; use type_::Type; use context::{is_pie_binary, get_reloc_model}; +use common::{C_bytes_in_context, val_ty}; use jobserver::{Client, Acquired}; use rustc_demangle; @@ -262,6 +263,8 @@ pub struct ModuleConfig { // emscripten's ecc compiler, when used as the linker. obj_is_bitcode: bool, no_integrated_as: bool, + embed_bitcode: bool, + embed_bitcode_marker: bool, } impl ModuleConfig { @@ -279,6 +282,8 @@ impl ModuleConfig { emit_asm: false, emit_obj: false, obj_is_bitcode: false, + embed_bitcode: false, + embed_bitcode_marker: false, no_integrated_as: false, no_verify: false, @@ -299,6 +304,17 @@ impl ModuleConfig { self.time_passes = sess.time_passes(); self.inline_threshold = sess.opts.cg.inline_threshold; self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode; + let embed_bitcode = sess.target.target.options.embed_bitcode || + sess.opts.debugging_opts.embed_bitcode; + if embed_bitcode { + match sess.opts.optimize { + config::OptLevel::No | + config::OptLevel::Less => { + self.embed_bitcode_marker = embed_bitcode; + } + _ => self.embed_bitcode = embed_bitcode, + } + } // Copy what clang does by turning on loop vectorization at O2 and // slp vectorization at O3. Otherwise configure other optimization aspects @@ -662,7 +678,7 @@ unsafe fn codegen(cgcx: &CodegenContext, let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name); - if write_bc || config.emit_bc_compressed { + if write_bc || config.emit_bc_compressed || config.embed_bitcode { let thin; let old; let data = if llvm::LLVMRustThinLTOAvailable() { @@ -681,6 +697,11 @@ unsafe fn codegen(cgcx: &CodegenContext, timeline.record("write-bc"); } + if config.embed_bitcode { + embed_bitcode(cgcx, llcx, llmod, Some(data)); + timeline.record("embed-bc"); + } + if config.emit_bc_compressed { let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION); let data = bytecode::encode(&mtrans.llmod_id, data); @@ -689,6 +710,8 @@ unsafe fn codegen(cgcx: &CodegenContext, } timeline.record("compress-bc"); } + } else if config.embed_bitcode_marker { + embed_bitcode(cgcx, llcx, llmod, None); } time_ext(config.time_passes, None, &format!("codegen passes [{}]", module_name.unwrap()), @@ -796,6 +819,59 @@ unsafe fn codegen(cgcx: &CodegenContext, &cgcx.output_filenames)) } +/// Embed the bitcode of an LLVM module in the LLVM module itself. +/// +/// This is done primarily for iOS where it appears to be standard to compile C +/// code at least with `-fembed-bitcode` which creates two sections in the +/// executable: +/// +/// * __LLVM,__bitcode +/// * __LLVM,__cmdline +/// +/// It appears *both* of these sections are necessary to get the linker to +/// recognize what's going on. For us though we just always throw in an empty +/// cmdline section. +/// +/// Furthermore debug/O1 builds don't actually embed bitcode but rather just +/// embed an empty section. +/// +/// Basically all of this is us attempting to follow in the footsteps of clang +/// on iOS. See #35968 for lots more info. +unsafe fn embed_bitcode(cgcx: &CodegenContext, + llcx: ContextRef, + llmod: ModuleRef, + bitcode: Option<&[u8]>) { + let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[])); + let llglobal = llvm::LLVMAddGlobal( + llmod, + val_ty(llconst).to_ref(), + "rustc.embedded.module\0".as_ptr() as *const _, + ); + llvm::LLVMSetInitializer(llglobal, llconst); + let section = if cgcx.opts.target_triple.contains("-ios") { + "__LLVM,__bitcode\0" + } else { + ".llvmbc\0" + }; + llvm::LLVMSetSection(llglobal, section.as_ptr() as *const _); + llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); + + let llconst = C_bytes_in_context(llcx, &[]); + let llglobal = llvm::LLVMAddGlobal( + llmod, + val_ty(llconst).to_ref(), + "rustc.embedded.cmdline\0".as_ptr() as *const _, + ); + llvm::LLVMSetInitializer(llglobal, llconst); + let section = if cgcx.opts.target_triple.contains("-ios") { + "__LLVM,__cmdline\0" + } else { + ".llvmcmd\0" + }; + llvm::LLVMSetSection(llglobal, section.as_ptr() as *const _); + llvm::LLVMRustSetLinkage(llglobal, llvm::Linkage::PrivateLinkage); +} + pub(crate) struct CompiledModules { pub modules: Vec, pub metadata_module: CompiledModule, diff --git a/src/libstd/build.rs b/src/libstd/build.rs index b3c71f4d81b2..6652ff98201a 100644 --- a/src/libstd/build.rs +++ b/src/libstd/build.rs @@ -86,6 +86,7 @@ fn main() { fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> { let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace", ".libs")?; + let cflags = env::var("CFLAGS").unwrap_or_default() + " -fvisibility=hidden -O2"; run(Command::new("sh") .current_dir(&native.out_dir) @@ -98,7 +99,7 @@ fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> { .arg("--disable-host-shared") .arg(format!("--host={}", build_helper::gnu_target(target))) .arg(format!("--build={}", build_helper::gnu_target(host))) - .env("CFLAGS", env::var("CFLAGS").unwrap_or_default() + " -fvisibility=hidden -O2")); + .env("CFLAGS", cflags)); run(Command::new(build_helper::make(host)) .current_dir(&native.out_dir) From 01cc5b3e195bb01088fdd59638f0d8c6d0a78142 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 13 Mar 2018 16:46:55 +0100 Subject: [PATCH 164/830] add intrinsics for portable packed simd vector reductions --- src/librustc_llvm/ffi.rs | 40 ++++ src/librustc_trans/builder.rs | 75 ++++++ src/librustc_trans/intrinsic.rs | 219 +++++++++++++++++- src/librustc_typeck/check/intrinsic.rs | 5 + src/rustllvm/RustWrapper.cpp | 46 ++++ .../simd-intrinsic-generic-reduction.rs | 143 ++++++++++++ 6 files changed, 525 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/simd-intrinsic-generic-reduction.rs diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 0ec5700f5f32..00547017349d 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1201,6 +1201,46 @@ extern "C" { Name: *const c_char) -> ValueRef; + pub fn LLVMRustBuildVectorReduceFAdd(B: BuilderRef, + Acc: ValueRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMul(B: BuilderRef, + Acc: ValueRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceAdd(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMul(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceAnd(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceOr(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceXor(B: BuilderRef, + Src: ValueRef) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMin(B: BuilderRef, + Src: ValueRef, + IsSigned: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceMax(B: BuilderRef, + Src: ValueRef, + IsSigned: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMin(B: BuilderRef, + Src: ValueRef, + IsNaN: bool) + -> ValueRef; + pub fn LLVMRustBuildVectorReduceFMax(B: BuilderRef, + Src: ValueRef, + IsNaN: bool) + -> ValueRef; + pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildPtrDiff(B: BuilderRef, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index d4e05a18e3a5..2c38197d68ec 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -955,6 +955,81 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + pub fn vector_reduce_fadd_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fadd_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_fmul_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmul_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_add(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.add"); + unsafe { + llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) + } + } + pub fn vector_reduce_mul(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.mul"); + unsafe { + llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) + } + } + pub fn vector_reduce_and(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.and"); + unsafe { + llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) + } + } + pub fn vector_reduce_or(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.or"); + unsafe { + llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) + } + } + pub fn vector_reduce_xor(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.xor"); + unsafe { + llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) + } + } + pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmin_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, false); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_fmax_fast(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmax_fast"); + unsafe { + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, false); + llvm::LLVMRustSetHasUnsafeAlgebra(instr); + instr + } + } + pub fn vector_reduce_min(&self, src: ValueRef, is_signed: bool) -> ValueRef { + self.count_insn("vector.reduce.min"); + unsafe { + llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) + } + } + pub fn vector_reduce_max(&self, src: ValueRef, is_signed: bool) -> ValueRef { + self.count_insn("vector.reduce.max"); + unsafe { + llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) + } + } + pub fn extract_value(&self, agg_val: ValueRef, idx: u64) -> ValueRef { self.count_insn("extractvalue"); assert_eq!(idx as c_uint as u64, idx); diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 3f87ce7e0479..011273f02e11 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1018,14 +1018,22 @@ fn generic_simd_intrinsic<'a, 'tcx>( name, $($fmt)*)); } } - macro_rules! require { - ($cond: expr, $($fmt: tt)*) => { - if !$cond { + macro_rules! return_error { + ($($fmt: tt)*) => { + { emit_error!($($fmt)*); return Err(()); } } } + + macro_rules! require { + ($cond: expr, $($fmt: tt)*) => { + if !$cond { + return_error!($($fmt)*); + } + }; + } macro_rules! require_simd { ($ty: expr, $position: expr) => { require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty) @@ -1142,6 +1150,211 @@ fn generic_simd_intrinsic<'a, 'tcx>( return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) } + if name == "simd_reduce_add" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_add(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_add(args[0].immediate())) + }, + ty::TyFloat(f) => { + // undef as accumulator makes the reduction unordered: + let acc = match f.bit_width() { + 32 => C_undef(Type::f32(bx.cx)), + 64 => C_undef(Type::f64(bx.cx)), + v => { + return_error!( + "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", + "simd_reduce_add", in_ty, in_elem, v, ret_ty) + } + }; + Ok(bx.vector_reduce_fadd_fast(acc, args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_add", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_mul" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_mul(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_mul(args[0].immediate())) + }, + ty::TyFloat(f) => { + // undef as accumulator makes the reduction unordered: + let acc = match f.bit_width() { + 32 => C_undef(Type::f32(bx.cx)), + 64 => C_undef(Type::f64(bx.cx)), + v => { + return_error!( + "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", + "simd_reduce_mul", in_ty, in_elem, v, ret_ty) + } + }; + Ok(bx.vector_reduce_fmul_fast(acc, args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_mul", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_min" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_min(args[0].immediate(), true)) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_min(args[0].immediate(), false)) + }, + ty::TyFloat(_f) => { + Ok(bx.vector_reduce_fmin_fast(args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_min", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_max" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_max(args[0].immediate(), true)) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_max(args[0].immediate(), false)) + }, + ty::TyFloat(_f) => { + Ok(bx.vector_reduce_fmax_fast(args[0].immediate())) + } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_max", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_and" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_and(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_and(args[0].immediate())) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_and", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_or" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_or(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_or(args[0].immediate())) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_or", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_xor" { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.vector_reduce_xor(args[0].immediate())) + }, + ty::TyUint(_u) => { + Ok(bx.vector_reduce_xor(args[0].immediate())) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_xor", in_ty, in_elem, ret_ty) + }, + } + } + + if name == "simd_reduce_all" { + //require!(ret_ty == in_elem, + // "expected return type `{}` (element of input `{}`), found `{}`", + // in_elem, in_ty, ret_ty); + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, in_len as u64); + let v = bx.trunc(args[0].immediate(), i1xn); + + let red = match in_elem.sty { + ty::TyInt(_i) => { + bx.vector_reduce_and(v) + }, + ty::TyUint(_u) => { + bx.vector_reduce_and(v) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_and", in_ty, in_elem, ret_ty) + }, + }; + return Ok(bx.zext(red, Type::bool(bx.cx))); + } + + if name == "simd_reduce_any" { + //require!(ret_ty == in_elem, + // "expected return type `{}` (element of input `{}`), found `{}`", + // in_elem, in_ty, ret_ty); + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, in_len as u64); + let v = bx.trunc(args[0].immediate(), i1xn); + + let red = match in_elem.sty { + ty::TyInt(_i) => { + bx.vector_reduce_or(v) + }, + ty::TyUint(_u) => { + bx.vector_reduce_or(v) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + "simd_reduce_and", in_ty, in_elem, ret_ty) + }, + }; + return Ok(bx.zext(red, Type::bool(bx.cx))); + } + + if name == "simd_cast" { require_simd!(ret_ty, "return"); let out_len = ret_ty.simd_size(tcx); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 2e00040d99a7..f2d01c57f298 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -361,6 +361,11 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), + "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), + "simd_reduce_add" | "simd_reduce_mul" | + "simd_reduce_and" | "simd_reduce_or" | "simd_reduce_xor" | + "simd_reduce_min" | "simd_reduce_max" + => (2, vec![param(0)], param(1)), name if name.starts_with("simd_shuffle") => { match name["simd_shuffle".len()..].parse() { Ok(n) => { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 27d5496f5762..e749549201e6 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1395,3 +1395,49 @@ LLVMRustModuleCost(LLVMModuleRef M) { auto f = unwrap(M)->functions(); return std::distance(std::begin(f), std::end(f)); } + +// Vector reductions: +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMul(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc),unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAdd(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateAddReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMul(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateMulReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAnd(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateAndReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceOr(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateOrReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceXor(LLVMBuilderRef B, LLVMValueRef Src) { + return wrap(unwrap(B)->CreateXorReduce(unwrap(Src))); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMin(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) { + return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Src), IsSigned)); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMax(LLVMBuilderRef B, LLVMValueRef Src, bool IsSigned) { + return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Src), IsSigned)); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMin(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { + return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Src), NoNaN)); +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { + return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); +} diff --git a/src/test/run-pass/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd-intrinsic-generic-reduction.rs new file mode 100644 index 000000000000..15b291ae179c --- /dev/null +++ b/src/test/run-pass/simd-intrinsic-generic-reduction.rs @@ -0,0 +1,143 @@ +// Copyright 2015 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. + +// Test that the simd_reduce_{op} intrinsics produce the correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +#[repr(simd)] +#[derive(Copy, Clone)] +struct b8x16( + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8 +); + +extern "platform-intrinsic" { + fn simd_reduce_add(x: T) -> U; + fn simd_reduce_mul(x: T) -> U; + fn simd_reduce_min(x: T) -> U; + fn simd_reduce_max(x: T) -> U; + fn simd_reduce_and(x: T) -> U; + fn simd_reduce_or(x: T) -> U; + fn simd_reduce_xor(x: T) -> U; + fn simd_reduce_all(x: T) -> bool; + fn simd_reduce_any(x: T) -> bool; +} + +fn main() { + unsafe { + let x = i32x4(1, -2, 3, 4); + let r: i32 = simd_reduce_add(x); + assert!(r == 6_i32); + let r: i32 = simd_reduce_mul(x); + assert!(r == -24_i32); + let r: i32 = simd_reduce_min(x); + assert!(r == -21_i32); + let r: i32 = simd_reduce_max(x); + assert!(r == 4_i32); + + let x = i32x4(-1, -1, -1, -1); + let r: i32 = simd_reduce_and(x); + assert!(r == -1_i32); + let r: i32 = simd_reduce_or(x); + assert!(r == -1_i32); + let r: i32 = simd_reduce_xor(x); + assert!(r == 0_i32); + + let x = i32x4(-1, -1, 0, -1); + let r: i32 = simd_reduce_and(x); + assert!(r == 0_i32); + let r: i32 = simd_reduce_or(x); + assert!(r == -1_i32); + let r: i32 = simd_reduce_xor(x); + assert!(r == -1_i32); + } + + unsafe { + let x = u32x4(1, 2, 3, 4); + let r: u32 = simd_reduce_add(x); + assert!(r == 10_u32); + let r: u32 = simd_reduce_mul(x); + assert!(r == 24_u32); + let r: u32 = simd_reduce_min(x); + assert!(r == 1_u32); + let r: u32 = simd_reduce_max(x); + assert!(r == 4_u32); + + let t = u32::max_value(); + let x = u32x4(t, t, t, t); + let r: u32 = simd_reduce_and(x); + assert!(r == t); + let r: u32 = simd_reduce_or(x); + assert!(r == t); + let r: u32 = simd_reduce_xor(x); + assert!(r == 0_u32); + + let x = u32x4(t, t, 0, t); + let r: u32 = simd_reduce_and(x); + assert!(r == 0_u32); + let r: u32 = simd_reduce_or(x); + assert!(r == t); + let r: u32 = simd_reduce_xor(x); + assert!(r == t); + } + + unsafe { + let x = f32x4(1., -2., 3., 4.); + let r: f32 = simd_reduce_add(x); + assert!(r == 6_f32); + let r: f32 = simd_reduce_mul(x); + assert!(r == -24_f32); + let r: f32 = simd_reduce_min(x); + assert!(r == -2_f32); + let r: f32 = simd_reduce_max(x); + assert!(r == 4_f32); + } + + unsafe { + let x = b8x4(!0, !0, !0, !0); + let r: bool = simd_reduce_all(x); + //let r: bool = foobar(x); + assert!(r); + let r: bool = simd_reduce_any(x); + assert!(r); + + let x = b8x4(!0, !0, 0, !0); + let r: bool = simd_reduce_all(x); + assert!(!r); + let r: bool = simd_reduce_any(x); + assert!(r); + + let x = b8x4(0, 0, 0, 0); + let r: bool = simd_reduce_all(x); + assert!(!r); + let r: bool = simd_reduce_any(x); + assert!(!r); + } +} From 21a9770d38483eb95d5045b50547058bc7ff7e65 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Tue, 13 Mar 2018 14:21:51 -0400 Subject: [PATCH 165/830] Adds a test for #48070 Resolves #48070. The bug itself was fixed by #48770, but that PR didn't add a test for it. --- src/test/run-pass/issue-48070.rs | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/test/run-pass/issue-48070.rs diff --git a/src/test/run-pass/issue-48070.rs b/src/test/run-pass/issue-48070.rs new file mode 100644 index 000000000000..c2253aa8b4c2 --- /dev/null +++ b/src/test/run-pass/issue-48070.rs @@ -0,0 +1,34 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// revisions: lxl nll + +#![cfg_attr(nll, feature(nll))] + +struct Foo { + x: u32 +} + +impl Foo { + fn twiddle(&mut self) -> &mut Self { self } + fn twaddle(&mut self) -> &mut Self { self } + fn emit(&mut self) { + self.x += 1; + } +} + +fn main() { + let mut foo = Foo { x: 0 }; + match 22 { + 22 => &mut foo, + 44 => foo.twiddle(), + _ => foo.twaddle(), + }.emit(); +} From 52bb99dcc7c918cc9568a3bd26801da07c1ce103 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Tue, 13 Mar 2018 14:52:11 -0400 Subject: [PATCH 166/830] Move 48070 test to ui --- src/test/{run-pass => ui/nll}/issue-48070.rs | 1 + 1 file changed, 1 insertion(+) rename src/test/{run-pass => ui/nll}/issue-48070.rs (98%) diff --git a/src/test/run-pass/issue-48070.rs b/src/test/ui/nll/issue-48070.rs similarity index 98% rename from src/test/run-pass/issue-48070.rs rename to src/test/ui/nll/issue-48070.rs index c2253aa8b4c2..71d92c3702e6 100644 --- a/src/test/run-pass/issue-48070.rs +++ b/src/test/ui/nll/issue-48070.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// run-pass // revisions: lxl nll #![cfg_attr(nll, feature(nll))] From decbb83f9e7e763d440d9e00861f6dd066e0e487 Mon Sep 17 00:00:00 2001 From: Michael Lamparski Date: Tue, 13 Mar 2018 15:11:53 -0400 Subject: [PATCH 167/830] Add test for issue 48941 A broken test to be fixed in the next commit. --- .../auxiliary/macro_crate_test.rs | 10 +++++++ src/test/compile-fail-fulldeps/issue-48941.rs | 29 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/test/compile-fail-fulldeps/issue-48941.rs diff --git a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs index 61b1a0a0b4d2..48be4ac6c37b 100644 --- a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs +++ b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs @@ -37,6 +37,9 @@ pub fn plugin_registrar(reg: &mut Registry) { reg.register_syntax_extension( Symbol::intern("into_multi_foo"), MultiModifier(Box::new(expand_into_foo_multi))); + reg.register_syntax_extension( + Symbol::intern("noop_attribute"), + MultiModifier(Box::new(expand_noop_attribute))); reg.register_syntax_extension( Symbol::intern("duplicate"), MultiDecorator(Box::new(expand_duplicate))); @@ -93,6 +96,13 @@ fn expand_into_foo_multi(cx: &mut ExtCtxt, } } +fn expand_noop_attribute(_cx: &mut ExtCtxt, + _sp: Span, + _attr: &MetaItem, + it: Annotatable) -> Annotatable { + it +} + // Create a duplicate of the annotatable, based on the MetaItem fn expand_duplicate(cx: &mut ExtCtxt, _sp: Span, diff --git a/src/test/compile-fail-fulldeps/issue-48941.rs b/src/test/compile-fail-fulldeps/issue-48941.rs new file mode 100644 index 000000000000..4be2874ed4ff --- /dev/null +++ b/src/test/compile-fail-fulldeps/issue-48941.rs @@ -0,0 +1,29 @@ +// Copyright 2013-2014 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 is a regression test against an ICE that used to occur +// on malformed attributes for a custom MultiModifier. + +// aux-build:macro_crate_test.rs +// ignore-stage1 + +#![feature(plugin)] +#![plugin(macro_crate_test)] + +#[noop_attribute"x"] //~ ERROR expected one of +fn night() { } + +#[noop_attribute("hi"), rank = 2] //~ ERROR unexpected token +fn knight() { } + +#[noop_attribute("/user", data= = " Date: Tue, 13 Mar 2018 15:12:15 -0400 Subject: [PATCH 168/830] Fix ICE on malformed plugin attributes --- src/libsyntax/ext/expand.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 377f47a3ea5a..3e75afcee1cf 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -484,13 +484,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> { match *ext { MultiModifier(ref mac) => { - let meta = attr.parse_meta(self.cx.parse_sess).ok()?; + let meta = attr.parse_meta(self.cx.parse_sess) + .map_err(|mut e| { e.emit(); }).ok()?; let item = mac.expand(self.cx, attr.span, &meta, item); Some(kind.expect_from_annotatables(item)) } MultiDecorator(ref mac) => { let mut items = Vec::new(); - let meta = attr.parse_meta(self.cx.parse_sess).ok()?; + let meta = attr.parse_meta(self.cx.parse_sess) + .expect("derive meta should already have been parsed"); mac.expand(self.cx, attr.span, &meta, &item, &mut |item| items.push(item)); items.push(item); Some(kind.expect_from_annotatables(items)) From 6d534d5880f27c9b1e5a12148572823202e70b4d Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 13 Mar 2018 13:26:07 -0700 Subject: [PATCH 169/830] Clarify usage message for --remap-path-prefix. --- src/librustc/session/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1c5cfa87ef46..7058d84f339d 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1641,7 +1641,7 @@ pub fn rustc_optgroups() -> Vec { opt::multi_s( "", "remap-path-prefix", - "remap source names in output", + "Remap source names in all output (compiler messages and output files)", "FROM=TO", ), ]); From 30adb53f46628fa37042543359a269221350b6d7 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 13 Mar 2018 17:00:51 -0500 Subject: [PATCH 170/830] talk about intra-links --- src/doc/rustdoc/src/unstable-features.md | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 8dbd0aa9a9a1..08cceff0e701 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -31,3 +31,48 @@ future. Attempting to use these error numbers on stable will result in the code sample being interpreted as plain text. + +## Linking to items by type + +As designed in [RFC 1946], Rustdoc can parse paths to items when you use them as links. To resolve +these type names, it uses the items currently in-scope, either by declaration or by `use` statement. +For modules, the "active scope" depends on whether the documentation is written outside the module +(as `///` comments on the `mod` statement) or inside the module (at `//!` comments inside the file +or block). For all other items, it uses the enclosing module's scope. + +[RFC 1946]: https://github.com/rust-lang/rfcs/pull/1946 + +For example, in the following code: + +```rust +/// Does the thing. +pub fn do_the_thing(_: SomeType) { + println!("Let's do the thing!"); +} + +/// Token you use to [`do_the_thing`]. +pub struct SomeType; +``` + +The link to ``[`do_the_thing`]`` in `SomeType`'s docs will properly link to the page for `fn +do_the_thing`. Note that here, rustdoc will insert the link target for you, but manually writing the +target out also works: + +```rust +pub mod some_module { + /// Token you use to do the thing. + pub struct SomeStruct; +} + +/// Does the thing. Requires one [`SomeStruct`] for the thing to work. +/// +/// [`SomeStruct`]: some_module::SomeStruct +pub fn do_the_thing(_: some_module::SomeStruct) { + println!("Let's do the thing!"); +} +``` + +For more details, check out [the RFC][RFC 1946], and see [the tracking issue][43466] for more +information about what parts of the feature are available. + +[43466]: https://github.com/rust-lang/rust/issues/43466 From 63f654a495ed868bcd5fb0ee03e1ff581e08e9ee Mon Sep 17 00:00:00 2001 From: Alex Butler Date: Tue, 13 Mar 2018 21:03:22 +0000 Subject: [PATCH 171/830] fix #48816 don't print help on indirect compiler ICE --- src/librustc_driver/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 746f2db4767f..d39dc8668c0e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1457,6 +1457,12 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { args.push(arg.to_string_lossy().to_string()); } + // Avoid printing help because of empty args. This can suggest the compiler + // itself is not the program root (consider RLS). + if args.len() < 2 { + return None; + } + let matches = if let Some(matches) = handle_options(&args) { matches } else { From 2f2e17341c171c847c201516bec9bf2234704000 Mon Sep 17 00:00:00 2001 From: Peter Hrvola Date: Fri, 23 Feb 2018 20:18:38 +0100 Subject: [PATCH 172/830] Speed up SVH computation by using Fingerprint::combine() Fix #47297 r? @michaelwoerister --- src/librustc/hir/map/collector.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 99b1e5783e01..e6f95fb99ea7 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -13,6 +13,7 @@ use dep_graph::{DepGraph, DepKind, DepNodeIndex}; use hir::def_id::{LOCAL_CRATE, CrateNum}; use hir::intravisit::{Visitor, NestedVisitorMap}; use hir::svh::Svh; +use ich::Fingerprint; use middle::cstore::CrateStore; use session::CrateDisambiguator; use std::iter::repeat; @@ -121,21 +122,24 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { collector } - pub(super) fn finalize_and_compute_crate_hash(self, + pub(super) fn finalize_and_compute_crate_hash(mut self, crate_disambiguator: CrateDisambiguator, cstore: &CrateStore, codemap: &CodeMap, commandline_args_hash: u64) -> (Vec>, Svh) { - let mut node_hashes: Vec<_> = self + self + .hir_body_nodes + .sort_unstable_by(|&(ref d1, _), &(ref d2, _)| d1.cmp(d2)); + + let node_hashes = self .hir_body_nodes .iter() - .map(|&(def_path_hash, dep_node_index)| { - (def_path_hash, self.dep_graph.fingerprint_of(dep_node_index)) - }) - .collect(); - - node_hashes.sort_unstable_by(|&(ref d1, _), &(ref d2, _)| d1.cmp(d2)); + .fold(Fingerprint::ZERO, |fingerprint , &(def_path_hash, dep_node_index)| { + fingerprint.combine( + def_path_hash.0.combine(self.dep_graph.fingerprint_of(dep_node_index)) + ) + }); let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| { let name = cstore.crate_name_untracked(cnum).as_str(); From 8c75e18e5d23ea88914a8e276037980e96866c76 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Feb 2018 16:17:44 +0100 Subject: [PATCH 173/830] test for putting back check on json --- src/librustc_errors/diagnostic_builder.rs | 3 +- src/librustc_errors/emitter.rs | 89 +++++++++-------------- src/librustc_errors/lib.rs | 51 ++++++++++++- src/tools/compiletest/src/json.rs | 20 +++++ src/tools/compiletest/src/runtest.rs | 43 ++++++----- 5 files changed, 127 insertions(+), 79 deletions(-) diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 2536fc648c70..945ecce7ab3e 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -92,7 +92,8 @@ impl<'a> DiagnosticBuilder<'a> { Level::Bug | Level::Fatal | Level::PhaseFatal | - Level::Error => { + Level::Error | + Level::FailureNote => { true } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index f481b36daa34..3b6e6db7f46c 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -21,7 +21,7 @@ use atty; use std::borrow::Cow; use std::io::prelude::*; use std::io; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use std::cmp::min; use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter}; use termcolor::{WriteColor, Color, Buffer}; @@ -33,6 +33,11 @@ const ANONYMIZED_LINE_NUM: &str = "LL"; pub trait Emitter { /// Emit a structured diagnostic. fn emit(&mut self, db: &DiagnosticBuilder); + + /// Check if should show explanations about "rustc --explain" + fn should_show_explain(&self) -> bool { + true + } } impl Emitter for EmitterWriter { @@ -80,6 +85,10 @@ impl Emitter for EmitterWriter { &children, &suggestions); } + + fn should_show_explain(&self) -> bool { + !self.short_message + } } /// maximum number of lines we will print for each error; arbitrary. @@ -114,7 +123,6 @@ pub struct EmitterWriter { cm: Option>, short_message: bool, teach: bool, - error_codes: HashSet, ui_testing: bool, } @@ -124,34 +132,6 @@ struct FileWithAnnotatedLines { multiline_depth: usize, } -impl Drop for EmitterWriter { - fn drop(&mut self) { - if !self.short_message && !self.error_codes.is_empty() { - let mut error_codes = self.error_codes.clone().into_iter().collect::>(); - let mut dst = self.dst.writable(); - error_codes.sort(); - if error_codes.len() > 1 { - let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; - writeln!(dst, - "You've got a few errors: {}{}", - error_codes[..limit].join(", "), - if error_codes.len() > 9 { "..." } else { "" } - ).expect("failed to give tips..."); - writeln!(dst, - "If you want more information on an error, try using \ - \"rustc --explain {}\"", - &error_codes[0]).expect("failed to give tips..."); - } else { - writeln!(dst, - "If you want more information on this error, try using \ - \"rustc --explain {}\"", - &error_codes[0]).expect("failed to give tips..."); - } - dst.flush().expect("failed to emit errors"); - } - } -} - impl EmitterWriter { pub fn stderr(color_config: ColorConfig, code_map: Option>, @@ -164,7 +144,6 @@ impl EmitterWriter { cm: code_map, short_message, teach, - error_codes: HashSet::new(), ui_testing: false, } } @@ -179,7 +158,6 @@ impl EmitterWriter { cm: code_map, short_message, teach, - error_codes: HashSet::new(), ui_testing: false, } } @@ -993,18 +971,26 @@ impl EmitterWriter { buffer.prepend(0, " ", Style::NoStyle); } draw_note_separator(&mut buffer, 0, max_line_num_len + 1); - buffer.append(0, &level.to_string(), Style::HeaderMsg); - buffer.append(0, ": ", Style::NoStyle); + let level_str = level.to_string(); + if !level_str.is_empty() { + buffer.append(0, &level_str, Style::HeaderMsg); + buffer.append(0, ": ", Style::NoStyle); + } self.msg_to_buffer(&mut buffer, msg, max_line_num_len, "note", None); } else { - buffer.append(0, &level.to_string(), Style::Level(level.clone())); + let level_str = level.to_string(); + if !level_str.is_empty() { + buffer.append(0, &level_str, Style::Level(level.clone())); + } // only render error codes, not lint codes if let Some(DiagnosticId::Error(ref code)) = *code { buffer.append(0, "[", Style::Level(level.clone())); buffer.append(0, &code, Style::Level(level.clone())); buffer.append(0, "]", Style::Level(level.clone())); } - buffer.append(0, ": ", Style::HeaderMsg); + if !level_str.is_empty() { + buffer.append(0, ": ", Style::HeaderMsg); + } for &(ref text, _) in msg.iter() { buffer.append(0, text, Style::HeaderMsg); } @@ -1020,14 +1006,12 @@ impl EmitterWriter { if primary_span != &&DUMMY_SP { (cm.lookup_char_pos(primary_span.lo()), cm) } else { - emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message, - &mut self.error_codes)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; return Ok(()); } } else { // If we don't have span information, emit and exit - emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message, - &mut self.error_codes)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; return Ok(()); }; if let Ok(pos) = @@ -1200,8 +1184,7 @@ impl EmitterWriter { } // final step: take our styled buffer, render it, then output it - emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message, - &mut self.error_codes)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; Ok(()) @@ -1218,8 +1201,11 @@ impl EmitterWriter { let mut buffer = StyledBuffer::new(); // Render the suggestion message - buffer.append(0, &level.to_string(), Style::Level(level.clone())); - buffer.append(0, ": ", Style::HeaderMsg); + let level_str = level.to_string(); + if !level_str.is_empty() { + buffer.append(0, &level_str, Style::Level(level.clone())); + buffer.append(0, ": ", Style::HeaderMsg); + } self.msg_to_buffer(&mut buffer, &[(suggestion.msg.to_owned(), Style::NoStyle)], max_line_num_len, @@ -1289,8 +1275,7 @@ impl EmitterWriter { let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS); buffer.puts(row_num, 0, &msg, Style::NoStyle); } - emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message, - &mut self.error_codes)?; + emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; } Ok(()) } @@ -1321,7 +1306,7 @@ impl EmitterWriter { draw_col_separator_no_space(&mut buffer, 0, max_line_num_len + 1); } match emit_to_destination(&buffer.render(), level, &mut self.dst, - self.short_message, &mut self.error_codes) { + self.short_message) { Ok(()) => (), Err(e) => panic!("failed to emit error: {}", e) } @@ -1416,8 +1401,7 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool { fn emit_to_destination(rendered_buffer: &Vec>, lvl: &Level, dst: &mut Destination, - short_message: bool, - error_codes: &mut HashSet) + short_message: bool) -> io::Result<()> { use lock; @@ -1436,16 +1420,13 @@ fn emit_to_destination(rendered_buffer: &Vec>, // same buffering approach. Instead, we use a global Windows mutex, which we acquire long // enough to output the full error message, then we release. let _buffer_lock = lock::acquire_global_lock("rustc_errors"); - for line in rendered_buffer { + for (pos, line) in rendered_buffer.iter().enumerate() { for part in line { dst.apply_style(lvl.clone(), part.style)?; write!(dst, "{}", part.text)?; - if !short_message && part.text.len() == 12 && part.text.starts_with("error[E") { - error_codes.insert(part.text[6..11].to_owned()); - } dst.reset()?; } - if !short_message { + if !short_message && (!lvl.is_failure_note() || pos != rendered_buffer.len() - 1) { write!(dst, "\n")?; } } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 924ed71ef0d6..7148969191f2 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -509,12 +509,14 @@ impl Handler { pub fn span_unimpl>(&self, sp: S, msg: &str) -> ! { self.span_bug(sp, &format!("unimplemented {}", msg)); } + pub fn failure(&self, msg: &str) { + DiagnosticBuilder::new(self, FailureNote, msg).emit() + } pub fn fatal(&self, msg: &str) -> FatalError { if self.flags.treat_err_as_bug { self.bug(msg); } - let mut db = DiagnosticBuilder::new(self, Fatal, msg); - db.emit(); + DiagnosticBuilder::new(self, Fatal, msg).emit(); FatalError } pub fn err(&self, msg: &str) { @@ -567,8 +569,39 @@ impl Handler { s = format!("aborting due to {} previous errors", self.err_count()); } } + let err = self.fatal(&s); - self.fatal(&s).raise(); + let can_show_explain = self.emitter.borrow().should_show_explain(); + let are_there_diagnostics = !self.tracked_diagnostic_codes.borrow().is_empty(); + if can_show_explain && are_there_diagnostics { + let mut error_codes = + self.tracked_diagnostic_codes.borrow() + .clone() + .into_iter() + .filter_map(|x| match x { + DiagnosticId::Error(ref s) => Some(s.clone()), + _ => None, + }) + .collect::>(); + if !error_codes.is_empty() { + error_codes.sort(); + if error_codes.len() > 1 { + let limit = if error_codes.len() > 9 { 9 } else { error_codes.len() }; + self.failure(&format!("Some errors occurred: {}{}", + error_codes[..limit].join(", "), + if error_codes.len() > 9 { "..." } else { "." })); + self.failure(&format!("For more information about an error, try \ + `rustc --explain {}`.", + &error_codes[0])); + } else { + self.failure(&format!("For more information about this error, try \ + `rustc --explain {}`.", + &error_codes[0])); + } + } + } + + err.raise(); } pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) { if lvl == Warning && !self.flags.can_emit_warnings { @@ -654,6 +687,7 @@ pub enum Level { Note, Help, Cancelled, + FailureNote, } impl fmt::Display for Level { @@ -682,9 +716,10 @@ impl Level { spec.set_fg(Some(Color::Cyan)) .set_intense(true); } + FailureNote => {} Cancelled => unreachable!(), } - return spec + spec } pub fn to_str(self) -> &'static str { @@ -694,7 +729,15 @@ impl Level { Warning => "warning", Note => "note", Help => "help", + FailureNote => "", Cancelled => panic!("Shouldn't call on cancelled error"), } } + + pub fn is_failure_note(&self) -> bool { + match *self { + FailureNote => true, + _ => false, + } + } } diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 08630628b718..761d1e511d52 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -24,6 +24,7 @@ struct Diagnostic { level: String, spans: Vec, children: Vec, + rendered: Option, } #[derive(Deserialize, Clone)] @@ -56,6 +57,25 @@ struct DiagnosticCode { explanation: Option, } +pub fn extract_rendered(output: &str, proc_res: &ProcRes) -> String { + output.lines() + .filter_map(|line| if line.starts_with('{') { + match serde_json::from_str::(line) { + Ok(diagnostic) => diagnostic.rendered, + Err(error) => { + proc_res.fatal(Some(&format!("failed to decode compiler output as json: \ + `{}`\noutput: {}\nline: {}", + error, + line, + output))); + } + } + } else { + None + }) + .collect() +} + pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec { output.lines() .flat_map(|line| parse_line(file_name, line, output, proc_res)) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 6619838cce07..953a13a3f582 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -248,7 +248,7 @@ impl<'test> TestCx<'test> { } fn run_cfail_test(&self) { - let proc_res = self.compile_test(&[]); + let proc_res = self.compile_test(); self.check_if_test_should_compile(&proc_res); self.check_no_compiler_crash(&proc_res); @@ -267,7 +267,7 @@ impl<'test> TestCx<'test> { } fn run_rfail_test(&self) { - let proc_res = self.compile_test(&[]); + let proc_res = self.compile_test(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -309,7 +309,7 @@ impl<'test> TestCx<'test> { } fn run_rpass_test(&self) { - let proc_res = self.compile_test(&[]); + let proc_res = self.compile_test(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -336,7 +336,7 @@ impl<'test> TestCx<'test> { return self.run_rpass_test(); } - let mut proc_res = self.compile_test(&[]); + let mut proc_res = self.compile_test(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -578,7 +578,7 @@ impl<'test> TestCx<'test> { let mut cmds = commands.join("\n"); // compile test file (it should have 'compile-flags:-g' in the header) - let compiler_run_result = self.compile_test(&[]); + let compiler_run_result = self.compile_test(); if !compiler_run_result.status.success() { self.fatal_proc_rec("compilation failed!", &compiler_run_result); } @@ -835,7 +835,7 @@ impl<'test> TestCx<'test> { fn run_debuginfo_lldb_test_no_opt(&self) { // compile test file (it should have 'compile-flags:-g' in the header) - let compile_result = self.compile_test(&[]); + let compile_result = self.compile_test(); if !compile_result.status.success() { self.fatal_proc_rec("compilation failed!", &compile_result); } @@ -1272,15 +1272,12 @@ impl<'test> TestCx<'test> { } } - fn compile_test(&self, extra_args: &[&'static str]) -> ProcRes { + fn compile_test(&self) -> ProcRes { let mut rustc = self.make_compile_args( &self.testpaths.file, TargetLocation::ThisFile(self.make_exe_name()), ); - if !extra_args.is_empty() { - rustc.args(extra_args); - } rustc.arg("-L").arg(&self.aux_output_dir_name()); match self.config.mode { @@ -1626,12 +1623,14 @@ impl<'test> TestCx<'test> { if self.props.error_patterns.is_empty() { rustc.args(&["--error-format", "json"]); } + if !self.props.disable_ui_testing_normalization { + rustc.arg("-Zui-testing"); + } } Ui => { - // In case no "--error-format" has been given in the test, we'll compile - // a first time to get the compiler's output then compile with - // "--error-format json" to check if all expected errors are actually there - // and that no new one appeared. + if !self.props.compile_flags.iter().any(|s| s.starts_with("--error-format")) { + rustc.args(&["--error-format", "json"]); + } if !self.props.disable_ui_testing_normalization { rustc.arg("-Zui-testing"); } @@ -2114,7 +2113,7 @@ impl<'test> TestCx<'test> { fn run_codegen_units_test(&self) { assert!(self.revision.is_none(), "revisions not relevant here"); - let proc_res = self.compile_test(&[]); + let proc_res = self.compile_test(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); @@ -2505,7 +2504,7 @@ impl<'test> TestCx<'test> { .iter() .any(|s| s.contains("--error-format")); - let proc_res = self.compile_test(&[]); + let proc_res = self.compile_test(); self.check_if_test_should_compile(&proc_res); let expected_stderr_path = self.expected_output_path(UI_STDERR); @@ -2517,8 +2516,13 @@ impl<'test> TestCx<'test> { let normalized_stdout = self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout); - let normalized_stderr = self.normalize_output(&proc_res.stderr, - &self.props.normalize_stderr); + let stderr = if explicit { + proc_res.stderr.clone() + } else { + json::extract_rendered(&proc_res.stderr, &proc_res) + }; + + let normalized_stderr = self.normalize_output(&stderr, &self.props.normalize_stderr); let mut errors = 0; errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout); @@ -2551,7 +2555,6 @@ impl<'test> TestCx<'test> { } } if !explicit { - let proc_res = self.compile_test(&["--error-format", "json"]); if !expected_errors.is_empty() || !proc_res.status.success() { // "// error-pattern" comments self.check_expected_errors(expected_errors, &proc_res); @@ -2563,7 +2566,7 @@ impl<'test> TestCx<'test> { } fn run_mir_opt_test(&self) { - let proc_res = self.compile_test(&[]); + let proc_res = self.compile_test(); if !proc_res.status.success() { self.fatal_proc_rec("compilation failed!", &proc_res); From 2e104a77cfb6b83f725512210c88dc970426a354 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 3 Mar 2018 15:59:40 +0100 Subject: [PATCH 174/830] update tests --- src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr | 2 +- src/test/ui-fulldeps/proc-macro/signature.stderr | 2 +- src/test/ui/anonymous-higher-ranked-lifetime.stderr | 2 +- .../ui/arbitrary-self-types-not-object-safe.stderr | 2 +- src/test/ui/asm-out-assign-imm.stderr | 2 +- .../ui/associated-const-impl-wrong-lifetime.stderr | 2 +- src/test/ui/associated-const-impl-wrong-type.stderr | 2 +- ...ed-type-projection-from-multiple-supertraits.stderr | 4 ++-- ...ociated-types-ICE-when-projecting-out-of-err.stderr | 2 +- .../ui/associated-types-in-ambiguous-context.stderr | 2 +- src/test/ui/attr-usage-repr.stderr | 2 +- src/test/ui/augmented-assignments.stderr | 4 ++-- src/test/ui/binary-op-on-double-ref.stderr | 2 +- src/test/ui/blind-item-item-shadow.stderr | 2 +- .../block-result/block-must-not-have-result-do.stderr | 2 +- .../block-result/block-must-not-have-result-res.stderr | 2 +- .../block-must-not-have-result-while.stderr | 2 +- .../ui/block-result/consider-removing-last-semi.stderr | 2 +- src/test/ui/block-result/issue-11714.stderr | 2 +- src/test/ui/block-result/issue-13428.stderr | 2 +- src/test/ui/block-result/issue-13624.stderr | 2 +- src/test/ui/block-result/issue-20862.stderr | 4 ++-- src/test/ui/block-result/issue-22645.stderr | 4 ++-- src/test/ui/block-result/issue-3563.stderr | 2 +- src/test/ui/block-result/issue-5500.stderr | 2 +- .../ui/block-result/unexpected-return-on-unit.stderr | 2 +- src/test/ui/bogus-tag.stderr | 2 +- src/test/ui/borrowck/borrowck-box-insensitivity.stderr | 4 ++-- src/test/ui/borrowck/borrowck-closures-two-mut.stderr | 2 +- .../borrowck/borrowck-escaping-closure-error-1.stderr | 2 +- .../borrowck/borrowck-escaping-closure-error-2.stderr | 2 +- src/test/ui/borrowck/borrowck-in-static.stderr | 2 +- .../ui/borrowck/borrowck-move-error-with-note.stderr | 4 ++-- .../ui/borrowck/borrowck-move-out-of-vec-tail.stderr | 2 +- src/test/ui/borrowck/borrowck-reinit.stderr | 2 +- .../borrowck-report-with-custom-diagnostic.stderr | 4 ++-- .../ui/borrowck/borrowck-vec-pattern-nesting.stderr | 4 ++-- src/test/ui/borrowck/immutable-arg.stderr | 2 +- src/test/ui/borrowck/issue-41962.stderr | 2 +- src/test/ui/borrowck/mut-borrow-in-loop.stderr | 2 +- src/test/ui/borrowck/mut-borrow-outside-loop.stderr | 2 +- .../regions-bound-missing-bound-in-impl.stderr | 4 ++-- ...losures-move-upvar-from-non-once-ref-closure.stderr | 2 +- src/test/ui/cast-as-bool.stderr | 2 +- src/test/ui/cast-errors-issue-43825.stderr | 2 +- src/test/ui/cast-rfc0401-2.stderr | 2 +- .../ui/cast-to-unsized-trait-object-suggestion.stderr | 2 +- src/test/ui/casts-differing-anon.stderr | 2 +- src/test/ui/casts-issue-46365.stderr | 2 +- src/test/ui/changing-crates.stderr | 2 +- src/test/ui/check_match/issue-35609.stderr | 2 +- .../expect-region-supply-region.stderr | 2 +- src/test/ui/closure_context/issue-26046-fn-mut.stderr | 2 +- src/test/ui/closure_context/issue-26046-fn-once.stderr | 2 +- src/test/ui/closure_context/issue-42065.stderr | 2 +- .../coherence-overlapping-inherent-impl-trait.stderr | 2 +- src/test/ui/codemap_tests/empty_span.stderr | 2 +- .../ui/codemap_tests/huge_multispan_highlight.stderr | 2 +- src/test/ui/codemap_tests/issue-11715.stderr | 2 +- src/test/ui/codemap_tests/issue-28308.stderr | 2 +- src/test/ui/codemap_tests/one_line.stderr | 2 +- .../ui/codemap_tests/overlapping_inherent_impls.stderr | 2 +- src/test/ui/codemap_tests/overlapping_spans.stderr | 2 +- src/test/ui/codemap_tests/tab.stderr | 4 ++-- src/test/ui/codemap_tests/tab_3.stderr | 2 +- src/test/ui/codemap_tests/two_files.stderr | 1 - src/test/ui/codemap_tests/unicode_2.stderr | 2 +- src/test/ui/coercion-missing-tail-expected-type.stderr | 2 +- src/test/ui/coherence-error-suppression.stderr | 2 +- src/test/ui/coherence-impls-copy.stderr | 4 ++-- .../ui/coherence-overlap-downstream-inherent.stderr | 2 +- src/test/ui/coherence-overlap-downstream.stderr | 2 +- .../ui/coherence-overlap-issue-23516-inherent.stderr | 2 +- src/test/ui/coherence-overlap-issue-23516.stderr | 2 +- src/test/ui/coherence-overlap-upstream-inherent.stderr | 2 +- src/test/ui/coherence-overlap-upstream.stderr | 2 +- src/test/ui/command-line-diagnostics.stderr | 2 +- src/test/ui/compare-method/proj-outlives-region.stderr | 2 +- src/test/ui/compare-method/region-extra-2.stderr | 2 +- src/test/ui/compare-method/region-extra.stderr | 2 +- src/test/ui/compare-method/region-unrelated.stderr | 2 +- src/test/ui/compare-method/reordered-type-param.stderr | 2 +- .../trait-bound-on-type-parameter.stderr | 2 +- .../ui/compare-method/traits-misc-mismatch-1.stderr | 2 +- .../ui/compare-method/traits-misc-mismatch-2.stderr | 2 +- src/test/ui/const-deref-ptr.stderr | 2 +- src/test/ui/const-eval-overflow-2.stderr | 2 +- src/test/ui/const-eval-overflow-4.stderr | 2 +- src/test/ui/const-eval-span.stderr | 2 +- .../ui/const-eval/conditional_array_execution.stderr | 2 +- src/test/ui/const-eval/index_out_of_bound.stderr | 2 +- src/test/ui/const-eval/issue-43197.stderr | 2 +- src/test/ui/const-fn-error.stderr | 4 ++-- src/test/ui/const-fn-mismatch.stderr | 2 +- src/test/ui/const-fn-not-in-trait.stderr | 2 +- src/test/ui/const-len-underflow-separate-spans.stderr | 2 +- src/test/ui/const-pattern-irrefutable.stderr | 2 +- src/test/ui/const-unsized.stderr | 2 +- src/test/ui/cycle-trait-supertrait-indirect.stderr | 2 +- src/test/ui/deref-suggestion.stderr | 2 +- src/test/ui/derived-errors/issue-31997-1.stderr | 2 +- src/test/ui/did_you_mean/E0178.stderr | 2 +- src/test/ui/did_you_mean/bad-assoc-pat.stderr | 2 +- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 4 ++-- .../issue-21659-show-relevant-trait-impls-1.stderr | 2 +- .../issue-21659-show-relevant-trait-impls-2.stderr | 2 +- src/test/ui/did_you_mean/issue-31424.stderr | 2 +- src/test/ui/did_you_mean/issue-34126.stderr | 2 +- src/test/ui/did_you_mean/issue-34337.stderr | 2 +- src/test/ui/did_you_mean/issue-35937.stderr | 4 ++-- src/test/ui/did_you_mean/issue-36798.stderr | 2 +- .../ui/did_you_mean/issue-36798_unknown_field.stderr | 2 +- src/test/ui/did_you_mean/issue-37139.stderr | 2 +- .../issue-38054-do-not-show-unresolved-names.stderr | 2 +- src/test/ui/did_you_mean/issue-38147-1.stderr | 2 +- src/test/ui/did_you_mean/issue-38147-2.stderr | 2 +- src/test/ui/did_you_mean/issue-38147-3.stderr | 2 +- src/test/ui/did_you_mean/issue-38147-4.stderr | 2 +- src/test/ui/did_you_mean/issue-39544.stderr | 4 ++-- .../did_you_mean/issue-39802-show-5-trait-impls.stderr | 2 +- src/test/ui/did_you_mean/issue-40006.stderr | 2 +- src/test/ui/did_you_mean/issue-40823.stderr | 2 +- .../issue-42599_available_fields_note.stderr | 4 ++-- src/test/ui/did_you_mean/issue-42764.stderr | 2 +- .../issue-43871-enum-instead-of-variant.stderr | 4 ++-- src/test/ui/did_you_mean/recursion_limit.stderr | 2 +- src/test/ui/did_you_mean/recursion_limit_deref.stderr | 4 ++-- ...t-object-reference-without-parens-suggestion.stderr | 4 ++-- src/test/ui/discrim-overflow-2.stderr | 2 +- src/test/ui/discrim-overflow.stderr | 2 +- src/test/ui/double-import.stderr | 2 +- src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr | 2 +- .../dropck/dropck-eyepatch-implies-unsafe-impl.stderr | 2 +- src/test/ui/dropck/dropck-eyepatch-reorder.stderr | 2 +- src/test/ui/dropck/dropck-eyepatch.stderr | 2 +- src/test/ui/e0119/complex-impl.stderr | 4 ++-- src/test/ui/e0119/conflict-with-std.stderr | 2 +- src/test/ui/e0119/issue-23563.stderr | 2 +- src/test/ui/e0119/issue-27403.stderr | 2 +- src/test/ui/e0119/issue-28981.stderr | 4 ++-- src/test/ui/e0119/so-37347311.stderr | 2 +- src/test/ui/empty-struct-unit-expr.stderr | 2 +- src/test/ui/enum-and-module-in-same-scope.stderr | 2 +- src/test/ui/error-codes/E0004-2.stderr | 2 +- src/test/ui/error-codes/E0004.stderr | 2 +- src/test/ui/error-codes/E0005.stderr | 2 +- src/test/ui/error-codes/E0007.stderr | 4 ++-- src/test/ui/error-codes/E0008.stderr | 2 +- src/test/ui/error-codes/E0009.stderr | 2 +- src/test/ui/error-codes/E0010-teach.stderr | 2 +- src/test/ui/error-codes/E0010.stderr | 2 +- src/test/ui/error-codes/E0017.stderr | 4 ++-- src/test/ui/error-codes/E0023.stderr | 2 +- src/test/ui/error-codes/E0025.stderr | 2 +- src/test/ui/error-codes/E0026-teach.stderr | 2 +- src/test/ui/error-codes/E0026.stderr | 2 +- src/test/ui/error-codes/E0027-teach.stderr | 2 +- src/test/ui/error-codes/E0027.stderr | 2 +- src/test/ui/error-codes/E0029-teach.stderr | 4 ++-- src/test/ui/error-codes/E0029.stderr | 4 ++-- src/test/ui/error-codes/E0030-teach.stderr | 2 +- src/test/ui/error-codes/E0030.stderr | 2 +- src/test/ui/error-codes/E0033-teach.stderr | 4 ++-- src/test/ui/error-codes/E0033.stderr | 4 ++-- src/test/ui/error-codes/E0034.stderr | 2 +- src/test/ui/error-codes/E0038.stderr | 2 +- src/test/ui/error-codes/E0040.stderr | 2 +- src/test/ui/error-codes/E0044.stderr | 2 +- src/test/ui/error-codes/E0045.stderr | 2 +- src/test/ui/error-codes/E0049.stderr | 2 +- src/test/ui/error-codes/E0050.stderr | 2 +- src/test/ui/error-codes/E0054.stderr | 2 +- src/test/ui/error-codes/E0055.stderr | 2 +- src/test/ui/error-codes/E0057.stderr | 2 +- src/test/ui/error-codes/E0059.stderr | 2 +- src/test/ui/error-codes/E0060.stderr | 2 +- src/test/ui/error-codes/E0061.stderr | 2 +- src/test/ui/error-codes/E0062.stderr | 2 +- src/test/ui/error-codes/E0063.stderr | 2 +- src/test/ui/error-codes/E0067.stderr | 4 ++-- src/test/ui/error-codes/E0069.stderr | 2 +- src/test/ui/error-codes/E0070.stderr | 4 ++-- src/test/ui/error-codes/E0071.stderr | 2 +- src/test/ui/error-codes/E0075.stderr | 2 +- src/test/ui/error-codes/E0076.stderr | 2 +- src/test/ui/error-codes/E0077.stderr | 2 +- src/test/ui/error-codes/E0080.stderr | 2 +- src/test/ui/error-codes/E0081.stderr | 2 +- src/test/ui/error-codes/E0084.stderr | 2 +- src/test/ui/error-codes/E0087.stderr | 2 +- src/test/ui/error-codes/E0088.stderr | 2 +- src/test/ui/error-codes/E0089.stderr | 2 +- src/test/ui/error-codes/E0090.stderr | 2 +- src/test/ui/error-codes/E0091.stderr | 2 +- src/test/ui/error-codes/E0092.stderr | 2 +- src/test/ui/error-codes/E0093.stderr | 2 +- src/test/ui/error-codes/E0094.stderr | 2 +- src/test/ui/error-codes/E0106.stderr | 2 +- src/test/ui/error-codes/E0107.stderr | 2 +- src/test/ui/error-codes/E0109.stderr | 2 +- src/test/ui/error-codes/E0110.stderr | 2 +- src/test/ui/error-codes/E0116.stderr | 2 +- src/test/ui/error-codes/E0117.stderr | 4 ++-- src/test/ui/error-codes/E0118.stderr | 2 +- src/test/ui/error-codes/E0119.stderr | 2 +- src/test/ui/error-codes/E0120.stderr | 2 +- src/test/ui/error-codes/E0121.stderr | 2 +- src/test/ui/error-codes/E0124.stderr | 2 +- src/test/ui/error-codes/E0128.stderr | 2 +- src/test/ui/error-codes/E0130.stderr | 2 +- src/test/ui/error-codes/E0131.stderr | 2 +- src/test/ui/error-codes/E0132.stderr | 2 +- src/test/ui/error-codes/E0133.stderr | 2 +- src/test/ui/error-codes/E0137.stderr | 2 +- src/test/ui/error-codes/E0138.stderr | 2 +- src/test/ui/error-codes/E0152.stderr | 2 +- src/test/ui/error-codes/E0161.stderr | 4 ++-- src/test/ui/error-codes/E0162.stderr | 2 +- src/test/ui/error-codes/E0164.stderr | 2 +- src/test/ui/error-codes/E0165.stderr | 2 +- src/test/ui/error-codes/E0184.stderr | 2 +- src/test/ui/error-codes/E0185.stderr | 2 +- src/test/ui/error-codes/E0186.stderr | 2 +- src/test/ui/error-codes/E0191.stderr | 2 +- src/test/ui/error-codes/E0192.stderr | 2 +- src/test/ui/error-codes/E0194.stderr | 2 +- src/test/ui/error-codes/E0195.stderr | 2 +- src/test/ui/error-codes/E0197.stderr | 2 +- src/test/ui/error-codes/E0198.stderr | 2 +- src/test/ui/error-codes/E0199.stderr | 2 +- src/test/ui/error-codes/E0200.stderr | 2 +- src/test/ui/error-codes/E0201.stderr | 2 +- src/test/ui/error-codes/E0206.stderr | 4 ++-- src/test/ui/error-codes/E0207.stderr | 2 +- src/test/ui/error-codes/E0214.stderr | 2 +- src/test/ui/error-codes/E0220.stderr | 4 ++-- src/test/ui/error-codes/E0221.stderr | 2 +- src/test/ui/error-codes/E0223.stderr | 2 +- src/test/ui/error-codes/E0225.stderr | 2 +- src/test/ui/error-codes/E0229.stderr | 2 +- src/test/ui/error-codes/E0232.stderr | 2 +- src/test/ui/error-codes/E0243.stderr | 2 +- src/test/ui/error-codes/E0244.stderr | 2 +- src/test/ui/error-codes/E0252.stderr | 2 +- src/test/ui/error-codes/E0253.stderr | 2 +- src/test/ui/error-codes/E0254.stderr | 2 +- src/test/ui/error-codes/E0255.stderr | 2 +- src/test/ui/error-codes/E0259.stderr | 2 +- src/test/ui/error-codes/E0260.stderr | 2 +- src/test/ui/error-codes/E0261.stderr | 2 +- src/test/ui/error-codes/E0262.stderr | 2 +- src/test/ui/error-codes/E0263.stderr | 2 +- src/test/ui/error-codes/E0264.stderr | 2 +- src/test/ui/error-codes/E0267.stderr | 2 +- src/test/ui/error-codes/E0268.stderr | 2 +- src/test/ui/error-codes/E0271.stderr | 2 +- src/test/ui/error-codes/E0275.stderr | 2 +- src/test/ui/error-codes/E0276.stderr | 2 +- src/test/ui/error-codes/E0277-2.stderr | 2 +- src/test/ui/error-codes/E0277.stderr | 2 +- src/test/ui/error-codes/E0282.stderr | 2 +- src/test/ui/error-codes/E0283.stderr | 2 +- src/test/ui/error-codes/E0296.stderr | 2 +- src/test/ui/error-codes/E0297.stderr | 2 +- src/test/ui/error-codes/E0301.stderr | 2 +- src/test/ui/error-codes/E0302.stderr | 2 +- src/test/ui/error-codes/E0303.stderr | 4 ++-- src/test/ui/error-codes/E0308-4.stderr | 2 +- src/test/ui/error-codes/E0308.stderr | 2 +- src/test/ui/error-codes/E0365.stderr | 2 +- src/test/ui/error-codes/E0370.stderr | 2 +- src/test/ui/error-codes/E0374.stderr | 2 +- src/test/ui/error-codes/E0375.stderr | 2 +- src/test/ui/error-codes/E0376.stderr | 2 +- src/test/ui/error-codes/E0388.stderr | 4 ++-- src/test/ui/error-codes/E0389.stderr | 2 +- src/test/ui/error-codes/E0390.stderr | 2 +- src/test/ui/error-codes/E0392.stderr | 2 +- src/test/ui/error-codes/E0393.stderr | 2 +- src/test/ui/error-codes/E0394.stderr | 2 +- src/test/ui/error-codes/E0395.stderr | 2 +- src/test/ui/error-codes/E0396.stderr | 2 +- src/test/ui/error-codes/E0401.stderr | 2 +- src/test/ui/error-codes/E0403.stderr | 2 +- src/test/ui/error-codes/E0404.stderr | 1 - src/test/ui/error-codes/E0405.stderr | 1 - src/test/ui/error-codes/E0407.stderr | 2 +- src/test/ui/error-codes/E0408.stderr | 2 +- src/test/ui/error-codes/E0411.stderr | 2 +- src/test/ui/error-codes/E0412.stderr | 2 +- src/test/ui/error-codes/E0415.stderr | 2 +- src/test/ui/error-codes/E0416.stderr | 2 +- src/test/ui/error-codes/E0423.stderr | 2 +- src/test/ui/error-codes/E0424.stderr | 2 +- src/test/ui/error-codes/E0425.stderr | 2 +- src/test/ui/error-codes/E0426.stderr | 2 +- src/test/ui/error-codes/E0428.stderr | 2 +- src/test/ui/error-codes/E0429.stderr | 2 +- src/test/ui/error-codes/E0430.stderr | 4 ++-- src/test/ui/error-codes/E0431.stderr | 2 +- src/test/ui/error-codes/E0432.stderr | 2 +- src/test/ui/error-codes/E0433.stderr | 2 +- src/test/ui/error-codes/E0434.stderr | 2 +- src/test/ui/error-codes/E0435.stderr | 2 +- src/test/ui/error-codes/E0437.stderr | 2 +- src/test/ui/error-codes/E0438.stderr | 2 +- src/test/ui/error-codes/E0439.stderr | 2 +- src/test/ui/error-codes/E0440.stderr | 2 +- src/test/ui/error-codes/E0441.stderr | 2 +- src/test/ui/error-codes/E0442.stderr | 2 +- src/test/ui/error-codes/E0443.stderr | 2 +- src/test/ui/error-codes/E0444.stderr | 2 +- src/test/ui/error-codes/E0445.stderr | 2 +- src/test/ui/error-codes/E0446.stderr | 2 +- src/test/ui/error-codes/E0449.stderr | 2 +- src/test/ui/error-codes/E0451.stderr | 2 +- src/test/ui/error-codes/E0452.stderr | 2 +- src/test/ui/error-codes/E0453.stderr | 2 +- src/test/ui/error-codes/E0454.stderr | 2 +- src/test/ui/error-codes/E0458.stderr | 4 ++-- src/test/ui/error-codes/E0459.stderr | 2 +- src/test/ui/error-codes/E0463.stderr | 2 +- src/test/ui/error-codes/E0478.stderr | 2 +- src/test/ui/error-codes/E0492.stderr | 2 +- src/test/ui/error-codes/E0494.stderr | 2 +- src/test/ui/error-codes/E0496.stderr | 2 +- src/test/ui/error-codes/E0499.stderr | 2 +- src/test/ui/error-codes/E0502.stderr | 2 +- src/test/ui/error-codes/E0503.stderr | 2 +- src/test/ui/error-codes/E0504.stderr | 2 +- src/test/ui/error-codes/E0505.stderr | 2 +- src/test/ui/error-codes/E0507.stderr | 2 +- src/test/ui/error-codes/E0509.stderr | 2 +- src/test/ui/error-codes/E0511.stderr | 2 +- src/test/ui/error-codes/E0512.stderr | 2 +- src/test/ui/error-codes/E0516.stderr | 2 +- src/test/ui/error-codes/E0517.stderr | 2 +- src/test/ui/error-codes/E0518.stderr | 2 +- src/test/ui/error-codes/E0520.stderr | 2 +- src/test/ui/error-codes/E0522.stderr | 4 ++-- src/test/ui/error-codes/E0527.stderr | 2 +- src/test/ui/error-codes/E0528.stderr | 2 +- src/test/ui/error-codes/E0529.stderr | 2 +- src/test/ui/error-codes/E0530.stderr | 2 +- src/test/ui/error-codes/E0532.stderr | 2 +- src/test/ui/error-codes/E0534.stderr | 2 +- src/test/ui/error-codes/E0558.stderr | 2 +- src/test/ui/error-codes/E0559.stderr | 2 +- src/test/ui/error-codes/E0560.stderr | 2 +- src/test/ui/error-codes/E0565-1.stderr | 2 +- src/test/ui/error-codes/E0565.stderr | 2 +- src/test/ui/error-codes/E0572.stderr | 2 +- src/test/ui/error-codes/E0582.stderr | 2 +- src/test/ui/error-codes/E0585.stderr | 2 +- src/test/ui/error-codes/E0586.stderr | 2 +- src/test/ui/error-codes/E0597.stderr | 2 +- src/test/ui/error-codes/E0599.stderr | 2 +- src/test/ui/error-codes/E0600.stderr | 2 +- src/test/ui/error-codes/E0602.stderr | 2 +- src/test/ui/error-codes/E0603.stderr | 2 +- src/test/ui/error-codes/E0604.stderr | 2 +- src/test/ui/error-codes/E0605.stderr | 2 +- src/test/ui/error-codes/E0606.stderr | 2 +- src/test/ui/error-codes/E0607.stderr | 2 +- src/test/ui/error-codes/E0608.stderr | 2 +- src/test/ui/error-codes/E0609.stderr | 2 +- src/test/ui/error-codes/E0610.stderr | 2 +- src/test/ui/error-codes/E0611.stderr | 2 +- src/test/ui/error-codes/E0612.stderr | 2 +- src/test/ui/error-codes/E0614.stderr | 2 +- src/test/ui/error-codes/E0615.stderr | 2 +- src/test/ui/error-codes/E0616.stderr | 2 +- src/test/ui/error-codes/E0617.stderr | 2 +- src/test/ui/error-codes/E0618.stderr | 2 +- src/test/ui/error-codes/E0620.stderr | 2 +- .../E0621-does-not-trigger-for-closures.stderr | 2 +- src/test/ui/error-codes/E0622.stderr | 2 +- src/test/ui/error-codes/E0624.stderr | 2 +- src/test/ui/error-codes/E0637.stderr | 2 +- src/test/ui/error-codes/E0657.stderr | 2 +- src/test/ui/error-codes/E0658.stderr | 2 +- src/test/ui/error-codes/E0659.stderr | 2 +- src/test/ui/error-festival.stderr | 4 ++-- src/test/ui/fat-ptr-cast.stderr | 4 ++-- src/test/ui/feature-gate-abi-msp430-interrupt.stderr | 2 +- src/test/ui/feature-gate-abi.stderr | 2 +- src/test/ui/feature-gate-abi_unadjusted.stderr | 2 +- .../ui/feature-gate-advanced-slice-features.stderr | 2 +- src/test/ui/feature-gate-allocator_internals.stderr | 2 +- ...ture-gate-allow-internal-unsafe-nested-macro.stderr | 2 +- ...re-gate-allow-internal-unstable-nested-macro.stderr | 2 +- .../feature-gate-allow-internal-unstable-struct.stderr | 2 +- .../ui/feature-gate-allow-internal-unstable.stderr | 2 +- src/test/ui/feature-gate-allow_fail.stderr | 2 +- src/test/ui/feature-gate-arbitrary-self-types.stderr | 2 +- ...eature-gate-arbitrary_self_types-raw-pointer.stderr | 2 +- src/test/ui/feature-gate-asm.stderr | 2 +- src/test/ui/feature-gate-asm2.stderr | 2 +- src/test/ui/feature-gate-assoc-type-defaults.stderr | 2 +- src/test/ui/feature-gate-box-expr.stderr | 2 +- src/test/ui/feature-gate-box_patterns.stderr | 2 +- src/test/ui/feature-gate-box_syntax.stderr | 2 +- src/test/ui/feature-gate-catch_expr.stderr | 2 +- src/test/ui/feature-gate-cfg-target-feature.stderr | 2 +- src/test/ui/feature-gate-cfg-target-has-atomic.stderr | 2 +- .../ui/feature-gate-cfg-target-thread-local.stderr | 2 +- src/test/ui/feature-gate-cfg-target-vendor.stderr | 2 +- src/test/ui/feature-gate-clone-closures.stderr | 2 +- src/test/ui/feature-gate-compiler-builtins.stderr | 2 +- src/test/ui/feature-gate-concat_idents.stderr | 2 +- src/test/ui/feature-gate-concat_idents2.stderr | 2 +- src/test/ui/feature-gate-concat_idents3.stderr | 2 +- .../ui/feature-gate-conservative_impl_trait.stderr | 2 +- src/test/ui/feature-gate-const_fn.stderr | 4 ++-- src/test/ui/feature-gate-copy-closures.stderr | 2 +- src/test/ui/feature-gate-crate_in_paths.stderr | 2 +- .../ui/feature-gate-crate_visibility_modifier.stderr | 2 +- src/test/ui/feature-gate-custom_attribute.stderr | 2 +- src/test/ui/feature-gate-custom_attribute2.stderr | 2 +- src/test/ui/feature-gate-custom_derive.stderr | 2 +- src/test/ui/feature-gate-decl_macro.stderr | 2 +- src/test/ui/feature-gate-doc_cfg.stderr | 2 +- src/test/ui/feature-gate-doc_masked.stderr | 2 +- src/test/ui/feature-gate-doc_spotlight.stderr | 2 +- src/test/ui/feature-gate-dotdoteq_in_patterns.stderr | 2 +- src/test/ui/feature-gate-dropck-ugeh.stderr | 2 +- src/test/ui/feature-gate-dyn-trait.stderr | 2 +- .../ui/feature-gate-exclusive-range-pattern.stderr | 2 +- src/test/ui/feature-gate-extern_absolute_paths.stderr | 4 ++-- src/test/ui/feature-gate-extern_in_paths.stderr | 2 +- src/test/ui/feature-gate-extern_types.stderr | 2 +- src/test/ui/feature-gate-external_doc.stderr | 2 +- src/test/ui/feature-gate-fundamental.stderr | 2 +- src/test/ui/feature-gate-generators.stderr | 2 +- .../ui/feature-gate-generic_associated_types.stderr | 2 +- src/test/ui/feature-gate-generic_param_attrs.stderr | 2 +- src/test/ui/feature-gate-global_allocator.stderr | 2 +- src/test/ui/feature-gate-global_asm.stderr | 2 +- src/test/ui/feature-gate-i128_type.stderr | 2 +- src/test/ui/feature-gate-i128_type2.stderr | 4 ++-- src/test/ui/feature-gate-if_while_or_patterns.stderr | 2 +- src/test/ui/feature-gate-in_band_lifetimes.stderr | 2 +- src/test/ui/feature-gate-intrinsics.stderr | 2 +- src/test/ui/feature-gate-lang-items.stderr | 2 +- src/test/ui/feature-gate-link_args.stderr | 2 +- src/test/ui/feature-gate-link_cfg.stderr | 2 +- src/test/ui/feature-gate-link_llvm_intrinsics.stderr | 2 +- src/test/ui/feature-gate-linkage.stderr | 2 +- src/test/ui/feature-gate-linker-flavor.stderr | 2 +- src/test/ui/feature-gate-log_syntax.stderr | 2 +- src/test/ui/feature-gate-log_syntax2.stderr | 2 +- src/test/ui/feature-gate-macro-lifetime-matcher.stderr | 2 +- src/test/ui/feature-gate-macro-vis-matcher.stderr | 2 +- src/test/ui/feature-gate-macro_at_most_once_rep.stderr | 2 +- src/test/ui/feature-gate-main.stderr | 2 +- src/test/ui/feature-gate-match_default_bindings.stderr | 2 +- src/test/ui/feature-gate-may-dangle.stderr | 2 +- src/test/ui/feature-gate-naked_functions.stderr | 2 +- src/test/ui/feature-gate-needs-allocator.stderr | 2 +- src/test/ui/feature-gate-negate-unsigned.stderr | 2 +- src/test/ui/feature-gate-never_type.stderr | 2 +- src/test/ui/feature-gate-nll.stderr | 2 +- src/test/ui/feature-gate-no-debug.stderr | 2 +- src/test/ui/feature-gate-no_core.stderr | 2 +- src/test/ui/feature-gate-non_ascii_idents.stderr | 2 +- src/test/ui/feature-gate-non_exhaustive.stderr | 2 +- ...feature-gate-omit-gdb-pretty-printer-section.stderr | 2 +- src/test/ui/feature-gate-on-unimplemented.stderr | 2 +- src/test/ui/feature-gate-optin-builtin-traits.stderr | 2 +- .../ui/feature-gate-overlapping_marker_traits.stderr | 2 +- src/test/ui/feature-gate-pattern_parentheses.stderr | 2 +- src/test/ui/feature-gate-placement-expr.stderr | 2 +- src/test/ui/feature-gate-plugin.stderr | 2 +- src/test/ui/feature-gate-plugin_registrar.stderr | 2 +- src/test/ui/feature-gate-prelude_import.stderr | 2 +- src/test/ui/feature-gate-profiler-runtime.stderr | 2 +- src/test/ui/feature-gate-repr-simd.stderr | 2 +- src/test/ui/feature-gate-repr128.stderr | 2 +- src/test/ui/feature-gate-repr_transparent.stderr | 2 +- src/test/ui/feature-gate-rustc-attrs.stderr | 2 +- src/test/ui/feature-gate-rustc_const_unstable.stderr | 2 +- src/test/ui/feature-gate-sanitizer-runtime.stderr | 2 +- src/test/ui/feature-gate-simd.stderr | 2 +- src/test/ui/feature-gate-slice-patterns.stderr | 2 +- src/test/ui/feature-gate-start.stderr | 2 +- src/test/ui/feature-gate-static-nobundle.stderr | 2 +- src/test/ui/feature-gate-stmt_expr_attributes.stderr | 2 +- src/test/ui/feature-gate-target_feature.stderr | 2 +- src/test/ui/feature-gate-thread_local.stderr | 2 +- src/test/ui/feature-gate-trace_macros.stderr | 2 +- src/test/ui/feature-gate-type_ascription.stderr | 2 +- .../feature-gate-unboxed-closures-manual-impls.stderr | 2 +- .../feature-gate-unboxed-closures-method-calls.stderr | 2 +- .../ui/feature-gate-unboxed-closures-ufcs-calls.stderr | 2 +- src/test/ui/feature-gate-unboxed-closures.stderr | 2 +- src/test/ui/feature-gate-underscore-lifetimes.stderr | 2 +- src/test/ui/feature-gate-universal.stderr | 2 +- src/test/ui/feature-gate-unsized_tuple_coercion.stderr | 2 +- src/test/ui/feature-gate-untagged_unions.stderr | 2 +- src/test/ui/feature-gate-unwind-attributes.stderr | 2 +- src/test/ui/feature-gate-used.stderr | 2 +- .../ui/feature-gate/issue-43106-gating-of-bench.stderr | 2 +- .../feature-gate/issue-43106-gating-of-inline.stderr | 4 ++-- .../issue-43106-gating-of-macro_escape.stderr | 2 +- .../issue-43106-gating-of-proc_macro_derive.stderr | 2 +- .../issue-43106-gating-of-rustc_deprecated.stderr | 2 +- .../feature-gate/issue-43106-gating-of-stable.stderr | 2 +- .../ui/feature-gate/issue-43106-gating-of-test.stderr | 2 +- .../feature-gate/issue-43106-gating-of-unstable.stderr | 2 +- src/test/ui/fmt/send-sync.stderr | 2 +- src/test/ui/generator/auto-trait-regions.stderr | 4 ++-- src/test/ui/generator/borrowing.stderr | 2 +- src/test/ui/generator/dropck.stderr | 2 +- src/test/ui/generator/generator-with-nll.stderr | 2 +- src/test/ui/generator/issue-48048.stderr | 2 +- .../ui/generator/no-arguments-on-generators.stderr | 2 +- src/test/ui/generator/not-send-sync.stderr | 2 +- src/test/ui/generator/pattern-borrow.stderr | 2 +- .../ui/generator/ref-escapes-but-not-over-yield.stderr | 2 +- src/test/ui/generator/sized-yield.stderr | 2 +- src/test/ui/generator/unsafe-immovable.stderr | 2 +- src/test/ui/generator/yield-in-args.stderr | 2 +- src/test/ui/generator/yield-in-const.stderr | 4 ++-- src/test/ui/generator/yield-in-function.stderr | 2 +- src/test/ui/generator/yield-in-static.stderr | 4 ++-- src/test/ui/generator/yield-while-iterating.stderr | 4 ++-- .../ui/generator/yield-while-local-borrowed.stderr | 2 +- .../ui/generator/yield-while-ref-reborrowed.stderr | 2 +- .../ui/generic-type-less-params-with-defaults.stderr | 2 +- .../ui/generic-type-more-params-with-defaults.stderr | 2 +- src/test/ui/if-let-arm-types.stderr | 2 +- src/test/ui/impl-duplicate-methods.stderr | 2 +- src/test/ui/impl-trait/auto-trait-leak.stderr | 4 ++-- src/test/ui/impl-trait/equality.stderr | 4 ++-- src/test/ui/impl-trait/impl-trait-plus-priority.stderr | 2 +- .../issue-21659-show-relevant-trait-impls-3.stderr | 2 +- .../impl-trait/method-suggestion-no-duplication.stderr | 2 +- .../ui/impl-trait/no-method-suggested-traits.stderr | 2 +- src/test/ui/impl-trait/trait_type.stderr | 4 ++-- .../ui/impl-trait/universal-mismatched-type.stderr | 2 +- .../ui/impl-trait/universal-two-impl-traits.stderr | 2 +- src/test/ui/impl-trait/universal_wrong_bounds.stderr | 2 -- src/test/ui/impl-unused-rps-in-assoc-type.stderr | 2 +- src/test/ui/impl_trait_projections.stderr | 4 ++-- src/test/ui/imports/duplicate.stderr | 4 ++-- src/test/ui/imports/macro-paths.stderr | 4 ++-- src/test/ui/imports/macros.stderr | 4 ++-- src/test/ui/imports/shadow_builtin_macros.stderr | 2 +- src/test/ui/impossible_range.stderr | 2 +- src/test/ui/in-band-lifetimes/E0687.stderr | 2 +- src/test/ui/in-band-lifetimes/E0687_where.stderr | 2 +- src/test/ui/in-band-lifetimes/E0688.stderr | 2 +- src/test/ui/in-band-lifetimes/mismatched.stderr | 4 ++-- src/test/ui/in-band-lifetimes/mismatched_trait.stderr | 2 +- .../in-band-lifetimes/mismatched_trait_impl-2.stderr | 4 ++-- .../ui/in-band-lifetimes/mismatched_trait_impl.stderr | 2 +- src/test/ui/in-band-lifetimes/mut_while_borrow.stderr | 2 +- .../ui/in-band-lifetimes/no_in_band_in_struct.stderr | 2 +- .../no_introducing_in_band_in_locals.stderr | 2 +- src/test/ui/in-band-lifetimes/shadow.stderr | 2 +- src/test/ui/index-help.stderr | 2 +- src/test/ui/infinite-recursion-const-fn.stderr | 2 +- .../ui/interior-mutability/interior-mutability.stderr | 2 +- .../invalid-module-declaration.stderr | 2 +- src/test/ui/invalid-path-in-const.stderr | 2 +- src/test/ui/issue-10969.stderr | 2 +- src/test/ui/issue-11004.stderr | 2 +- src/test/ui/issue-11319.stderr | 2 +- src/test/ui/issue-12187-1.stderr | 2 +- src/test/ui/issue-12187-2.stderr | 2 +- src/test/ui/issue-12511.stderr | 2 +- src/test/ui/issue-13058.stderr | 4 ++-- src/test/ui/issue-14092.stderr | 2 +- src/test/ui/issue-15260.stderr | 2 +- src/test/ui/issue-15524.stderr | 2 +- src/test/ui/issue-17263.stderr | 4 ++-- src/test/ui/issue-17441.stderr | 2 +- src/test/ui/issue-18183.stderr | 2 +- src/test/ui/issue-18819.stderr | 2 +- src/test/ui/issue-19498.stderr | 2 +- src/test/ui/issue-19707.stderr | 2 +- src/test/ui/issue-19922.stderr | 2 +- src/test/ui/issue-20692.stderr | 2 +- src/test/ui/issue-21546.stderr | 2 +- src/test/ui/issue-21600.stderr | 2 +- src/test/ui/issue-21950.stderr | 4 ++-- src/test/ui/issue-22370.stderr | 2 +- src/test/ui/issue-22560.stderr | 4 ++-- src/test/ui/issue-22886.stderr | 2 +- src/test/ui/issue-22933-2.stderr | 2 +- src/test/ui/issue-23041.stderr | 2 +- src/test/ui/issue-23173.stderr | 2 +- src/test/ui/issue-23217.stderr | 2 +- src/test/ui/issue-23302-1.stderr | 2 +- src/test/ui/issue-23302-2.stderr | 2 +- src/test/ui/issue-23302-3.stderr | 2 +- src/test/ui/issue-23543.stderr | 2 +- src/test/ui/issue-23544.stderr | 2 +- src/test/ui/issue-23716.stderr | 2 +- src/test/ui/issue-24036.stderr | 2 +- src/test/ui/issue-24081.stderr | 2 +- src/test/ui/issue-24424.stderr | 2 +- src/test/ui/issue-25385.stderr | 2 +- src/test/ui/issue-25793.stderr | 2 +- src/test/ui/issue-25826.stderr | 2 +- src/test/ui/issue-26056.stderr | 2 +- src/test/ui/issue-26093.stderr | 2 +- src/test/ui/issue-26472.stderr | 2 +- src/test/ui/issue-26638.stderr | 2 +- src/test/ui/issue-26886.stderr | 2 +- src/test/ui/issue-27842.stderr | 2 +- src/test/ui/issue-27942.stderr | 2 +- src/test/ui/issue-2848.stderr | 2 +- src/test/ui/issue-28568.stderr | 2 +- src/test/ui/issue-28776.stderr | 2 +- src/test/ui/issue-28837.stderr | 2 +- src/test/ui/issue-28971.stderr | 2 +- src/test/ui/issue-29124.stderr | 2 +- src/test/ui/issue-29723.stderr | 2 +- src/test/ui/issue-3008-1.stderr | 2 +- src/test/ui/issue-3008-2.stderr | 2 +- src/test/ui/issue-30255.stderr | 2 +- src/test/ui/issue-30302.stderr | 1 + src/test/ui/issue-3044.stderr | 2 +- src/test/ui/issue-32326.stderr | 2 +- src/test/ui/issue-33525.stderr | 4 ++-- src/test/ui/issue-33941.stderr | 2 +- src/test/ui/issue-34047.stderr | 2 +- src/test/ui/issue-34209.stderr | 2 +- src/test/ui/issue-35139.stderr | 2 +- src/test/ui/issue-35241.stderr | 2 +- src/test/ui/issue-35675.stderr | 4 ++-- src/test/ui/issue-35869.stderr | 2 +- src/test/ui/issue-36163.stderr | 2 +- src/test/ui/issue-36400.stderr | 2 +- src/test/ui/issue-36708.stderr | 2 +- src/test/ui/issue-3779.stderr | 2 +- src/test/ui/issue-37884.stderr | 2 +- src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr | 2 +- src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr | 2 +- src/test/ui/issue-41652/issue_41652.stderr | 2 +- src/test/ui/issue-42106.stderr | 2 +- src/test/ui/issue-4335.stderr | 4 ++-- src/test/ui/issue-44023.stderr | 2 +- src/test/ui/issue-45157.stderr | 2 +- src/test/ui/issue-45697-1.stderr | 4 ++-- src/test/ui/issue-45697.stderr | 4 ++-- src/test/ui/issue-45730.stderr | 2 +- src/test/ui/issue-46112.stderr | 2 +- src/test/ui/issue-46332.stderr | 2 +- src/test/ui/issue-46471-1.stderr | 2 +- src/test/ui/issue-46471.stderr | 2 +- src/test/ui/issue-46472.stderr | 2 +- src/test/ui/issue-46983.stderr | 2 +- src/test/ui/issue-47377.stderr | 2 +- src/test/ui/issue-47380.stderr | 2 +- src/test/ui/issue-47511.stderr | 2 +- src/test/ui/issue-47623.stderr | 2 +- src/test/ui/issue-47706-trait.stderr | 4 ++-- src/test/ui/issue-47706.stderr | 2 +- src/test/ui/issue-48276.stderr | 2 +- src/test/ui/issue-4935.stderr | 2 +- src/test/ui/issue-5239-1.stderr | 2 +- src/test/ui/issue-6458-3.stderr | 2 +- src/test/ui/issue-6458-4.stderr | 2 +- src/test/ui/issue-6458.stderr | 2 +- src/test/ui/issue-7813.stderr | 2 +- ...ision-return-type-requires-explicit-lifetime.stderr | 2 +- .../42701_one_named_and_one_anonymous.stderr | 2 +- ...turn-one-existing-name-early-bound-in-struct.stderr | 2 +- .../ex1-return-one-existing-name-if-else-2.stderr | 2 +- .../ex1-return-one-existing-name-if-else-3.stderr | 2 +- ...eturn-one-existing-name-if-else-using-impl-2.stderr | 2 +- ...eturn-one-existing-name-if-else-using-impl-3.stderr | 2 +- ...-return-one-existing-name-if-else-using-impl.stderr | 2 +- .../ex1-return-one-existing-name-if-else.stderr | 2 +- ...return-one-existing-name-return-type-is-anon.stderr | 2 +- .../ex1-return-one-existing-name-self-is-anon.stderr | 2 +- .../ex1b-return-no-names-if-else.stderr | 2 +- .../ex2a-push-one-existing-name-2.stderr | 2 +- .../ex2a-push-one-existing-name-early-bound.stderr | 2 +- .../lifetime-errors/ex2a-push-one-existing-name.stderr | 2 +- .../lifetime-errors/ex2b-push-no-existing-names.stderr | 2 +- .../ex2c-push-inference-variable.stderr | 2 +- .../ex2d-push-inference-variable-2.stderr | 2 +- .../ex2e-push-inference-variable-3.stderr | 2 +- .../ui/lifetime-errors/ex3-both-anon-regions-2.stderr | 2 +- .../ui/lifetime-errors/ex3-both-anon-regions-3.stderr | 2 +- .../ex3-both-anon-regions-both-are-structs-2.stderr | 2 +- .../ex3-both-anon-regions-both-are-structs-3.stderr | 2 +- .../ex3-both-anon-regions-both-are-structs-4.stderr | 2 +- ...-regions-both-are-structs-earlybound-regions.stderr | 2 +- ...n-regions-both-are-structs-latebound-regions.stderr | 2 +- .../ex3-both-anon-regions-both-are-structs.stderr | 2 +- .../ex3-both-anon-regions-latebound-regions.stderr | 2 +- .../ex3-both-anon-regions-one-is-struct-2.stderr | 2 +- .../ex3-both-anon-regions-one-is-struct-3.stderr | 2 +- .../ex3-both-anon-regions-one-is-struct-4.stderr | 2 +- .../ex3-both-anon-regions-one-is-struct.stderr | 2 +- .../ex3-both-anon-regions-return-type-is-anon.stderr | 2 +- .../ex3-both-anon-regions-self-is-anon.stderr | 2 +- .../ex3-both-anon-regions-using-fn-items.stderr | 2 +- .../ex3-both-anon-regions-using-impl-items.stderr | 2 +- .../ex3-both-anon-regions-using-trait-objects.stderr | 2 +- .../ui/lifetime-errors/ex3-both-anon-regions.stderr | 2 +- .../liveness-assign-imm-local-notes.stderr | 2 +- src/test/ui/lifetimes/borrowck-let-suggestion.stderr | 2 +- .../lifetimes/lifetime-doesnt-live-long-enough.stderr | 4 ++-- src/test/ui/lint-forbid-attr.stderr | 2 +- src/test/ui/lint/outer-forbid.stderr | 2 +- src/test/ui/lint/use_suggestion_json.stderr | 10 +++++++++- src/test/ui/liveness-return-last-stmt-semi.stderr | 2 +- src/test/ui/loop-break-value-no-repeat.stderr | 2 +- src/test/ui/lub-glb/old-lub-glb-hr.stderr | 2 +- src/test/ui/lub-glb/old-lub-glb-object.stderr | 2 +- .../ui/macros/macro-backtrace-invalid-internals.stderr | 4 ++-- src/test/ui/macros/macro-backtrace-nested.stderr | 2 +- src/test/ui/macros/macro_path_as_generic_bound.stderr | 1 - src/test/ui/macros/span-covering-argument-1.stderr | 2 +- src/test/ui/main-wrong-location.stderr | 2 +- src/test/ui/method-call-err-msg.stderr | 4 ++-- src/test/ui/method-missing-call.stderr | 2 +- src/test/ui/mismatched_types/E0053.stderr | 2 +- src/test/ui/mismatched_types/E0409.stderr | 4 ++-- src/test/ui/mismatched_types/E0631.stderr | 2 +- src/test/ui/mismatched_types/abridged.stderr | 2 +- src/test/ui/mismatched_types/binops.stderr | 2 +- src/test/ui/mismatched_types/cast-rfc0401.stderr | 4 ++-- .../closure-arg-count-expected-type-issue-47244.stderr | 2 +- src/test/ui/mismatched_types/closure-arg-count.stderr | 2 +- .../mismatched_types/closure-arg-type-mismatch.stderr | 4 ++-- src/test/ui/mismatched_types/closure-mismatch.stderr | 4 ++-- src/test/ui/mismatched_types/const-fn-in-trait.stderr | 2 +- src/test/ui/mismatched_types/fn-variance-1.stderr | 2 +- .../ui/mismatched_types/for-loop-has-unit-body.stderr | 2 +- src/test/ui/mismatched_types/issue-19109.stderr | 2 +- src/test/ui/mismatched_types/issue-26480.stderr | 4 ++-- src/test/ui/mismatched_types/issue-35030.stderr | 2 +- src/test/ui/mismatched_types/issue-36053-2.stderr | 4 ++-- src/test/ui/mismatched_types/issue-38371.stderr | 4 ++-- src/test/ui/mismatched_types/main.stderr | 2 +- .../method-help-unsatisfied-bound.stderr | 2 +- .../ui/mismatched_types/overloaded-calls-bad.stderr | 4 ++-- .../mismatched_types/trait-bounds-cant-coerce.stderr | 2 +- .../trait-impl-fn-incompatibility.stderr | 2 +- .../unboxed-closures-vtable-mismatch.stderr | 2 +- src/test/ui/missing-items/issue-40221.stderr | 2 +- src/test/ui/missing-items/m2.stderr | 4 ++-- .../ui/missing-items/missing-type-parameter.stderr | 2 +- .../missing_non_modrs_mod/missing_non_modrs_mod.stderr | 2 +- src/test/ui/moves-based-on-type-block-bad.stderr | 2 +- src/test/ui/moves-based-on-type-match-bindings.stderr | 2 +- src/test/ui/moves-based-on-type-tuple.stderr | 2 +- src/test/ui/nested_impl_trait.stderr | 4 ++-- src/test/ui/nll/borrowed-local-error.stderr | 2 +- src/test/ui/nll/borrowed-match-issue-45045.stderr | 2 +- src/test/ui/nll/borrowed-referent-issue-38899.stderr | 2 +- src/test/ui/nll/borrowed-temporary-error.stderr | 2 +- src/test/ui/nll/borrowed-universal-error-2.stderr | 2 +- src/test/ui/nll/borrowed-universal-error.stderr | 2 +- src/test/ui/nll/capture-ref-in-struct.stderr | 2 +- .../ui/nll/closure-requirements/escape-argument.stderr | 2 +- .../closure-requirements/escape-upvar-nested.stderr | 2 +- .../nll/closure-requirements/escape-upvar-ref.stderr | 2 +- .../propagate-approximated-ref.stderr | 2 +- ...ted-shorter-to-static-comparing-against-free.stderr | 2 +- .../propagate-approximated-val.stderr | 2 +- .../propagate-from-trait-match.stderr | 2 +- .../region-lbr-anon-does-not-outlive-static.stderr | 2 +- .../region-lbr1-does-not-outlive-ebr2.stderr | 2 +- src/test/ui/nll/drop-no-may-dangle.stderr | 2 +- src/test/ui/nll/get_default.stderr | 2 +- src/test/ui/nll/guarantor-issue-46974.stderr | 4 ++-- src/test/ui/nll/issue-31567.stderr | 2 +- src/test/ui/nll/issue-47470.stderr | 2 +- ...aybe-initialized-drop-implicit-fragment-drop.stderr | 2 +- .../ui/nll/maybe-initialized-drop-with-fragment.stderr | 2 +- ...nitialized-drop-with-uninitialized-fragments.stderr | 2 +- src/test/ui/nll/maybe-initialized-drop.stderr | 2 +- src/test/ui/nll/return-ref-mut-issue-46557.stderr | 2 +- src/test/ui/nll/trait-associated-constant.stderr | 2 +- src/test/ui/nll/ty-outlives/impl-trait-captures.stderr | 2 +- src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr | 2 +- .../nll/ty-outlives/projection-implied-bounds.stderr | 2 +- .../ty-outlives/projection-no-regions-closure.stderr | 2 +- .../ui/nll/ty-outlives/projection-no-regions-fn.stderr | 2 +- .../ty-outlives/projection-one-region-closure.stderr | 2 +- .../projection-two-region-trait-bound-closure.stderr | 2 +- .../ty-param-closure-approximate-lower-bound.stderr | 2 +- .../ty-param-closure-outlives-from-return-type.stderr | 2 +- .../ty-param-closure-outlives-from-where-clause.stderr | 2 +- .../ty-outlives/ty-param-fn-body-nll-feature.stderr | 2 +- src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr | 2 +- src/test/ui/nll/ty-outlives/ty-param-fn.stderr | 2 +- src/test/ui/no-patterns-in-args.stderr | 4 ++-- src/test/ui/non-constant-expr-for-arr-len.stderr | 2 +- src/test/ui/non-exhaustive-pattern-witness.stderr | 2 +- src/test/ui/non_modrs_mods/non_modrs_mods.stderr | 2 +- src/test/ui/not-enough-arguments.stderr | 2 +- src/test/ui/numeric-fields.stderr | 4 ++-- src/test/ui/object-safety-associated-consts.stderr | 2 +- src/test/ui/object-safety-generics.stderr | 2 +- src/test/ui/object-safety-mentions-Self.stderr | 2 +- src/test/ui/object-safety-sized.stderr | 2 +- .../ui/object-safety-supertrait-mentions-Self.stderr | 2 +- src/test/ui/on-unimplemented/bad-annotation.stderr | 4 ++-- src/test/ui/on-unimplemented/multiple-impls.stderr | 2 +- src/test/ui/on-unimplemented/no-debug.stderr | 2 +- src/test/ui/on-unimplemented/on-impl.stderr | 2 +- src/test/ui/on-unimplemented/on-trait.stderr | 2 +- src/test/ui/on-unimplemented/slice-index.stderr | 2 +- src/test/ui/partialeq_help.stderr | 2 +- src/test/ui/pat-slice-old-style.stderr | 2 +- src/test/ui/qualified-path-params-2.stderr | 4 ++-- src/test/ui/reachable/expr_unary.stderr | 2 +- src/test/ui/recursive-requirements.stderr | 2 +- .../ui/region-borrow-params-issue-29793-small.stderr | 4 ++-- src/test/ui/regions-fn-subtyping-return-static.stderr | 2 +- src/test/ui/regions-nested-fns-2.stderr | 2 +- src/test/ui/resolve-conflict-item-vs-import.stderr | 2 +- src/test/ui/resolve-inconsistent-names.stderr | 2 +- src/test/ui/resolve/enums-are-namespaced-xc.stderr | 4 ++-- src/test/ui/resolve/issue-14254.stderr | 4 ++-- src/test/ui/resolve/issue-16058.stderr | 2 +- src/test/ui/resolve/issue-17518.stderr | 2 +- src/test/ui/resolve/issue-18252.stderr | 2 +- src/test/ui/resolve/issue-19452.stderr | 2 +- src/test/ui/resolve/issue-21221-1.stderr | 2 -- src/test/ui/resolve/issue-21221-2.stderr | 2 -- src/test/ui/resolve/issue-21221-3.stderr | 1 - src/test/ui/resolve/issue-21221-4.stderr | 1 - src/test/ui/resolve/issue-23305.stderr | 2 +- src/test/ui/resolve/issue-2356.stderr | 4 ++-- src/test/ui/resolve/issue-24968.stderr | 2 +- src/test/ui/resolve/issue-33876.stderr | 2 +- src/test/ui/resolve/issue-3907-2.stderr | 2 +- src/test/ui/resolve/issue-3907.stderr | 1 - src/test/ui/resolve/issue-39226.stderr | 2 +- src/test/ui/resolve/issue-5035-2.stderr | 2 +- src/test/ui/resolve/issue-5035.stderr | 2 -- src/test/ui/resolve/issue-6702.stderr | 2 +- src/test/ui/resolve/levenshtein.stderr | 4 ++-- src/test/ui/resolve/name-clash-nullary.stderr | 2 +- src/test/ui/resolve/privacy-enum-ctor.stderr | 4 ++-- src/test/ui/resolve/privacy-struct-ctor.stderr | 4 ++-- src/test/ui/resolve/resolve-assoc-suggestions.stderr | 4 ++-- src/test/ui/resolve/resolve-hint-macro.stderr | 2 +- .../ui/resolve/resolve-speculative-adjustment.stderr | 2 +- .../suggest-path-instead-of-mod-dot-item.stderr | 4 ++-- src/test/ui/resolve/token-error-correct-2.stderr | 2 +- src/test/ui/resolve/token-error-correct-3.stderr | 4 ++-- src/test/ui/resolve/tuple-struct-alias.stderr | 4 ++-- .../unboxed-closure-sugar-nonexistent-trait.stderr | 2 -- .../ui/resolve/unresolved_static_type_field.stderr | 2 +- src/test/ui/resolve/use_suggestion_placement.stderr | 4 ++-- src/test/ui/rfc-2005-default-binding-mode/const.stderr | 2 +- src/test/ui/rfc-2005-default-binding-mode/enum.stderr | 2 +- .../rfc-2005-default-binding-mode/explicit-mut.stderr | 2 +- src/test/ui/rfc-2005-default-binding-mode/for.stderr | 2 +- .../issue-44912-or.stderr | 2 +- src/test/ui/rfc-2005-default-binding-mode/lit.stderr | 2 +- .../no-double-error.stderr | 2 +- src/test/ui/rfc-2005-default-binding-mode/slice.stderr | 2 +- .../ui/rfc-2005-default-binding-mode/suggestion.stderr | 2 +- .../construct_with_other_type.stderr | 2 +- ...generic_associated_type_undeclared_lifetimes.stderr | 4 ++-- .../rfc1598-generic-associated-types/iterable.stderr | 2 +- .../pointer_family.stderr | 2 +- .../streaming_iterator.stderr | 2 +- src/test/ui/self-impl.stderr | 2 +- src/test/ui/shadowed-lifetime.stderr | 2 +- src/test/ui/shadowed-type-parameter.stderr | 2 +- src/test/ui/span/E0046.stderr | 2 +- src/test/ui/span/E0057.stderr | 2 +- src/test/ui/span/E0072.stderr | 2 +- src/test/ui/span/E0204.stderr | 2 +- src/test/ui/span/E0493.stderr | 2 +- src/test/ui/span/E0535.stderr | 2 +- src/test/ui/span/E0536.stderr | 2 +- src/test/ui/span/E0537.stderr | 2 +- .../borrowck-borrow-overloaded-auto-deref-mut.stderr | 4 ++-- .../span/borrowck-borrow-overloaded-deref-mut.stderr | 2 +- .../ui/span/borrowck-call-is-borrow-issue-12224.stderr | 4 ++-- .../borrowck-call-method-from-mut-aliasable.stderr | 2 +- src/test/ui/span/borrowck-fn-in-const-b.stderr | 2 +- .../ui/span/borrowck-let-suggestion-suffixes.stderr | 2 +- src/test/ui/span/borrowck-object-mutability.stderr | 2 +- src/test/ui/span/borrowck-ref-into-rvalue.stderr | 2 +- src/test/ui/span/coerce-suggestions.stderr | 2 +- src/test/ui/span/destructor-restrictions.stderr | 2 +- src/test/ui/span/dropck-object-cycle.stderr | 2 +- src/test/ui/span/dropck_arr_cycle_checked.stderr | 2 +- src/test/ui/span/dropck_direct_cycle_with_drop.stderr | 2 +- src/test/ui/span/dropck_misc_variants.stderr | 2 +- src/test/ui/span/dropck_vec_cycle_checked.stderr | 2 +- src/test/ui/span/gated-features-attr-spans.stderr | 2 +- src/test/ui/span/impl-wrong-item-for-trait.stderr | 4 ++-- src/test/ui/span/issue-11925.stderr | 2 +- src/test/ui/span/issue-15480.stderr | 2 +- .../issue-23338-locals-die-before-temps-of-body.stderr | 2 +- src/test/ui/span/issue-23729.stderr | 2 +- src/test/ui/span/issue-23827.stderr | 2 +- src/test/ui/span/issue-24356.stderr | 2 +- ...ssue-24805-dropck-child-has-items-via-parent.stderr | 2 +- .../ui/span/issue-24805-dropck-trait-has-items.stderr | 2 +- src/test/ui/span/issue-24895-copy-clone-dropck.stderr | 2 +- src/test/ui/span/issue-25199.stderr | 2 +- src/test/ui/span/issue-26656.stderr | 2 +- src/test/ui/span/issue-27522.stderr | 2 +- src/test/ui/span/issue-29106.stderr | 2 +- src/test/ui/span/issue-29595.stderr | 2 +- src/test/ui/span/issue-33884.stderr | 2 +- src/test/ui/span/issue-34264.stderr | 4 ++-- src/test/ui/span/issue-35987.stderr | 2 -- src/test/ui/span/issue-36530.stderr | 2 +- src/test/ui/span/issue-36537.stderr | 2 +- src/test/ui/span/issue-37767.stderr | 2 +- src/test/ui/span/issue-39018.stderr | 2 +- src/test/ui/span/issue-39698.stderr | 2 +- src/test/ui/span/issue-40157.stderr | 2 +- .../ui/span/issue-42234-unknown-receiver-type.stderr | 2 +- src/test/ui/span/issue-7575.stderr | 2 +- src/test/ui/span/issue28498-reject-ex1.stderr | 2 +- .../ui/span/issue28498-reject-lifetime-param.stderr | 2 +- src/test/ui/span/issue28498-reject-passed-to-fn.stderr | 2 +- src/test/ui/span/issue28498-reject-trait-bound.stderr | 2 +- src/test/ui/span/missing-unit-argument.stderr | 2 +- src/test/ui/span/move-closure.stderr | 2 +- src/test/ui/span/multiline-span-E0072.stderr | 2 +- src/test/ui/span/multiline-span-simple.stderr | 2 +- src/test/ui/span/mut-arg-hint.stderr | 2 +- src/test/ui/span/mut-ptr-cant-outlive-ref.stderr | 2 +- src/test/ui/span/non-existing-module-import.stderr | 2 +- src/test/ui/span/pub-struct-field.stderr | 2 +- src/test/ui/span/range-2.stderr | 2 +- src/test/ui/span/recursive-type-field.stderr | 2 +- .../ui/span/regionck-unboxed-closure-lifetimes.stderr | 2 +- .../span/regions-close-over-borrowed-ref-in-obj.stderr | 2 +- .../ui/span/regions-close-over-type-parameter-2.stderr | 2 +- .../ui/span/regions-escape-loop-via-variable.stderr | 2 +- src/test/ui/span/regions-escape-loop-via-vec.stderr | 4 ++-- .../span/regions-infer-borrow-scope-within-loop.stderr | 2 +- .../ui/span/send-is-not-static-ensures-scoping.stderr | 2 +- src/test/ui/span/send-is-not-static-std-sync-2.stderr | 2 +- src/test/ui/span/send-is-not-static-std-sync.stderr | 4 ++-- src/test/ui/span/slice-borrow.stderr | 2 +- src/test/ui/span/suggestion-non-ascii.stderr | 2 +- src/test/ui/span/type-binding.stderr | 2 +- src/test/ui/span/typo-suggestion.stderr | 2 +- .../ui/span/vec-must-not-hide-type-from-dropck.stderr | 2 +- src/test/ui/span/vec_refs_data_with_early_death.stderr | 2 +- src/test/ui/span/wf-method-late-bound-regions.stderr | 2 +- src/test/ui/specialization-feature-gate-default.stderr | 2 +- src/test/ui/specialization-feature-gate-overlap.stderr | 2 +- src/test/ui/static-lifetime.stderr | 2 +- src/test/ui/str-concat-on-double-ref.stderr | 2 +- src/test/ui/str-lit-type-mismatch.stderr | 2 +- src/test/ui/struct-fields-decl-dupe.stderr | 2 +- src/test/ui/struct-fields-hints-no-dupe.stderr | 2 +- src/test/ui/struct-fields-hints.stderr | 2 +- src/test/ui/struct-fields-too-many.stderr | 2 +- src/test/ui/struct-path-self-type-mismatch.stderr | 2 +- src/test/ui/suggest-private-fields.stderr | 2 +- .../closure-immutable-outer-variable.stderr | 2 +- .../confuse-field-and-method/issue-18343.stderr | 2 +- .../confuse-field-and-method/issue-2392.stderr | 2 +- .../confuse-field-and-method/issue-32128.stderr | 2 +- .../confuse-field-and-method/issue-33784.stderr | 2 +- .../confuse-field-and-method/private-field.stderr | 2 +- src/test/ui/suggestions/conversion-methods.stderr | 2 +- .../suggestions/dont-suggest-dereference-on-arg.stderr | 2 +- .../dont-suggest-private-trait-method.stderr | 2 +- src/test/ui/suggestions/extern-crate-rename.stderr | 2 +- .../ui/suggestions/fn-closure-mutable-capture.stderr | 2 +- src/test/ui/suggestions/for-c-in-str.stderr | 2 +- .../issue-32354-suggest-import-rename.stderr | 2 +- .../ui/suggestions/issue-43420-no-over-suggest.stderr | 2 +- ...ad-extern-crate-rename-suggestion-formatting.stderr | 2 +- ...sue-46756-consider-borrowing-cast-or-binexpr.stderr | 2 +- .../method-on-ambiguous-numeric-type.stderr | 2 +- src/test/ui/suggestions/numeric-cast-2.stderr | 2 +- src/test/ui/suggestions/numeric-cast.stderr | 2 +- src/test/ui/suggestions/return-type.stderr | 2 +- src/test/ui/suggestions/str-array-assignment.stderr | 4 ++-- src/test/ui/suggestions/suggest-labels.stderr | 2 +- src/test/ui/suggestions/suggest-methods.stderr | 2 +- src/test/ui/suggestions/try-on-option.stderr | 2 +- src/test/ui/suggestions/try-operator-on-main.stderr | 2 +- .../type-ascription-instead-of-initializer.stderr | 2 +- .../ui/suggestions/type-ascription-with-fn-call.stderr | 2 +- src/test/ui/svh-change-lit.stderr | 2 +- src/test/ui/svh-change-significant-cfg.stderr | 2 +- src/test/ui/svh-change-trait-bound.stderr | 2 +- src/test/ui/svh-change-type-arg.stderr | 2 +- src/test/ui/svh-change-type-ret.stderr | 2 +- src/test/ui/svh-change-type-static.stderr | 2 +- src/test/ui/svh-use-trait.stderr | 2 +- src/test/ui/switched-expectations.stderr | 2 +- src/test/ui/token/issue-10636-2.stderr | 2 +- src/test/ui/token/issue-15980.stderr | 2 +- src/test/ui/token/issue-41155.stderr | 4 ++-- src/test/ui/trait-alias.stderr | 2 +- src/test/ui/trait-duplicate-methods.stderr | 2 +- src/test/ui/trait-method-private.stderr | 2 +- src/test/ui/trait-safety-fn-body.stderr | 2 +- src/test/ui/trait-suggest-where-clause.stderr | 2 +- .../ui/traits-multidispatch-convert-ambig-dest.stderr | 2 +- src/test/ui/transmute/main.stderr | 2 +- .../transmute-from-fn-item-types-error.stderr | 4 ++-- src/test/ui/transmute/transmute-type-parameters.stderr | 2 +- src/test/ui/type-annotation-needed.stderr | 2 +- src/test/ui/type-check-defaults.stderr | 2 +- src/test/ui/type-check/assignment-in-if.stderr | 2 +- .../ui/type-check/cannot_infer_local_or_array.stderr | 2 +- .../ui/type-check/cannot_infer_local_or_vec.stderr | 2 +- .../cannot_infer_local_or_vec_in_tuples.stderr | 2 +- src/test/ui/type-check/issue-22897.stderr | 2 +- src/test/ui/type-check/issue-40294.stderr | 2 +- src/test/ui/type-check/issue-41314.stderr | 4 ++-- src/test/ui/type-check/missing_trait_impl.stderr | 2 +- src/test/ui/type-check/unknown_type_for_closure.stderr | 2 +- src/test/ui/type-recursive.stderr | 2 +- .../ui/typeck-builtin-bound-type-parameters.stderr | 4 ++-- src/test/ui/typeck_type_placeholder_item.stderr | 2 +- src/test/ui/typeck_type_placeholder_lifetime_1.stderr | 2 +- src/test/ui/typeck_type_placeholder_lifetime_2.stderr | 2 +- src/test/ui/ui-testing-optout.stderr | 2 +- src/test/ui/unboxed-closure-no-cyclic-sig.stderr | 2 +- src/test/ui/unboxed-closure-sugar-wrong-trait.stderr | 4 ++-- ...-closures-infer-fn-once-move-from-projection.stderr | 2 +- src/test/ui/unconstrained-none.stderr | 2 +- src/test/ui/unconstrained-ref.stderr | 2 +- src/test/ui/union/union-derive-eq.stderr | 2 +- src/test/ui/union/union-fields-2.stderr | 4 ++-- src/test/ui/union/union-sized-field.stderr | 2 +- src/test/ui/union/union-suggest-field.stderr | 4 ++-- src/test/ui/unknown-language-item.stderr | 2 +- src/test/ui/unsafe-const-fn.stderr | 2 +- src/test/ui/unsized-enum2.stderr | 2 +- src/test/ui/use-mod.stderr | 4 ++-- src/test/ui/use-nested-groups-error.stderr | 2 +- src/test/ui/variadic-ffi-3.stderr | 4 ++-- src/test/ui/variance-unused-type-param.stderr | 2 +- src/test/ui/vector-no-ann.stderr | 2 +- 1044 files changed, 1153 insertions(+), 1163 deletions(-) diff --git a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr index ac26b5212ecb..c03ee7f983f5 100644 --- a/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr +++ b/src/test/ui-fulldeps/lint-plugin-forbid-attrs.stderr @@ -21,4 +21,4 @@ LL | #[allow(test_lint)] error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0453" +For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui-fulldeps/proc-macro/signature.stderr b/src/test/ui-fulldeps/proc-macro/signature.stderr index dad403ccf3a6..fdd10c3c5b90 100644 --- a/src/test/ui-fulldeps/proc-macro/signature.stderr +++ b/src/test/ui-fulldeps/proc-macro/signature.stderr @@ -12,4 +12,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index ff31595ee9ba..82f527f8cca8 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -154,4 +154,4 @@ LL | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &() error: aborting due to 11 previous errors -If you want more information on this error, try using "rustc --explain E0631" +For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/arbitrary-self-types-not-object-safe.stderr index ba240c8d5115..b3f9cbc587ba 100644 --- a/src/test/ui/arbitrary-self-types-not-object-safe.stderr +++ b/src/test/ui/arbitrary-self-types-not-object-safe.stderr @@ -17,4 +17,4 @@ LL | let x = Box::new(5usize) as Box; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/asm-out-assign-imm.stderr b/src/test/ui/asm-out-assign-imm.stderr index 16df627578e9..4ec758b97f2d 100644 --- a/src/test/ui/asm-out-assign-imm.stderr +++ b/src/test/ui/asm-out-assign-imm.stderr @@ -9,4 +9,4 @@ LL | asm!("mov $1, $0" : "=r"(x) : "r"(5)); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0384" +For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-const-impl-wrong-lifetime.stderr index e0a9653423fb..d800f4c727d7 100644 --- a/src/test/ui/associated-const-impl-wrong-lifetime.stderr +++ b/src/test/ui/associated-const-impl-wrong-lifetime.stderr @@ -15,4 +15,4 @@ LL | impl<'a> Foo for &'a () { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/associated-const-impl-wrong-type.stderr b/src/test/ui/associated-const-impl-wrong-type.stderr index 6c2f2600acc3..cfccacaee282 100644 --- a/src/test/ui/associated-const-impl-wrong-type.stderr +++ b/src/test/ui/associated-const-impl-wrong-type.stderr @@ -9,4 +9,4 @@ LL | const BAR: i32 = -1; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0326" +For more information about this error, try `rustc --explain E0326`. diff --git a/src/test/ui/associated-type-projection-from-multiple-supertraits.stderr b/src/test/ui/associated-type-projection-from-multiple-supertraits.stderr index 3b732ed39331..7a10b6d021f5 100644 --- a/src/test/ui/associated-type-projection-from-multiple-supertraits.stderr +++ b/src/test/ui/associated-type-projection-from-multiple-supertraits.stderr @@ -42,5 +42,5 @@ LL | fn paint(c: C, d: C::Color) { error: aborting due to 4 previous errors -You've got a few errors: E0191, E0221 -If you want more information on an error, try using "rustc --explain E0191" +Some errors occurred: E0191, E0221. +For more information about an error, try `rustc --explain E0191`. diff --git a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr index f69b0af71f62..7924ab744440 100644 --- a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr +++ b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr @@ -6,4 +6,4 @@ LL | r = r + a; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-types-in-ambiguous-context.stderr b/src/test/ui/associated-types-in-ambiguous-context.stderr index ff5c45e797e5..c45873ffd530 100644 --- a/src/test/ui/associated-types-in-ambiguous-context.stderr +++ b/src/test/ui/associated-types-in-ambiguous-context.stderr @@ -24,4 +24,4 @@ LL | fn grab(&self) -> Grab::Value; error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0223" +For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/attr-usage-repr.stderr b/src/test/ui/attr-usage-repr.stderr index 03c6f599b6c7..1f3b358545bd 100644 --- a/src/test/ui/attr-usage-repr.stderr +++ b/src/test/ui/attr-usage-repr.stderr @@ -40,4 +40,4 @@ LL | enum ESimd { A, B } error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0517" +For more information about this error, try `rustc --explain E0517`. diff --git a/src/test/ui/augmented-assignments.stderr b/src/test/ui/augmented-assignments.stderr index e04dc2f72a30..953af813c382 100644 --- a/src/test/ui/augmented-assignments.stderr +++ b/src/test/ui/augmented-assignments.stderr @@ -20,5 +20,5 @@ LL | x; //~ value moved here error: aborting due to 2 previous errors -You've got a few errors: E0382, E0596 -If you want more information on an error, try using "rustc --explain E0382" +Some errors occurred: E0382, E0596. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/binary-op-on-double-ref.stderr b/src/test/ui/binary-op-on-double-ref.stderr index b6c502b90b58..07aa3bfe40de 100644 --- a/src/test/ui/binary-op-on-double-ref.stderr +++ b/src/test/ui/binary-op-on-double-ref.stderr @@ -9,4 +9,4 @@ LL | x % 2 == 0 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0369" +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/blind-item-item-shadow.stderr b/src/test/ui/blind-item-item-shadow.stderr index f02dd6b3e98f..240ea6061b97 100644 --- a/src/test/ui/blind-item-item-shadow.stderr +++ b/src/test/ui/blind-item-item-shadow.stderr @@ -15,4 +15,4 @@ LL | use foo::foo as other_foo; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0255" +For more information about this error, try `rustc --explain E0255`. diff --git a/src/test/ui/block-result/block-must-not-have-result-do.stderr b/src/test/ui/block-result/block-must-not-have-result-do.stderr index 242906ca5cb4..d864d767957d 100644 --- a/src/test/ui/block-result/block-must-not-have-result-do.stderr +++ b/src/test/ui/block-result/block-must-not-have-result-do.stderr @@ -9,4 +9,4 @@ LL | true //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/block-must-not-have-result-res.stderr b/src/test/ui/block-result/block-must-not-have-result-res.stderr index ca730927c880..005a3ab9b5df 100644 --- a/src/test/ui/block-result/block-must-not-have-result-res.stderr +++ b/src/test/ui/block-result/block-must-not-have-result-res.stderr @@ -11,4 +11,4 @@ LL | true //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/block-must-not-have-result-while.stderr b/src/test/ui/block-result/block-must-not-have-result-while.stderr index 1a4852a4541a..a003ae871cad 100644 --- a/src/test/ui/block-result/block-must-not-have-result-while.stderr +++ b/src/test/ui/block-result/block-must-not-have-result-while.stderr @@ -9,4 +9,4 @@ LL | true //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr index 6fa892e10e75..a0855c317379 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -28,4 +28,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr index 8fad1c4de4a1..e9cd72812347 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -15,4 +15,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr index 7f39f53d6f99..888ee5a2d19a 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -31,4 +31,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/issue-13624.stderr b/src/test/ui/block-result/issue-13624.stderr index 0df7cf43c351..e54e22522f25 100644 --- a/src/test/ui/block-result/issue-13624.stderr +++ b/src/test/ui/block-result/issue-13624.stderr @@ -20,4 +20,4 @@ LL | a::Enum::EnumStructVariant { x, y, z } => { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/issue-20862.stderr b/src/test/ui/block-result/issue-20862.stderr index 238edb765ac1..990fb404c946 100644 --- a/src/test/ui/block-result/issue-20862.stderr +++ b/src/test/ui/block-result/issue-20862.stderr @@ -17,5 +17,5 @@ LL | let x = foo(5)(2); error: aborting due to 2 previous errors -You've got a few errors: E0308, E0618 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0618. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/issue-22645.stderr b/src/test/ui/block-result/issue-22645.stderr index 03d9d03371ee..c94dd7086266 100644 --- a/src/test/ui/block-result/issue-22645.stderr +++ b/src/test/ui/block-result/issue-22645.stderr @@ -22,5 +22,5 @@ LL | b + 3 //~ ERROR E0277 error: aborting due to 2 previous errors -You've got a few errors: E0277, E0308 -If you want more information on an error, try using "rustc --explain E0277" +Some errors occurred: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/block-result/issue-3563.stderr b/src/test/ui/block-result/issue-3563.stderr index af0e25ab18a9..c4dee857574b 100644 --- a/src/test/ui/block-result/issue-3563.stderr +++ b/src/test/ui/block-result/issue-3563.stderr @@ -8,4 +8,4 @@ LL | || self.b() error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/block-result/issue-5500.stderr b/src/test/ui/block-result/issue-5500.stderr index 74379809de0d..27018b5da7bd 100644 --- a/src/test/ui/block-result/issue-5500.stderr +++ b/src/test/ui/block-result/issue-5500.stderr @@ -11,4 +11,4 @@ LL | &panic!() error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/block-result/unexpected-return-on-unit.stderr b/src/test/ui/block-result/unexpected-return-on-unit.stderr index 10a8814a7e54..585cfb3d0d35 100644 --- a/src/test/ui/block-result/unexpected-return-on-unit.stderr +++ b/src/test/ui/block-result/unexpected-return-on-unit.stderr @@ -17,4 +17,4 @@ LL | fn bar() -> usize { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/bogus-tag.stderr b/src/test/ui/bogus-tag.stderr index 76284f3b71b6..f9917b07f070 100644 --- a/src/test/ui/bogus-tag.stderr +++ b/src/test/ui/bogus-tag.stderr @@ -9,4 +9,4 @@ LL | color::hsl(h, s, l) => { println!("hsl"); } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.stderr index 7bea41b2209e..5bf1fc081786 100644 --- a/src/test/ui/borrowck/borrowck-box-insensitivity.stderr +++ b/src/test/ui/borrowck/borrowck-box-insensitivity.stderr @@ -161,5 +161,5 @@ LL | } error: aborting due to 16 previous errors -You've got a few errors: E0382, E0502, E0503, E0505 -If you want more information on an error, try using "rustc --explain E0382" +Some errors occurred: E0382, E0502, E0503, E0505. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr index 7205b48399a2..c739165ddbd3 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr @@ -150,4 +150,4 @@ LL | } error: aborting due to 10 previous errors -If you want more information on this error, try using "rustc --explain E0499" +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr index 98176cce508a..eb1fa53d7558 100644 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr @@ -12,4 +12,4 @@ LL | spawn(move || books.push(4)); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0373" +For more information about this error, try `rustc --explain E0373`. diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr index 5de31c3ac357..1343c0a1f5b7 100644 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr @@ -12,4 +12,4 @@ LL | Box::new(move || books.push(4)) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0373" +For more information about this error, try `rustc --explain E0373`. diff --git a/src/test/ui/borrowck/borrowck-in-static.stderr b/src/test/ui/borrowck/borrowck-in-static.stderr index 989322662e86..356fad07666e 100644 --- a/src/test/ui/borrowck/borrowck-in-static.stderr +++ b/src/test/ui/borrowck/borrowck-in-static.stderr @@ -8,4 +8,4 @@ LL | Box::new(|| x) //~ ERROR cannot move out of captured outer variable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0507" +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/borrowck-move-error-with-note.stderr b/src/test/ui/borrowck/borrowck-move-error-with-note.stderr index acc78f4ab329..81ed058e47f4 100644 --- a/src/test/ui/borrowck/borrowck-move-error-with-note.stderr +++ b/src/test/ui/borrowck/borrowck-move-error-with-note.stderr @@ -34,5 +34,5 @@ LL | n => { error: aborting due to 3 previous errors -You've got a few errors: E0507, E0509 -If you want more information on an error, try using "rustc --explain E0507" +Some errors occurred: E0507, E0509. +For more information about an error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr index 49d5daa543bb..c4051e5a2556 100644 --- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr @@ -15,4 +15,4 @@ LL | | Foo { string: b }] => { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0508" +For more information about this error, try `rustc --explain E0508`. diff --git a/src/test/ui/borrowck/borrowck-reinit.stderr b/src/test/ui/borrowck/borrowck-reinit.stderr index a2fbe5ab9cd5..654afa421868 100644 --- a/src/test/ui/borrowck/borrowck-reinit.stderr +++ b/src/test/ui/borrowck/borrowck-reinit.stderr @@ -20,4 +20,4 @@ LL | let _ = (1,x); //~ ERROR use of moved value: `x` (Ast) error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr b/src/test/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr index 01899446f48f..648ee1dff785 100644 --- a/src/test/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr +++ b/src/test/ui/borrowck/borrowck-report-with-custom-diagnostic.stderr @@ -36,5 +36,5 @@ LL | }; error: aborting due to 3 previous errors -You've got a few errors: E0499, E0502 -If you want more information on an error, try using "rustc --explain E0499" +Some errors occurred: E0499, E0502. +For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr index 3d9fbc800385..e11702df80a9 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -80,5 +80,5 @@ LL | let a = vec[0]; //~ ERROR cannot move out error: aborting due to 8 previous errors -You've got a few errors: E0506, E0508 -If you want more information on an error, try using "rustc --explain E0506" +Some errors occurred: E0506, E0508. +For more information about an error, try `rustc --explain E0506`. diff --git a/src/test/ui/borrowck/immutable-arg.stderr b/src/test/ui/borrowck/immutable-arg.stderr index 34de3ca19a3c..b7506849b817 100644 --- a/src/test/ui/borrowck/immutable-arg.stderr +++ b/src/test/ui/borrowck/immutable-arg.stderr @@ -16,4 +16,4 @@ LL | _x = 4; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0384" +For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr index f0ee6b31f736..39525d787b1f 100644 --- a/src/test/ui/borrowck/issue-41962.stderr +++ b/src/test/ui/borrowck/issue-41962.stderr @@ -54,4 +54,4 @@ LL | if let Some(thing) = maybe { error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.stderr b/src/test/ui/borrowck/mut-borrow-in-loop.stderr index 9b777246861f..cda59d3bc68b 100644 --- a/src/test/ui/borrowck/mut-borrow-in-loop.stderr +++ b/src/test/ui/borrowck/mut-borrow-in-loop.stderr @@ -27,4 +27,4 @@ LL | } error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0499" +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/mut-borrow-outside-loop.stderr b/src/test/ui/borrowck/mut-borrow-outside-loop.stderr index 583f97b6cdfd..80a3ba4493c5 100644 --- a/src/test/ui/borrowck/mut-borrow-outside-loop.stderr +++ b/src/test/ui/borrowck/mut-borrow-outside-loop.stderr @@ -21,4 +21,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0499" +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 2fe3a45b76d4..b58dbd1e4d1c 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -46,5 +46,5 @@ LL | fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) { error: aborting due to 4 previous errors -You've got a few errors: E0195, E0276, E0308 -If you want more information on an error, try using "rustc --explain E0195" +Some errors occurred: E0195, E0276, E0308. +For more information about an error, try `rustc --explain E0195`. diff --git a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr index d07bdab087cb..f2f8ae8c08c2 100644 --- a/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr +++ b/src/test/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr @@ -9,4 +9,4 @@ LL | y.into_iter(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0507" +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/cast-as-bool.stderr b/src/test/ui/cast-as-bool.stderr index 1c60bc44d90f..050a18ec9d3e 100644 --- a/src/test/ui/cast-as-bool.stderr +++ b/src/test/ui/cast-as-bool.stderr @@ -8,4 +8,4 @@ LL | let u = 5 as bool; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0054" +For more information about this error, try `rustc --explain E0054`. diff --git a/src/test/ui/cast-errors-issue-43825.stderr b/src/test/ui/cast-errors-issue-43825.stderr index 3418472feafc..6dbbadde5c6f 100644 --- a/src/test/ui/cast-errors-issue-43825.stderr +++ b/src/test/ui/cast-errors-issue-43825.stderr @@ -6,4 +6,4 @@ LL | let error = error; //~ ERROR cannot find value `error` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/cast-rfc0401-2.stderr b/src/test/ui/cast-rfc0401-2.stderr index e0c39d84c193..f7ffa2459597 100644 --- a/src/test/ui/cast-rfc0401-2.stderr +++ b/src/test/ui/cast-rfc0401-2.stderr @@ -8,4 +8,4 @@ LL | let _ = 3 as bool; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0054" +For more information about this error, try `rustc --explain E0054`. diff --git a/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr b/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr index b2497dfeb287..67c33740f196 100644 --- a/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr +++ b/src/test/ui/cast-to-unsized-trait-object-suggestion.stderr @@ -16,4 +16,4 @@ LL | Box::new(1) as Send; //~ ERROR cast to unsized error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0620" +For more information about this error, try `rustc --explain E0620`. diff --git a/src/test/ui/casts-differing-anon.stderr b/src/test/ui/casts-differing-anon.stderr index c5fbbbc0e9eb..acbff4f73c39 100644 --- a/src/test/ui/casts-differing-anon.stderr +++ b/src/test/ui/casts-differing-anon.stderr @@ -8,4 +8,4 @@ LL | b_raw = f_raw as *mut _; //~ ERROR is invalid error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0606" +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/casts-issue-46365.stderr b/src/test/ui/casts-issue-46365.stderr index 138388f29765..08ba5e4b3210 100644 --- a/src/test/ui/casts-issue-46365.stderr +++ b/src/test/ui/casts-issue-46365.stderr @@ -6,4 +6,4 @@ LL | ipsum: Ipsum //~ ERROR cannot find type `Ipsum` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0412" +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/changing-crates.stderr b/src/test/ui/changing-crates.stderr index 436335aa917d..d8de685c7d7a 100644 --- a/src/test/ui/changing-crates.stderr +++ b/src/test/ui/changing-crates.stderr @@ -11,4 +11,4 @@ LL | extern crate b; //~ ERROR: found possibly newer version of crate `a` which error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/check_match/issue-35609.stderr b/src/test/ui/check_match/issue-35609.stderr index 3768d5782e76..418573171f1e 100644 --- a/src/test/ui/check_match/issue-35609.stderr +++ b/src/test/ui/check_match/issue-35609.stderr @@ -48,4 +48,4 @@ LL | match Some(A) { //~ ERROR non-exhaustive error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0004" +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr index 20661cae5ca2..8184616c97ff 100644 --- a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr +++ b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr @@ -84,4 +84,4 @@ LL | f = Some(x); error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/closure_context/issue-26046-fn-mut.stderr b/src/test/ui/closure_context/issue-26046-fn-mut.stderr index 9cc0f1bf9df7..ac98d9427e45 100644 --- a/src/test/ui/closure_context/issue-26046-fn-mut.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-mut.stderr @@ -11,4 +11,4 @@ LL | Box::new(closure) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0525" +For more information about this error, try `rustc --explain E0525`. diff --git a/src/test/ui/closure_context/issue-26046-fn-once.stderr b/src/test/ui/closure_context/issue-26046-fn-once.stderr index 0facdaf3c70a..e09fdb5fb778 100644 --- a/src/test/ui/closure_context/issue-26046-fn-once.stderr +++ b/src/test/ui/closure_context/issue-26046-fn-once.stderr @@ -11,4 +11,4 @@ LL | Box::new(closure) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0525" +For more information about this error, try `rustc --explain E0525`. diff --git a/src/test/ui/closure_context/issue-42065.stderr b/src/test/ui/closure_context/issue-42065.stderr index fdbec34ca7ed..5c2105c4f795 100644 --- a/src/test/ui/closure_context/issue-42065.stderr +++ b/src/test/ui/closure_context/issue-42065.stderr @@ -14,4 +14,4 @@ LL | for (key, value) in dict { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr index 6531e3b8f8b7..7975966bf809 100644 --- a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr +++ b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr @@ -8,4 +8,4 @@ LL | impl C { fn f() {} } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0592" +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/codemap_tests/empty_span.stderr b/src/test/ui/codemap_tests/empty_span.stderr index 63b19c9e0c6a..1bd8d8e37fee 100644 --- a/src/test/ui/codemap_tests/empty_span.stderr +++ b/src/test/ui/codemap_tests/empty_span.stderr @@ -6,4 +6,4 @@ LL | unsafe impl Send for &'static Foo { } //~ ERROR cross-crate traits with error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0321" +For more information about this error, try `rustc --explain E0321`. diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr index 2fdd6906a564..68818f50cd27 100644 --- a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr +++ b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr @@ -9,4 +9,4 @@ LL | let y = &mut x; //~ ERROR cannot borrow error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/codemap_tests/issue-11715.stderr b/src/test/ui/codemap_tests/issue-11715.stderr index d44dac0d5376..d9551d7918a9 100644 --- a/src/test/ui/codemap_tests/issue-11715.stderr +++ b/src/test/ui/codemap_tests/issue-11715.stderr @@ -10,4 +10,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0499" +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/codemap_tests/issue-28308.stderr b/src/test/ui/codemap_tests/issue-28308.stderr index 947c8142e31f..53fde4a628db 100644 --- a/src/test/ui/codemap_tests/issue-28308.stderr +++ b/src/test/ui/codemap_tests/issue-28308.stderr @@ -8,4 +8,4 @@ LL | assert!("foo"); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0600" +For more information about this error, try `rustc --explain E0600`. diff --git a/src/test/ui/codemap_tests/one_line.stderr b/src/test/ui/codemap_tests/one_line.stderr index a31a5318b41e..5a6d474ed166 100644 --- a/src/test/ui/codemap_tests/one_line.stderr +++ b/src/test/ui/codemap_tests/one_line.stderr @@ -9,4 +9,4 @@ LL | v.push(v.pop().unwrap()); //~ ERROR cannot borrow error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0499" +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr index d11ac5463f03..db729ac34f32 100644 --- a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr +++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr @@ -29,4 +29,4 @@ LL | fn baz(&self) {} error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0592" +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/codemap_tests/overlapping_spans.stderr b/src/test/ui/codemap_tests/overlapping_spans.stderr index c585964a5274..62a4f08e1566 100644 --- a/src/test/ui/codemap_tests/overlapping_spans.stderr +++ b/src/test/ui/codemap_tests/overlapping_spans.stderr @@ -9,4 +9,4 @@ LL | S {f:_s} => {} //~ ERROR cannot move out error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0509" +For more information about this error, try `rustc --explain E0509`. diff --git a/src/test/ui/codemap_tests/tab.stderr b/src/test/ui/codemap_tests/tab.stderr index 0f683bd68415..c466610bcec8 100644 --- a/src/test/ui/codemap_tests/tab.stderr +++ b/src/test/ui/codemap_tests/tab.stderr @@ -17,5 +17,5 @@ LL | "bar boo" //~ ERROR mismatched types error: aborting due to 2 previous errors -You've got a few errors: E0308, E0425 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/codemap_tests/tab_3.stderr b/src/test/ui/codemap_tests/tab_3.stderr index c2826359e080..d960c0b7da80 100644 --- a/src/test/ui/codemap_tests/tab_3.stderr +++ b/src/test/ui/codemap_tests/tab_3.stderr @@ -11,4 +11,4 @@ LL | println!("{:?}", some_vec); //~ ERROR use of moved error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index a7fa82a0ba15..614531c98212 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -6,4 +6,3 @@ LL | impl Bar for Baz { } //~ ERROR expected trait, found type alias error: cannot continue compilation due to previous error -If you want more information on this error, try using "rustc --explain E0404" diff --git a/src/test/ui/codemap_tests/unicode_2.stderr b/src/test/ui/codemap_tests/unicode_2.stderr index b75245589b02..b7f7f7fc5ce9 100644 --- a/src/test/ui/codemap_tests/unicode_2.stderr +++ b/src/test/ui/codemap_tests/unicode_2.stderr @@ -22,4 +22,4 @@ LL | let _ = a̐é; //~ ERROR cannot find error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion-missing-tail-expected-type.stderr index 74b6f083f38d..84b6c961a253 100644 --- a/src/test/ui/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion-missing-tail-expected-type.stderr @@ -26,4 +26,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/coherence-error-suppression.stderr b/src/test/ui/coherence-error-suppression.stderr index e195e9452e5a..8cf3fe760f12 100644 --- a/src/test/ui/coherence-error-suppression.stderr +++ b/src/test/ui/coherence-error-suppression.stderr @@ -6,4 +6,4 @@ LL | impl Foo for DoesNotExist {} //~ ERROR cannot find type `DoesNotExist` in t error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0412" +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/coherence-impls-copy.stderr b/src/test/ui/coherence-impls-copy.stderr index 029b04789525..d98492876e8c 100644 --- a/src/test/ui/coherence-impls-copy.stderr +++ b/src/test/ui/coherence-impls-copy.stderr @@ -57,5 +57,5 @@ LL | impl Copy for &'static [NotSync] {} error: aborting due to 8 previous errors -You've got a few errors: E0117, E0206 -If you want more information on an error, try using "rustc --explain E0117" +Some errors occurred: E0117, E0206. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence-overlap-downstream-inherent.stderr b/src/test/ui/coherence-overlap-downstream-inherent.stderr index ec315d897ac1..29df3f9c37a3 100644 --- a/src/test/ui/coherence-overlap-downstream-inherent.stderr +++ b/src/test/ui/coherence-overlap-downstream-inherent.stderr @@ -20,4 +20,4 @@ LL | impl A { fn f(&self) {} } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0592" +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence-overlap-downstream.stderr b/src/test/ui/coherence-overlap-downstream.stderr index 1fac596ed300..8e14e4f9bda1 100644 --- a/src/test/ui/coherence-overlap-downstream.stderr +++ b/src/test/ui/coherence-overlap-downstream.stderr @@ -18,4 +18,4 @@ LL | impl Foo for i32 {} error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence-overlap-issue-23516-inherent.stderr b/src/test/ui/coherence-overlap-issue-23516-inherent.stderr index 6bb73e6d3833..d217a4d2cdf9 100644 --- a/src/test/ui/coherence-overlap-issue-23516-inherent.stderr +++ b/src/test/ui/coherence-overlap-issue-23516-inherent.stderr @@ -11,4 +11,4 @@ LL | impl Cake> { fn dummy(&self) { } } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0592" +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence-overlap-issue-23516.stderr b/src/test/ui/coherence-overlap-issue-23516.stderr index fe4e7cf34873..ea2ecda6f0de 100644 --- a/src/test/ui/coherence-overlap-issue-23516.stderr +++ b/src/test/ui/coherence-overlap-issue-23516.stderr @@ -10,4 +10,4 @@ LL | impl Sweet for Box { } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/coherence-overlap-upstream-inherent.stderr b/src/test/ui/coherence-overlap-upstream-inherent.stderr index a7a6003b06c8..6c6f0dc24833 100644 --- a/src/test/ui/coherence-overlap-upstream-inherent.stderr +++ b/src/test/ui/coherence-overlap-upstream-inherent.stderr @@ -11,4 +11,4 @@ LL | impl A { fn dummy(&self) { } } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0592" +For more information about this error, try `rustc --explain E0592`. diff --git a/src/test/ui/coherence-overlap-upstream.stderr b/src/test/ui/coherence-overlap-upstream.stderr index cc199548f062..794c830cc5bf 100644 --- a/src/test/ui/coherence-overlap-upstream.stderr +++ b/src/test/ui/coherence-overlap-upstream.stderr @@ -10,4 +10,4 @@ LL | impl Foo for i16 {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/command-line-diagnostics.stderr b/src/test/ui/command-line-diagnostics.stderr index 9e9e03373e88..2a45edae3256 100644 --- a/src/test/ui/command-line-diagnostics.stderr +++ b/src/test/ui/command-line-diagnostics.stderr @@ -8,4 +8,4 @@ LL | x = 43; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0384" +For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/compare-method/proj-outlives-region.stderr b/src/test/ui/compare-method/proj-outlives-region.stderr index 9abecb2e03c8..5d734a25fe88 100644 --- a/src/test/ui/compare-method/proj-outlives-region.stderr +++ b/src/test/ui/compare-method/proj-outlives-region.stderr @@ -9,4 +9,4 @@ LL | fn foo() where U: 'a { } //~ ERROR E0276 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/region-extra-2.stderr b/src/test/ui/compare-method/region-extra-2.stderr index 32d7024db35d..4e4f0d7c7bce 100644 --- a/src/test/ui/compare-method/region-extra-2.stderr +++ b/src/test/ui/compare-method/region-extra-2.stderr @@ -9,4 +9,4 @@ LL | fn renew<'b: 'a>(self) -> &'b mut [T] where 'a: 'b { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/region-extra.stderr b/src/test/ui/compare-method/region-extra.stderr index ce62cc62e222..a366fe746766 100644 --- a/src/test/ui/compare-method/region-extra.stderr +++ b/src/test/ui/compare-method/region-extra.stderr @@ -9,4 +9,4 @@ LL | fn foo() where 'a: 'b { } //~ ERROR impl has stricter error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/region-unrelated.stderr b/src/test/ui/compare-method/region-unrelated.stderr index 2026dd1f1ccc..6448e0fb25ab 100644 --- a/src/test/ui/compare-method/region-unrelated.stderr +++ b/src/test/ui/compare-method/region-unrelated.stderr @@ -9,4 +9,4 @@ LL | fn foo() where V: 'a { } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr index 8f0744fa56db..1efd5f2fb258 100644 --- a/src/test/ui/compare-method/reordered-type-param.stderr +++ b/src/test/ui/compare-method/reordered-type-param.stderr @@ -12,4 +12,4 @@ LL | fn b(&self, _x: G) -> G { panic!() } //~ ERROR method `b` has error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0053" +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr index 53aced771ccb..4530cb187183 100644 --- a/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr +++ b/src/test/ui/compare-method/trait-bound-on-type-parameter.stderr @@ -9,4 +9,4 @@ LL | fn b(&self, _x: F) -> F { panic!() } //~ ERROR E0276 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/traits-misc-mismatch-1.stderr b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr index a0c333c3a53f..e99ce95b371c 100644 --- a/src/test/ui/compare-method/traits-misc-mismatch-1.stderr +++ b/src/test/ui/compare-method/traits-misc-mismatch-1.stderr @@ -63,4 +63,4 @@ LL | fn method>(&self) {} error: aborting due to 7 previous errors -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/compare-method/traits-misc-mismatch-2.stderr b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr index 921b0e5d1c49..1de5b1a8a1a9 100644 --- a/src/test/ui/compare-method/traits-misc-mismatch-2.stderr +++ b/src/test/ui/compare-method/traits-misc-mismatch-2.stderr @@ -9,4 +9,4 @@ LL | fn zip>(self, other: U) -> ZipIterator { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/const-deref-ptr.stderr b/src/test/ui/const-deref-ptr.stderr index 8a80802c52ca..61db58104d2d 100644 --- a/src/test/ui/const-deref-ptr.stderr +++ b/src/test/ui/const-deref-ptr.stderr @@ -6,4 +6,4 @@ LL | static C: u64 = unsafe {*(0xdeadbeef as *const u64)}; //~ ERROR E0396 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0396" +For more information about this error, try `rustc --explain E0396`. diff --git a/src/test/ui/const-eval-overflow-2.stderr b/src/test/ui/const-eval-overflow-2.stderr index f376de7cc4c1..9cee718c286b 100644 --- a/src/test/ui/const-eval-overflow-2.stderr +++ b/src/test/ui/const-eval-overflow-2.stderr @@ -12,4 +12,4 @@ LL | NEG_NEG_128 => println!("A"), error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-eval-overflow-4.stderr b/src/test/ui/const-eval-overflow-4.stderr index 14753038fef0..db0a6fc82044 100644 --- a/src/test/ui/const-eval-overflow-4.stderr +++ b/src/test/ui/const-eval-overflow-4.stderr @@ -14,4 +14,4 @@ LL | : [u32; (i8::MAX as i8 + 1i8) as usize] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-eval-span.stderr b/src/test/ui/const-eval-span.stderr index e3c28cafc628..afe8d1bc0b5b 100644 --- a/src/test/ui/const-eval-span.stderr +++ b/src/test/ui/const-eval-span.stderr @@ -9,4 +9,4 @@ LL | V = CONSTANT, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-eval/conditional_array_execution.stderr b/src/test/ui/const-eval/conditional_array_execution.stderr index 4cf12e222831..9270dafbe651 100644 --- a/src/test/ui/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/const-eval/conditional_array_execution.stderr @@ -14,4 +14,4 @@ LL | println!("{}", FOO); //~ E0080 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-eval/index_out_of_bound.stderr b/src/test/ui/const-eval/index_out_of_bound.stderr index 7651fb257e3c..793e0a7ace8d 100644 --- a/src/test/ui/const-eval/index_out_of_bound.stderr +++ b/src/test/ui/const-eval/index_out_of_bound.stderr @@ -6,4 +6,4 @@ LL | static FOO: i32 = [][0]; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr index 3f1082687475..2d51e6603b59 100644 --- a/src/test/ui/const-eval/issue-43197.stderr +++ b/src/test/ui/const-eval/issue-43197.stderr @@ -26,4 +26,4 @@ LL | println!("{} {}", X, Y); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-fn-error.stderr b/src/test/ui/const-fn-error.stderr index d57efce0dffc..077c4d60e649 100644 --- a/src/test/ui/const-fn-error.stderr +++ b/src/test/ui/const-fn-error.stderr @@ -33,5 +33,5 @@ LL | let a : [i32; f(X)]; error: aborting due to 4 previous errors -You've got a few errors: E0015, E0016, E0019, E0080 -If you want more information on an error, try using "rustc --explain E0015" +Some errors occurred: E0015, E0016, E0019, E0080. +For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/const-fn-mismatch.stderr b/src/test/ui/const-fn-mismatch.stderr index efbf701120d2..1c9728fec9ec 100644 --- a/src/test/ui/const-fn-mismatch.stderr +++ b/src/test/ui/const-fn-mismatch.stderr @@ -6,4 +6,4 @@ LL | const fn f() -> u32 { 22 } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0379" +For more information about this error, try `rustc --explain E0379`. diff --git a/src/test/ui/const-fn-not-in-trait.stderr b/src/test/ui/const-fn-not-in-trait.stderr index 4a77862c3122..5801f701ff8f 100644 --- a/src/test/ui/const-fn-not-in-trait.stderr +++ b/src/test/ui/const-fn-not-in-trait.stderr @@ -12,4 +12,4 @@ LL | const fn g() -> u32 { 0 } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0379" +For more information about this error, try `rustc --explain E0379`. diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr index 98f4ac9e83fb..8d737dbfc085 100644 --- a/src/test/ui/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/const-len-underflow-separate-spans.stderr @@ -20,4 +20,4 @@ LL | let a: [i8; LEN] = unimplemented!(); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/const-pattern-irrefutable.stderr b/src/test/ui/const-pattern-irrefutable.stderr index 9a05d4c76c49..6d5738f33287 100644 --- a/src/test/ui/const-pattern-irrefutable.stderr +++ b/src/test/ui/const-pattern-irrefutable.stderr @@ -18,4 +18,4 @@ LL | let d = 4; //~ ERROR refutable pattern in local binding: `_` not covere error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0005" +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/const-unsized.stderr b/src/test/ui/const-unsized.stderr index 478539c88eac..0bbb5debbba6 100644 --- a/src/test/ui/const-unsized.stderr +++ b/src/test/ui/const-unsized.stderr @@ -36,4 +36,4 @@ LL | static STATIC_BAR: str = *"bar"; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/cycle-trait-supertrait-indirect.stderr b/src/test/ui/cycle-trait-supertrait-indirect.stderr index 388da3f860e0..68c20df5f721 100644 --- a/src/test/ui/cycle-trait-supertrait-indirect.stderr +++ b/src/test/ui/cycle-trait-supertrait-indirect.stderr @@ -18,4 +18,4 @@ LL | trait B: C { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0391" +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr index 620cbd9d3364..a5f87928924c 100644 --- a/src/test/ui/deref-suggestion.stderr +++ b/src/test/ui/deref-suggestion.stderr @@ -60,4 +60,4 @@ LL | foo3(borrow!(0)); error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/derived-errors/issue-31997-1.stderr b/src/test/ui/derived-errors/issue-31997-1.stderr index 92c025046a22..7cdcac3891fc 100644 --- a/src/test/ui/derived-errors/issue-31997-1.stderr +++ b/src/test/ui/derived-errors/issue-31997-1.stderr @@ -6,4 +6,4 @@ LL | let mut map = HashMap::new(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0433" +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/did_you_mean/E0178.stderr b/src/test/ui/did_you_mean/E0178.stderr index 293cf7444f4a..29e7aeb45ca7 100644 --- a/src/test/ui/did_you_mean/E0178.stderr +++ b/src/test/ui/did_you_mean/E0178.stderr @@ -24,4 +24,4 @@ LL | z: fn() -> Foo + 'a, //~ ERROR expected a path error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0178" +For more information about this error, try `rustc --explain E0178`. diff --git a/src/test/ui/did_you_mean/bad-assoc-pat.stderr b/src/test/ui/did_you_mean/bad-assoc-pat.stderr index 80caa86fde55..10ee175a97e1 100644 --- a/src/test/ui/did_you_mean/bad-assoc-pat.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-pat.stderr @@ -48,4 +48,4 @@ LL | &(u8,)::AssocItem => {} error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index b584fa16988e..45dce3d8740d 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -104,5 +104,5 @@ LL | type H = Fn(u8) -> (u8)::Output; error: aborting due to 15 previous errors -You've got a few errors: E0121, E0223 -If you want more information on an error, try using "rustc --explain E0121" +Some errors occurred: E0121, E0223. +For more information about an error, try `rustc --explain E0121`. diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr index 5290b388e476..1e55b0c024fb 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-1.stderr @@ -10,4 +10,4 @@ LL | f1.foo(1usize); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr index d1b3b2031f6c..eee7f32032b6 100644 --- a/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr +++ b/src/test/ui/did_you_mean/issue-21659-show-relevant-trait-impls-2.stderr @@ -13,4 +13,4 @@ LL | f1.foo(1usize); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr index eb2659e1fcaa..a80593e05f10 100644 --- a/src/test/ui/did_you_mean/issue-31424.stderr +++ b/src/test/ui/did_you_mean/issue-31424.stderr @@ -17,4 +17,4 @@ LL | (&mut self).bar(); //~ ERROR cannot borrow error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-34126.stderr b/src/test/ui/did_you_mean/issue-34126.stderr index b99b1b54d538..08ece78b7888 100644 --- a/src/test/ui/did_you_mean/issue-34126.stderr +++ b/src/test/ui/did_you_mean/issue-34126.stderr @@ -9,4 +9,4 @@ LL | self.run(&mut self); //~ ERROR cannot borrow error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-34337.stderr b/src/test/ui/did_you_mean/issue-34337.stderr index 3b73132423d4..7a4a03ce5d7e 100644 --- a/src/test/ui/did_you_mean/issue-34337.stderr +++ b/src/test/ui/did_you_mean/issue-34337.stderr @@ -9,4 +9,4 @@ LL | get(&mut key); //~ ERROR cannot borrow error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-35937.stderr b/src/test/ui/did_you_mean/issue-35937.stderr index 7894ca208818..4a29cd81425c 100644 --- a/src/test/ui/did_you_mean/issue-35937.stderr +++ b/src/test/ui/did_you_mean/issue-35937.stderr @@ -24,5 +24,5 @@ LL | s.x += 1; //~ ERROR cannot assign error: aborting due to 3 previous errors -You've got a few errors: E0594, E0596 -If you want more information on an error, try using "rustc --explain E0594" +Some errors occurred: E0594, E0596. +For more information about an error, try `rustc --explain E0594`. diff --git a/src/test/ui/did_you_mean/issue-36798.stderr b/src/test/ui/did_you_mean/issue-36798.stderr index 100f93d2e31c..c0a73abdf725 100644 --- a/src/test/ui/did_you_mean/issue-36798.stderr +++ b/src/test/ui/did_you_mean/issue-36798.stderr @@ -6,4 +6,4 @@ LL | f.baz; //~ ERROR no field error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0609" +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr index 4bbadf3a7906..4cf0df443512 100644 --- a/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr +++ b/src/test/ui/did_you_mean/issue-36798_unknown_field.stderr @@ -8,4 +8,4 @@ LL | f.zz; //~ ERROR no field error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0609" +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/did_you_mean/issue-37139.stderr b/src/test/ui/did_you_mean/issue-37139.stderr index 9d918964ce6c..7cf3326f9d61 100644 --- a/src/test/ui/did_you_mean/issue-37139.stderr +++ b/src/test/ui/did_you_mean/issue-37139.stderr @@ -9,4 +9,4 @@ LL | test(&mut x); //~ ERROR cannot borrow immutable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr index 5a9fbafb8eb5..e3c75599a415 100644 --- a/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr +++ b/src/test/ui/did_you_mean/issue-38054-do-not-show-unresolved-names.stderr @@ -12,4 +12,4 @@ LL | use Foo1; //~ ERROR unresolved error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0432" +For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/did_you_mean/issue-38147-1.stderr b/src/test/ui/did_you_mean/issue-38147-1.stderr index ca842b396465..4ebb5683405d 100644 --- a/src/test/ui/did_you_mean/issue-38147-1.stderr +++ b/src/test/ui/did_you_mean/issue-38147-1.stderr @@ -8,4 +8,4 @@ LL | self.s.push('x'); //~ ERROR cannot borrow data mutably error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0389" +For more information about this error, try `rustc --explain E0389`. diff --git a/src/test/ui/did_you_mean/issue-38147-2.stderr b/src/test/ui/did_you_mean/issue-38147-2.stderr index 606f1dd52232..31433cf83c3b 100644 --- a/src/test/ui/did_you_mean/issue-38147-2.stderr +++ b/src/test/ui/did_you_mean/issue-38147-2.stderr @@ -9,4 +9,4 @@ LL | self.s.push('x'); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-38147-3.stderr b/src/test/ui/did_you_mean/issue-38147-3.stderr index cf075204e8b7..8bb23acdc407 100644 --- a/src/test/ui/did_you_mean/issue-38147-3.stderr +++ b/src/test/ui/did_you_mean/issue-38147-3.stderr @@ -9,4 +9,4 @@ LL | self.s.push('x'); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-38147-4.stderr b/src/test/ui/did_you_mean/issue-38147-4.stderr index a10acf1460dc..e78cea14a7b5 100644 --- a/src/test/ui/did_you_mean/issue-38147-4.stderr +++ b/src/test/ui/did_you_mean/issue-38147-4.stderr @@ -8,4 +8,4 @@ LL | f.s.push('x'); //~ ERROR cannot borrow data mutably error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0389" +For more information about this error, try `rustc --explain E0389`. diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr index a05b70b2eb86..dfa9cb880e56 100644 --- a/src/test/ui/did_you_mean/issue-39544.stderr +++ b/src/test/ui/did_you_mean/issue-39544.stderr @@ -98,5 +98,5 @@ LL | *x.0 = 1; error: aborting due to 12 previous errors -You've got a few errors: E0594, E0596 -If you want more information on an error, try using "rustc --explain E0594" +Some errors occurred: E0594, E0596. +For more information about an error, try `rustc --explain E0594`. diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index c08ee4247c7b..3f955da86ba0 100644 --- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr @@ -53,4 +53,4 @@ LL | fn bar(&self){} error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr index e576393500fe..a3433939573a 100644 --- a/src/test/ui/did_you_mean/issue-40006.stderr +++ b/src/test/ui/did_you_mean/issue-40006.stderr @@ -66,4 +66,4 @@ LL | impl X { //~ ERROR cannot be made into an object error: aborting due to 9 previous errors -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/did_you_mean/issue-40823.stderr b/src/test/ui/did_you_mean/issue-40823.stderr index 3aece9908a9c..20e95513ec2f 100644 --- a/src/test/ui/did_you_mean/issue-40823.stderr +++ b/src/test/ui/did_you_mean/issue-40823.stderr @@ -6,4 +6,4 @@ LL | buf.iter_mut(); //~ ERROR cannot borrow immutable borrowed content error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr index 64c20ff8e078..c4b282bde528 100644 --- a/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr +++ b/src/test/ui/did_you_mean/issue-42599_available_fields_note.stderr @@ -28,5 +28,5 @@ LL | let egregious_field_misaccess = demo.egregiously_nonexistent_field; error: aborting due to 4 previous errors -You've got a few errors: E0560, E0609 -If you want more information on an error, try using "rustc --explain E0560" +Some errors occurred: E0560, E0609. +For more information about an error, try `rustc --explain E0560`. diff --git a/src/test/ui/did_you_mean/issue-42764.stderr b/src/test/ui/did_you_mean/issue-42764.stderr index 390b214e62e0..f1da920872d7 100644 --- a/src/test/ui/did_you_mean/issue-42764.stderr +++ b/src/test/ui/did_you_mean/issue-42764.stderr @@ -15,4 +15,4 @@ LL | this_function_expects_a_double_option(DoubleOption::AlternativeSome(n)) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr index 1f653c908866..779ae31ca300 100644 --- a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr +++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr @@ -30,5 +30,5 @@ LL | if let Example(_) = y { //~ ERROR expected tuple struct/variant, found error: aborting due to 3 previous errors -You've got a few errors: E0423, E0532 -If you want more information on an error, try using "rustc --explain E0423" +Some errors occurred: E0423, E0532. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index 8b34c533d8b4..691c7ccd9fdf 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -23,4 +23,4 @@ LL | fn is_send() { } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0275" +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr index a4048fbfb265..2c8039615572 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr @@ -21,5 +21,5 @@ LL | let x: &Bottom = &t; //~ ERROR mismatched types error: aborting due to 3 previous errors -You've got a few errors: E0055, E0308 -If you want more information on an error, try using "rustc --explain E0055" +Some errors occurred: E0055, E0308. +For more information about an error, try `rustc --explain E0055`. diff --git a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr index fcfa80e1c9d8..6dd216489313 100644 --- a/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr +++ b/src/test/ui/did_you_mean/trait-object-reference-without-parens-suggestion.stderr @@ -20,5 +20,5 @@ LL | let _: &Copy + 'static; //~ ERROR expected a path error: aborting due to 3 previous errors -You've got a few errors: E0038, E0178 -If you want more information on an error, try using "rustc --explain E0038" +Some errors occurred: E0038, E0178. +For more information about an error, try `rustc --explain E0038`. diff --git a/src/test/ui/discrim-overflow-2.stderr b/src/test/ui/discrim-overflow-2.stderr index 6162766b5870..bd610bc7163d 100644 --- a/src/test/ui/discrim-overflow-2.stderr +++ b/src/test/ui/discrim-overflow-2.stderr @@ -64,4 +64,4 @@ LL | OhNo, //~ ERROR enum discriminant overflowed [E0370] error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0370" +For more information about this error, try `rustc --explain E0370`. diff --git a/src/test/ui/discrim-overflow.stderr b/src/test/ui/discrim-overflow.stderr index a713aea1b21e..ef784679ce02 100644 --- a/src/test/ui/discrim-overflow.stderr +++ b/src/test/ui/discrim-overflow.stderr @@ -64,4 +64,4 @@ LL | OhNo, //~ ERROR enum discriminant overflowed [E0370] error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0370" +For more information about this error, try `rustc --explain E0370`. diff --git a/src/test/ui/double-import.stderr b/src/test/ui/double-import.stderr index ceddff4047b1..df6463a7e288 100644 --- a/src/test/ui/double-import.stderr +++ b/src/test/ui/double-import.stderr @@ -14,4 +14,4 @@ LL | use sub2::foo as other_foo; //~ ERROR the name `foo` is defined multiple ti error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0252" +For more information about this error, try `rustc --explain E0252`. diff --git a/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr b/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr index 454ee6afe24b..668fbf9521b1 100644 --- a/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-extern-crate.stderr @@ -44,4 +44,4 @@ LL | } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr index d5b4e85ce5e4..f4ea7f1bc509 100644 --- a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr @@ -22,4 +22,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0569" +For more information about this error, try `rustc --explain E0569`. diff --git a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr index 6fac358e21af..e6ce53402f4f 100644 --- a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr @@ -44,4 +44,4 @@ LL | } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/dropck/dropck-eyepatch.stderr b/src/test/ui/dropck/dropck-eyepatch.stderr index d8cc5bf23730..5e0a4a744212 100644 --- a/src/test/ui/dropck/dropck-eyepatch.stderr +++ b/src/test/ui/dropck/dropck-eyepatch.stderr @@ -44,4 +44,4 @@ LL | } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/e0119/complex-impl.stderr b/src/test/ui/e0119/complex-impl.stderr index b268c7554045..0c331cf5e75b 100644 --- a/src/test/ui/e0119/complex-impl.stderr +++ b/src/test/ui/e0119/complex-impl.stderr @@ -16,5 +16,5 @@ LL | impl External for (Q, R) {} //~ ERROR must be used error: aborting due to 2 previous errors -You've got a few errors: E0119, E0210 -If you want more information on an error, try using "rustc --explain E0119" +Some errors occurred: E0119, E0210. +For more information about an error, try `rustc --explain E0119`. diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr index ff17643f1210..e8b2c84c0df0 100644 --- a/src/test/ui/e0119/conflict-with-std.stderr +++ b/src/test/ui/e0119/conflict-with-std.stderr @@ -29,4 +29,4 @@ LL | impl TryFrom for X { //~ ERROR conflicting implementations error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/e0119/issue-23563.stderr b/src/test/ui/e0119/issue-23563.stderr index 9ad866253446..0630b76882e7 100644 --- a/src/test/ui/e0119/issue-23563.stderr +++ b/src/test/ui/e0119/issue-23563.stderr @@ -10,4 +10,4 @@ LL | impl<'a, T> LolFrom<&'a [T]> for LocalType { //~ ERROR conflicting imple error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/e0119/issue-27403.stderr b/src/test/ui/e0119/issue-27403.stderr index 4f4a9e97d6bb..9dea60a72b50 100644 --- a/src/test/ui/e0119/issue-27403.stderr +++ b/src/test/ui/e0119/issue-27403.stderr @@ -10,4 +10,4 @@ LL | impl Into for GenX { //~ ERROR conflicting implementations error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/e0119/issue-28981.stderr b/src/test/ui/e0119/issue-28981.stderr index b1ec1111ede9..16da24550bc1 100644 --- a/src/test/ui/e0119/issue-28981.stderr +++ b/src/test/ui/e0119/issue-28981.stderr @@ -16,5 +16,5 @@ LL | impl Deref for Foo { } //~ ERROR must be used error: aborting due to 2 previous errors -You've got a few errors: E0119, E0210 -If you want more information on an error, try using "rustc --explain E0119" +Some errors occurred: E0119, E0210. +For more information about an error, try `rustc --explain E0119`. diff --git a/src/test/ui/e0119/so-37347311.stderr b/src/test/ui/e0119/so-37347311.stderr index 8be27adc4a2f..6c14b200ee5b 100644 --- a/src/test/ui/e0119/so-37347311.stderr +++ b/src/test/ui/e0119/so-37347311.stderr @@ -9,4 +9,4 @@ LL | impl From for MyError { //~ ERROR conflicting impl error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/empty-struct-unit-expr.stderr b/src/test/ui/empty-struct-unit-expr.stderr index e64f383f91b9..fff696fc80f0 100644 --- a/src/test/ui/empty-struct-unit-expr.stderr +++ b/src/test/ui/empty-struct-unit-expr.stderr @@ -38,4 +38,4 @@ LL | let xe4 = XE::XEmpty4; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0618" +For more information about this error, try `rustc --explain E0618`. diff --git a/src/test/ui/enum-and-module-in-same-scope.stderr b/src/test/ui/enum-and-module-in-same-scope.stderr index 86f7ee5bb0e5..230872abe0b3 100644 --- a/src/test/ui/enum-and-module-in-same-scope.stderr +++ b/src/test/ui/enum-and-module-in-same-scope.stderr @@ -11,4 +11,4 @@ LL | mod Foo { //~ ERROR the name `Foo` is defined multiple times error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0428" +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index c3412e73599b..6a4392df35d8 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -12,4 +12,4 @@ LL | match x { } //~ ERROR E0004 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0004" +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/error-codes/E0004.stderr b/src/test/ui/error-codes/E0004.stderr index 56351f80f9d2..cf364a886891 100644 --- a/src/test/ui/error-codes/E0004.stderr +++ b/src/test/ui/error-codes/E0004.stderr @@ -6,4 +6,4 @@ LL | match x { //~ ERROR E0004 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0004" +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr index d02817a66755..b321a69805eb 100644 --- a/src/test/ui/error-codes/E0005.stderr +++ b/src/test/ui/error-codes/E0005.stderr @@ -6,4 +6,4 @@ LL | let Some(y) = x; //~ ERROR E0005 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0005" +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/error-codes/E0007.stderr b/src/test/ui/error-codes/E0007.stderr index c5cf140bab50..f662365b8f18 100644 --- a/src/test/ui/error-codes/E0007.stderr +++ b/src/test/ui/error-codes/E0007.stderr @@ -12,5 +12,5 @@ LL | op_string @ Some(s) => {}, error: aborting due to 2 previous errors -You've got a few errors: E0007, E0303 -If you want more information on an error, try using "rustc --explain E0007" +Some errors occurred: E0007, E0303. +For more information about an error, try `rustc --explain E0007`. diff --git a/src/test/ui/error-codes/E0008.stderr b/src/test/ui/error-codes/E0008.stderr index cdf6eff0fabb..e9af3166ed5e 100644 --- a/src/test/ui/error-codes/E0008.stderr +++ b/src/test/ui/error-codes/E0008.stderr @@ -6,4 +6,4 @@ LL | Some(s) if s.len() == 0 => {}, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0008" +For more information about this error, try `rustc --explain E0008`. diff --git a/src/test/ui/error-codes/E0009.stderr b/src/test/ui/error-codes/E0009.stderr index ac6c2ace1f8d..8b3071420dd8 100644 --- a/src/test/ui/error-codes/E0009.stderr +++ b/src/test/ui/error-codes/E0009.stderr @@ -8,4 +8,4 @@ LL | Some((y, ref z)) => {}, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0009" +For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/error-codes/E0010-teach.stderr b/src/test/ui/error-codes/E0010-teach.stderr index 0d97a56b1b42..fa5c767caf24 100644 --- a/src/test/ui/error-codes/E0010-teach.stderr +++ b/src/test/ui/error-codes/E0010-teach.stderr @@ -8,4 +8,4 @@ LL | const CON : Box = box 0; //~ ERROR E0010 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0010" +For more information about this error, try `rustc --explain E0010`. diff --git a/src/test/ui/error-codes/E0010.stderr b/src/test/ui/error-codes/E0010.stderr index 0d8b0800b089..83c1b409a517 100644 --- a/src/test/ui/error-codes/E0010.stderr +++ b/src/test/ui/error-codes/E0010.stderr @@ -6,4 +6,4 @@ LL | const CON : Box = box 0; //~ ERROR E0010 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0010" +For more information about this error, try `rustc --explain E0010`. diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index 540d76a6d450..411b9f313978 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -24,5 +24,5 @@ LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017 error: aborting due to 4 previous errors -You've got a few errors: E0017, E0596 -If you want more information on an error, try using "rustc --explain E0017" +Some errors occurred: E0017, E0596. +For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr index 2f69db3e7ef1..26f7baeb1a46 100644 --- a/src/test/ui/error-codes/E0023.stderr +++ b/src/test/ui/error-codes/E0023.stderr @@ -18,4 +18,4 @@ LL | Fruit::Pear(1, 2) => {}, //~ ERROR E0023 error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0023" +For more information about this error, try `rustc --explain E0023`. diff --git a/src/test/ui/error-codes/E0025.stderr b/src/test/ui/error-codes/E0025.stderr index 2e32ccab0dd3..f60372559a33 100644 --- a/src/test/ui/error-codes/E0025.stderr +++ b/src/test/ui/error-codes/E0025.stderr @@ -8,4 +8,4 @@ LL | let Foo { a: x, a: y, b: 0 } = x; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0025" +For more information about this error, try `rustc --explain E0025`. diff --git a/src/test/ui/error-codes/E0026-teach.stderr b/src/test/ui/error-codes/E0026-teach.stderr index e7ab3fbf307f..63d072fe03d0 100644 --- a/src/test/ui/error-codes/E0026-teach.stderr +++ b/src/test/ui/error-codes/E0026-teach.stderr @@ -10,4 +10,4 @@ LL | Thing { x, y, z } => {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0026" +For more information about this error, try `rustc --explain E0026`. diff --git a/src/test/ui/error-codes/E0026.stderr b/src/test/ui/error-codes/E0026.stderr index 9415da2a819f..af8519511276 100644 --- a/src/test/ui/error-codes/E0026.stderr +++ b/src/test/ui/error-codes/E0026.stderr @@ -6,4 +6,4 @@ LL | Thing { x, y, z } => {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0026" +For more information about this error, try `rustc --explain E0026`. diff --git a/src/test/ui/error-codes/E0027-teach.stderr b/src/test/ui/error-codes/E0027-teach.stderr index d9c6a865dad8..1c5333d76a85 100644 --- a/src/test/ui/error-codes/E0027-teach.stderr +++ b/src/test/ui/error-codes/E0027-teach.stderr @@ -8,4 +8,4 @@ LL | Dog { age: x } => {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0027" +For more information about this error, try `rustc --explain E0027`. diff --git a/src/test/ui/error-codes/E0027.stderr b/src/test/ui/error-codes/E0027.stderr index 6959324ccdec..208b263e0f89 100644 --- a/src/test/ui/error-codes/E0027.stderr +++ b/src/test/ui/error-codes/E0027.stderr @@ -6,4 +6,4 @@ LL | Dog { age: x } => {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0027" +For more information about this error, try `rustc --explain E0027`. diff --git a/src/test/ui/error-codes/E0029-teach.stderr b/src/test/ui/error-codes/E0029-teach.stderr index d4e9a1c30400..25d95108f963 100644 --- a/src/test/ui/error-codes/E0029-teach.stderr +++ b/src/test/ui/error-codes/E0029-teach.stderr @@ -18,5 +18,5 @@ LL | "hello" ... "world" => {} error: aborting due to 2 previous errors -You've got a few errors: E0029, E0658 -If you want more information on an error, try using "rustc --explain E0029" +Some errors occurred: E0029, E0658. +For more information about an error, try `rustc --explain E0029`. diff --git a/src/test/ui/error-codes/E0029.stderr b/src/test/ui/error-codes/E0029.stderr index ab1fa321dbde..53c228c6e38c 100644 --- a/src/test/ui/error-codes/E0029.stderr +++ b/src/test/ui/error-codes/E0029.stderr @@ -17,5 +17,5 @@ LL | "hello" ... "world" => {} error: aborting due to 2 previous errors -You've got a few errors: E0029, E0658 -If you want more information on an error, try using "rustc --explain E0029" +Some errors occurred: E0029, E0658. +For more information about an error, try `rustc --explain E0029`. diff --git a/src/test/ui/error-codes/E0030-teach.stderr b/src/test/ui/error-codes/E0030-teach.stderr index e23bf89be29b..8b262d5b296b 100644 --- a/src/test/ui/error-codes/E0030-teach.stderr +++ b/src/test/ui/error-codes/E0030-teach.stderr @@ -8,4 +8,4 @@ LL | 1000 ... 5 => {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0030" +For more information about this error, try `rustc --explain E0030`. diff --git a/src/test/ui/error-codes/E0030.stderr b/src/test/ui/error-codes/E0030.stderr index 9d4352888cb8..0949cfb50b68 100644 --- a/src/test/ui/error-codes/E0030.stderr +++ b/src/test/ui/error-codes/E0030.stderr @@ -6,4 +6,4 @@ LL | 1000 ... 5 => {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0030" +For more information about this error, try `rustc --explain E0030`. diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr index 9f2a9595b390..c74485781c12 100644 --- a/src/test/ui/error-codes/E0033-teach.stderr +++ b/src/test/ui/error-codes/E0033-teach.stderr @@ -24,5 +24,5 @@ LL | let &invalid = trait_obj; error: aborting due to 3 previous errors -You've got a few errors: E0033, E0038, E0423 -If you want more information on an error, try using "rustc --explain E0033" +Some errors occurred: E0033, E0038, E0423. +For more information about an error, try `rustc --explain E0033`. diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr index a0d73c074f82..a1e72d6f6695 100644 --- a/src/test/ui/error-codes/E0033.stderr +++ b/src/test/ui/error-codes/E0033.stderr @@ -20,5 +20,5 @@ LL | let &invalid = trait_obj; error: aborting due to 3 previous errors -You've got a few errors: E0033, E0038, E0423 -If you want more information on an error, try using "rustc --explain E0033" +Some errors occurred: E0033, E0038, E0423. +For more information about an error, try `rustc --explain E0033`. diff --git a/src/test/ui/error-codes/E0034.stderr b/src/test/ui/error-codes/E0034.stderr index f457dfded7cd..cec0f2d2a80b 100644 --- a/src/test/ui/error-codes/E0034.stderr +++ b/src/test/ui/error-codes/E0034.stderr @@ -17,4 +17,4 @@ LL | fn foo() {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0034" +For more information about this error, try `rustc --explain E0034`. diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index b3f3ea57a346..bc76323f1839 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -8,4 +8,4 @@ LL | fn call_foo(x: Box) { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/error-codes/E0040.stderr b/src/test/ui/error-codes/E0040.stderr index a2f6174e9185..01636ae98b81 100644 --- a/src/test/ui/error-codes/E0040.stderr +++ b/src/test/ui/error-codes/E0040.stderr @@ -6,4 +6,4 @@ LL | x.drop(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0040" +For more information about this error, try `rustc --explain E0040`. diff --git a/src/test/ui/error-codes/E0044.stderr b/src/test/ui/error-codes/E0044.stderr index b823f3717b35..b981f525517e 100644 --- a/src/test/ui/error-codes/E0044.stderr +++ b/src/test/ui/error-codes/E0044.stderr @@ -12,4 +12,4 @@ LL | extern { fn some_func(x: T); } //~ ERROR E0044 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0044" +For more information about this error, try `rustc --explain E0044`. diff --git a/src/test/ui/error-codes/E0045.stderr b/src/test/ui/error-codes/E0045.stderr index e79965aeff78..35a592a69860 100644 --- a/src/test/ui/error-codes/E0045.stderr +++ b/src/test/ui/error-codes/E0045.stderr @@ -6,4 +6,4 @@ LL | extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0045" +For more information about this error, try `rustc --explain E0045`. diff --git a/src/test/ui/error-codes/E0049.stderr b/src/test/ui/error-codes/E0049.stderr index cdc936df2704..b7eaad570438 100644 --- a/src/test/ui/error-codes/E0049.stderr +++ b/src/test/ui/error-codes/E0049.stderr @@ -9,4 +9,4 @@ LL | fn foo(x: bool) -> Self { Bar } //~ ERROR E0049 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0049" +For more information about this error, try `rustc --explain E0049`. diff --git a/src/test/ui/error-codes/E0050.stderr b/src/test/ui/error-codes/E0050.stderr index d5d1677f43f4..bff3b7b16b91 100644 --- a/src/test/ui/error-codes/E0050.stderr +++ b/src/test/ui/error-codes/E0050.stderr @@ -27,4 +27,4 @@ LL | fn less(&self, x: u8, y: u8, z: u8) { } //~ ERROR E0050 error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0050" +For more information about this error, try `rustc --explain E0050`. diff --git a/src/test/ui/error-codes/E0054.stderr b/src/test/ui/error-codes/E0054.stderr index ed82704e6611..d5cf18460fd8 100644 --- a/src/test/ui/error-codes/E0054.stderr +++ b/src/test/ui/error-codes/E0054.stderr @@ -8,4 +8,4 @@ LL | let x_is_nonzero = x as bool; //~ ERROR E0054 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0054" +For more information about this error, try `rustc --explain E0054`. diff --git a/src/test/ui/error-codes/E0055.stderr b/src/test/ui/error-codes/E0055.stderr index 3d13b1441062..9653f4eaeefd 100644 --- a/src/test/ui/error-codes/E0055.stderr +++ b/src/test/ui/error-codes/E0055.stderr @@ -8,4 +8,4 @@ LL | ref_foo.foo(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0055" +For more information about this error, try `rustc --explain E0055`. diff --git a/src/test/ui/error-codes/E0057.stderr b/src/test/ui/error-codes/E0057.stderr index 0d6cd77de070..fb3e710b8cf9 100644 --- a/src/test/ui/error-codes/E0057.stderr +++ b/src/test/ui/error-codes/E0057.stderr @@ -12,4 +12,4 @@ LL | let c = f(2, 3); //~ ERROR E0057 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0057" +For more information about this error, try `rustc --explain E0057`. diff --git a/src/test/ui/error-codes/E0059.stderr b/src/test/ui/error-codes/E0059.stderr index 5e2907eed692..abe8b729c93b 100644 --- a/src/test/ui/error-codes/E0059.stderr +++ b/src/test/ui/error-codes/E0059.stderr @@ -6,4 +6,4 @@ LL | fn foo>(f: F) -> F::Output { f(3) } //~ ERROR E0059 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0059" +For more information about this error, try `rustc --explain E0059`. diff --git a/src/test/ui/error-codes/E0060.stderr b/src/test/ui/error-codes/E0060.stderr index 0493015cc765..c6aac6e41c62 100644 --- a/src/test/ui/error-codes/E0060.stderr +++ b/src/test/ui/error-codes/E0060.stderr @@ -9,4 +9,4 @@ LL | unsafe { printf(); } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0060" +For more information about this error, try `rustc --explain E0060`. diff --git a/src/test/ui/error-codes/E0061.stderr b/src/test/ui/error-codes/E0061.stderr index 6ddd4be9d8e2..d5842a18bc8b 100644 --- a/src/test/ui/error-codes/E0061.stderr +++ b/src/test/ui/error-codes/E0061.stderr @@ -18,4 +18,4 @@ LL | f2(); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0061" +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/error-codes/E0062.stderr b/src/test/ui/error-codes/E0062.stderr index a24c5e059147..c5c38c6f5ffe 100644 --- a/src/test/ui/error-codes/E0062.stderr +++ b/src/test/ui/error-codes/E0062.stderr @@ -8,4 +8,4 @@ LL | x: 0, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0062" +For more information about this error, try `rustc --explain E0062`. diff --git a/src/test/ui/error-codes/E0063.stderr b/src/test/ui/error-codes/E0063.stderr index 7f33223a7ea1..1ed54b4e7ba6 100644 --- a/src/test/ui/error-codes/E0063.stderr +++ b/src/test/ui/error-codes/E0063.stderr @@ -24,4 +24,4 @@ LL | let z = TruncatedPluralFoo{x:1}; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0063" +For more information about this error, try `rustc --explain E0063`. diff --git a/src/test/ui/error-codes/E0067.stderr b/src/test/ui/error-codes/E0067.stderr index b964b9dffc1f..76f06c7c4637 100644 --- a/src/test/ui/error-codes/E0067.stderr +++ b/src/test/ui/error-codes/E0067.stderr @@ -14,5 +14,5 @@ LL | LinkedList::new() += 1; //~ ERROR E0368 error: aborting due to 2 previous errors -You've got a few errors: E0067, E0368 -If you want more information on an error, try using "rustc --explain E0067" +Some errors occurred: E0067, E0368. +For more information about an error, try `rustc --explain E0067`. diff --git a/src/test/ui/error-codes/E0069.stderr b/src/test/ui/error-codes/E0069.stderr index 8a5b5984c33d..0ba1ed456635 100644 --- a/src/test/ui/error-codes/E0069.stderr +++ b/src/test/ui/error-codes/E0069.stderr @@ -6,4 +6,4 @@ LL | return; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0069" +For more information about this error, try `rustc --explain E0069`. diff --git a/src/test/ui/error-codes/E0070.stderr b/src/test/ui/error-codes/E0070.stderr index 33da9030c41d..892e6943112f 100644 --- a/src/test/ui/error-codes/E0070.stderr +++ b/src/test/ui/error-codes/E0070.stderr @@ -27,5 +27,5 @@ LL | some_other_func() = 4; //~ ERROR E0070 error: aborting due to 4 previous errors -You've got a few errors: E0070, E0308 -If you want more information on an error, try using "rustc --explain E0070" +Some errors occurred: E0070, E0308. +For more information about an error, try `rustc --explain E0070`. diff --git a/src/test/ui/error-codes/E0071.stderr b/src/test/ui/error-codes/E0071.stderr index b28dcf90c82f..637338672e0b 100644 --- a/src/test/ui/error-codes/E0071.stderr +++ b/src/test/ui/error-codes/E0071.stderr @@ -6,4 +6,4 @@ LL | let u = FooAlias { value: 0 }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0071" +For more information about this error, try `rustc --explain E0071`. diff --git a/src/test/ui/error-codes/E0075.stderr b/src/test/ui/error-codes/E0075.stderr index 4fd5b65f4a9c..d29d5d788036 100644 --- a/src/test/ui/error-codes/E0075.stderr +++ b/src/test/ui/error-codes/E0075.stderr @@ -6,4 +6,4 @@ LL | struct Bad; //~ ERROR E0075 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0075" +For more information about this error, try `rustc --explain E0075`. diff --git a/src/test/ui/error-codes/E0076.stderr b/src/test/ui/error-codes/E0076.stderr index 3cee6f4527cb..ae3494038109 100644 --- a/src/test/ui/error-codes/E0076.stderr +++ b/src/test/ui/error-codes/E0076.stderr @@ -6,4 +6,4 @@ LL | struct Bad(u16, u32, u32); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0076" +For more information about this error, try `rustc --explain E0076`. diff --git a/src/test/ui/error-codes/E0077.stderr b/src/test/ui/error-codes/E0077.stderr index 822efe9628bc..42a169f5a20a 100644 --- a/src/test/ui/error-codes/E0077.stderr +++ b/src/test/ui/error-codes/E0077.stderr @@ -6,4 +6,4 @@ LL | struct Bad(String); //~ ERROR E0077 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0077" +For more information about this error, try `rustc --explain E0077`. diff --git a/src/test/ui/error-codes/E0080.stderr b/src/test/ui/error-codes/E0080.stderr index 6db53acd6b98..500e0e83a55f 100644 --- a/src/test/ui/error-codes/E0080.stderr +++ b/src/test/ui/error-codes/E0080.stderr @@ -34,4 +34,4 @@ LL | Y = (1 / 0) //~ ERROR E0080 error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/error-codes/E0081.stderr b/src/test/ui/error-codes/E0081.stderr index e1133c1fc587..36150d7c5263 100644 --- a/src/test/ui/error-codes/E0081.stderr +++ b/src/test/ui/error-codes/E0081.stderr @@ -8,4 +8,4 @@ LL | X = 3, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0081" +For more information about this error, try `rustc --explain E0081`. diff --git a/src/test/ui/error-codes/E0084.stderr b/src/test/ui/error-codes/E0084.stderr index 5ebe03090a0a..d0bc519c9969 100644 --- a/src/test/ui/error-codes/E0084.stderr +++ b/src/test/ui/error-codes/E0084.stderr @@ -8,4 +8,4 @@ LL | enum Foo {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0084" +For more information about this error, try `rustc --explain E0084`. diff --git a/src/test/ui/error-codes/E0087.stderr b/src/test/ui/error-codes/E0087.stderr index b1ff92d8c276..cd1e99e7b411 100644 --- a/src/test/ui/error-codes/E0087.stderr +++ b/src/test/ui/error-codes/E0087.stderr @@ -12,4 +12,4 @@ LL | bar::(); //~ ERROR expected at most 1 type parameter, found 2 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0087" +For more information about this error, try `rustc --explain E0087`. diff --git a/src/test/ui/error-codes/E0088.stderr b/src/test/ui/error-codes/E0088.stderr index 5497eb028d86..4bf2760994eb 100644 --- a/src/test/ui/error-codes/E0088.stderr +++ b/src/test/ui/error-codes/E0088.stderr @@ -12,4 +12,4 @@ LL | g::<'static, 'static>(); //~ ERROR E0088 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0088" +For more information about this error, try `rustc --explain E0088`. diff --git a/src/test/ui/error-codes/E0089.stderr b/src/test/ui/error-codes/E0089.stderr index 3a3990879433..0b95033fb360 100644 --- a/src/test/ui/error-codes/E0089.stderr +++ b/src/test/ui/error-codes/E0089.stderr @@ -6,4 +6,4 @@ LL | foo::(); //~ ERROR expected 2 type parameters, found 1 type parame error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0089" +For more information about this error, try `rustc --explain E0089`. diff --git a/src/test/ui/error-codes/E0090.stderr b/src/test/ui/error-codes/E0090.stderr index 82e8eaf69ea2..f119d5fa4671 100644 --- a/src/test/ui/error-codes/E0090.stderr +++ b/src/test/ui/error-codes/E0090.stderr @@ -6,4 +6,4 @@ LL | foo::<'static>(); //~ ERROR expected 2 lifetime parameters, found 1 lif error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0090" +For more information about this error, try `rustc --explain E0090`. diff --git a/src/test/ui/error-codes/E0091.stderr b/src/test/ui/error-codes/E0091.stderr index 003e9e7efcd1..2116f8f64760 100644 --- a/src/test/ui/error-codes/E0091.stderr +++ b/src/test/ui/error-codes/E0091.stderr @@ -12,4 +12,4 @@ LL | type Foo2 = Box; //~ ERROR E0091 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0091" +For more information about this error, try `rustc --explain E0091`. diff --git a/src/test/ui/error-codes/E0092.stderr b/src/test/ui/error-codes/E0092.stderr index 8b53a029c35d..50d6d63b99c2 100644 --- a/src/test/ui/error-codes/E0092.stderr +++ b/src/test/ui/error-codes/E0092.stderr @@ -6,4 +6,4 @@ LL | fn atomic_foo(); //~ ERROR E0092 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0092" +For more information about this error, try `rustc --explain E0092`. diff --git a/src/test/ui/error-codes/E0093.stderr b/src/test/ui/error-codes/E0093.stderr index 4e2016508376..f261b83a0b88 100644 --- a/src/test/ui/error-codes/E0093.stderr +++ b/src/test/ui/error-codes/E0093.stderr @@ -6,4 +6,4 @@ LL | fn foo(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0093" +For more information about this error, try `rustc --explain E0093`. diff --git a/src/test/ui/error-codes/E0094.stderr b/src/test/ui/error-codes/E0094.stderr index 7a2dfaae279e..322802fc44f0 100644 --- a/src/test/ui/error-codes/E0094.stderr +++ b/src/test/ui/error-codes/E0094.stderr @@ -6,4 +6,4 @@ LL | fn size_of() -> usize; //~ ERROR E0094 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0094" +For more information about this error, try `rustc --explain E0094`. diff --git a/src/test/ui/error-codes/E0106.stderr b/src/test/ui/error-codes/E0106.stderr index 645414ca1ea3..9862dca3fdef 100644 --- a/src/test/ui/error-codes/E0106.stderr +++ b/src/test/ui/error-codes/E0106.stderr @@ -30,4 +30,4 @@ LL | buzz: Buzz, error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0106" +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/error-codes/E0107.stderr b/src/test/ui/error-codes/E0107.stderr index a695a593429a..76bb2667643e 100644 --- a/src/test/ui/error-codes/E0107.stderr +++ b/src/test/ui/error-codes/E0107.stderr @@ -18,4 +18,4 @@ LL | foo2: Foo<'a, 'b, 'c>, error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0107" +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr index 89f3154fb48b..6473517bfada 100644 --- a/src/test/ui/error-codes/E0109.stderr +++ b/src/test/ui/error-codes/E0109.stderr @@ -6,4 +6,4 @@ LL | type X = u32; //~ ERROR E0109 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0109" +For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr index 3f4d525b6e50..10e06ee6d025 100644 --- a/src/test/ui/error-codes/E0110.stderr +++ b/src/test/ui/error-codes/E0110.stderr @@ -6,4 +6,4 @@ LL | type X = u32<'static>; //~ ERROR E0110 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0110" +For more information about this error, try `rustc --explain E0110`. diff --git a/src/test/ui/error-codes/E0116.stderr b/src/test/ui/error-codes/E0116.stderr index 88954b906c46..7c2f35a3305e 100644 --- a/src/test/ui/error-codes/E0116.stderr +++ b/src/test/ui/error-codes/E0116.stderr @@ -8,4 +8,4 @@ LL | impl Vec {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0116" +For more information about this error, try `rustc --explain E0116`. diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr index 240aa4240cc6..16c1a1fae7f5 100644 --- a/src/test/ui/error-codes/E0117.stderr +++ b/src/test/ui/error-codes/E0117.stderr @@ -15,5 +15,5 @@ LL | impl Drop for u32 {} //~ ERROR E0117 error: aborting due to 2 previous errors -You've got a few errors: E0117, E0120 -If you want more information on an error, try using "rustc --explain E0117" +Some errors occurred: E0117, E0120. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/error-codes/E0118.stderr b/src/test/ui/error-codes/E0118.stderr index bb811ab6345e..896213e34874 100644 --- a/src/test/ui/error-codes/E0118.stderr +++ b/src/test/ui/error-codes/E0118.stderr @@ -8,4 +8,4 @@ LL | impl (u8, u8) { //~ ERROR E0118 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0118" +For more information about this error, try `rustc --explain E0118`. diff --git a/src/test/ui/error-codes/E0119.stderr b/src/test/ui/error-codes/E0119.stderr index 55ca8c5a7796..f1e942d4cf53 100644 --- a/src/test/ui/error-codes/E0119.stderr +++ b/src/test/ui/error-codes/E0119.stderr @@ -9,4 +9,4 @@ LL | impl MyTrait for Foo { //~ ERROR E0119 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/error-codes/E0120.stderr b/src/test/ui/error-codes/E0120.stderr index cd69b8d67bf9..6237500c7ae3 100644 --- a/src/test/ui/error-codes/E0120.stderr +++ b/src/test/ui/error-codes/E0120.stderr @@ -6,4 +6,4 @@ LL | impl Drop for MyTrait { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0120" +For more information about this error, try `rustc --explain E0120`. diff --git a/src/test/ui/error-codes/E0121.stderr b/src/test/ui/error-codes/E0121.stderr index ca9557cdcdc4..019e637aa8c5 100644 --- a/src/test/ui/error-codes/E0121.stderr +++ b/src/test/ui/error-codes/E0121.stderr @@ -12,4 +12,4 @@ LL | static BAR: _ = "test"; //~ ERROR E0121 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0121" +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/error-codes/E0124.stderr b/src/test/ui/error-codes/E0124.stderr index 1f4b4ce0efae..c95162c9d214 100644 --- a/src/test/ui/error-codes/E0124.stderr +++ b/src/test/ui/error-codes/E0124.stderr @@ -8,4 +8,4 @@ LL | field1: i32, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0124" +For more information about this error, try `rustc --explain E0124`. diff --git a/src/test/ui/error-codes/E0128.stderr b/src/test/ui/error-codes/E0128.stderr index 632b11967232..81da580f0d51 100644 --- a/src/test/ui/error-codes/E0128.stderr +++ b/src/test/ui/error-codes/E0128.stderr @@ -6,4 +6,4 @@ LL | struct Foo { //~ ERROR E0128 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0128" +For more information about this error, try `rustc --explain E0128`. diff --git a/src/test/ui/error-codes/E0130.stderr b/src/test/ui/error-codes/E0130.stderr index 3e00909109b5..3b54b1b86698 100644 --- a/src/test/ui/error-codes/E0130.stderr +++ b/src/test/ui/error-codes/E0130.stderr @@ -6,4 +6,4 @@ LL | fn foo((a, b): (u32, u32)); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0130" +For more information about this error, try `rustc --explain E0130`. diff --git a/src/test/ui/error-codes/E0131.stderr b/src/test/ui/error-codes/E0131.stderr index b9caca22aeb1..3774e21c2143 100644 --- a/src/test/ui/error-codes/E0131.stderr +++ b/src/test/ui/error-codes/E0131.stderr @@ -6,4 +6,4 @@ LL | fn main() { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0131" +For more information about this error, try `rustc --explain E0131`. diff --git a/src/test/ui/error-codes/E0132.stderr b/src/test/ui/error-codes/E0132.stderr index ce22a99e66c8..80d1c29d50f9 100644 --- a/src/test/ui/error-codes/E0132.stderr +++ b/src/test/ui/error-codes/E0132.stderr @@ -6,4 +6,4 @@ LL | fn f< T >() {} //~ ERROR E0132 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0132" +For more information about this error, try `rustc --explain E0132`. diff --git a/src/test/ui/error-codes/E0133.stderr b/src/test/ui/error-codes/E0133.stderr index d703ce6203ef..dc57a6274445 100644 --- a/src/test/ui/error-codes/E0133.stderr +++ b/src/test/ui/error-codes/E0133.stderr @@ -6,4 +6,4 @@ LL | f(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0133" +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/error-codes/E0137.stderr b/src/test/ui/error-codes/E0137.stderr index 4a5b4f6da86a..ab2f9ba5bea9 100644 --- a/src/test/ui/error-codes/E0137.stderr +++ b/src/test/ui/error-codes/E0137.stderr @@ -9,4 +9,4 @@ LL | fn f() {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0137" +For more information about this error, try `rustc --explain E0137`. diff --git a/src/test/ui/error-codes/E0138.stderr b/src/test/ui/error-codes/E0138.stderr index 40b476afb9af..e713b11b37fe 100644 --- a/src/test/ui/error-codes/E0138.stderr +++ b/src/test/ui/error-codes/E0138.stderr @@ -9,4 +9,4 @@ LL | fn f(argc: isize, argv: *const *const u8) -> isize { 0 } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0138" +For more information about this error, try `rustc --explain E0138`. diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index 99a9b85f41e2..f67022bd6d3f 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -8,4 +8,4 @@ LL | struct Foo; //~ ERROR E0152 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0152" +For more information about this error, try `rustc --explain E0152`. diff --git a/src/test/ui/error-codes/E0161.stderr b/src/test/ui/error-codes/E0161.stderr index fb8f3e0e1683..0135e495c16b 100644 --- a/src/test/ui/error-codes/E0161.stderr +++ b/src/test/ui/error-codes/E0161.stderr @@ -12,5 +12,5 @@ LL | let _x: Box = box *"hello"; //~ ERROR E0161 error: aborting due to 2 previous errors -You've got a few errors: E0161, E0507 -If you want more information on an error, try using "rustc --explain E0161" +Some errors occurred: E0161, E0507. +For more information about an error, try `rustc --explain E0161`. diff --git a/src/test/ui/error-codes/E0162.stderr b/src/test/ui/error-codes/E0162.stderr index e9a7b18fcdd9..91f402dad59b 100644 --- a/src/test/ui/error-codes/E0162.stderr +++ b/src/test/ui/error-codes/E0162.stderr @@ -6,4 +6,4 @@ LL | if let Irrefutable(x) = irr { //~ ERROR E0162 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0162" +For more information about this error, try `rustc --explain E0162`. diff --git a/src/test/ui/error-codes/E0164.stderr b/src/test/ui/error-codes/E0164.stderr index ec91d9b52a95..6eabace9b141 100644 --- a/src/test/ui/error-codes/E0164.stderr +++ b/src/test/ui/error-codes/E0164.stderr @@ -6,4 +6,4 @@ LL | Foo::B(i) => i, //~ ERROR E0164 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0164" +For more information about this error, try `rustc --explain E0164`. diff --git a/src/test/ui/error-codes/E0165.stderr b/src/test/ui/error-codes/E0165.stderr index ac6a88483ec5..66be95e38d2a 100644 --- a/src/test/ui/error-codes/E0165.stderr +++ b/src/test/ui/error-codes/E0165.stderr @@ -6,4 +6,4 @@ LL | while let Irrefutable(x) = irr { //~ ERROR E0165 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0165" +For more information about this error, try `rustc --explain E0165`. diff --git a/src/test/ui/error-codes/E0184.stderr b/src/test/ui/error-codes/E0184.stderr index bd67ed110646..eb6160bc0059 100644 --- a/src/test/ui/error-codes/E0184.stderr +++ b/src/test/ui/error-codes/E0184.stderr @@ -6,4 +6,4 @@ LL | #[derive(Copy)] //~ ERROR E0184 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0184" +For more information about this error, try `rustc --explain E0184`. diff --git a/src/test/ui/error-codes/E0185.stderr b/src/test/ui/error-codes/E0185.stderr index 12ecf25811e9..e5c92abc521b 100644 --- a/src/test/ui/error-codes/E0185.stderr +++ b/src/test/ui/error-codes/E0185.stderr @@ -9,4 +9,4 @@ LL | fn foo(&self) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0185" +For more information about this error, try `rustc --explain E0185`. diff --git a/src/test/ui/error-codes/E0186.stderr b/src/test/ui/error-codes/E0186.stderr index 015c6e5d0bc8..0556ef700ac1 100644 --- a/src/test/ui/error-codes/E0186.stderr +++ b/src/test/ui/error-codes/E0186.stderr @@ -9,4 +9,4 @@ LL | fn foo() {} //~ ERROR E0186 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0186" +For more information about this error, try `rustc --explain E0186`. diff --git a/src/test/ui/error-codes/E0191.stderr b/src/test/ui/error-codes/E0191.stderr index 14ae4469f12a..08b0a845814d 100644 --- a/src/test/ui/error-codes/E0191.stderr +++ b/src/test/ui/error-codes/E0191.stderr @@ -6,4 +6,4 @@ LL | type Foo = Trait; //~ ERROR E0191 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0191" +For more information about this error, try `rustc --explain E0191`. diff --git a/src/test/ui/error-codes/E0192.stderr b/src/test/ui/error-codes/E0192.stderr index 1b2d6eb0285f..fd8976271a51 100644 --- a/src/test/ui/error-codes/E0192.stderr +++ b/src/test/ui/error-codes/E0192.stderr @@ -6,4 +6,4 @@ LL | impl !Trait for Foo { } //~ ERROR E0192 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0192" +For more information about this error, try `rustc --explain E0192`. diff --git a/src/test/ui/error-codes/E0194.stderr b/src/test/ui/error-codes/E0194.stderr index 9447b90355e9..6869f3c96f77 100644 --- a/src/test/ui/error-codes/E0194.stderr +++ b/src/test/ui/error-codes/E0194.stderr @@ -9,4 +9,4 @@ LL | fn do_something_else(&self, bar: T); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0194" +For more information about this error, try `rustc --explain E0194`. diff --git a/src/test/ui/error-codes/E0195.stderr b/src/test/ui/error-codes/E0195.stderr index 735aa4283ec3..f2cf661830d8 100644 --- a/src/test/ui/error-codes/E0195.stderr +++ b/src/test/ui/error-codes/E0195.stderr @@ -9,4 +9,4 @@ LL | fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0195" +For more information about this error, try `rustc --explain E0195`. diff --git a/src/test/ui/error-codes/E0197.stderr b/src/test/ui/error-codes/E0197.stderr index 250101929eec..a18599e4f470 100644 --- a/src/test/ui/error-codes/E0197.stderr +++ b/src/test/ui/error-codes/E0197.stderr @@ -6,4 +6,4 @@ LL | unsafe impl Foo { } //~ ERROR E0197 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0197" +For more information about this error, try `rustc --explain E0197`. diff --git a/src/test/ui/error-codes/E0198.stderr b/src/test/ui/error-codes/E0198.stderr index 12120658d611..41ea0565cccb 100644 --- a/src/test/ui/error-codes/E0198.stderr +++ b/src/test/ui/error-codes/E0198.stderr @@ -6,4 +6,4 @@ LL | unsafe impl !Send for Foo { } //~ ERROR E0198 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0198" +For more information about this error, try `rustc --explain E0198`. diff --git a/src/test/ui/error-codes/E0199.stderr b/src/test/ui/error-codes/E0199.stderr index 826d13a7a0ec..b3cfd0d21ddb 100644 --- a/src/test/ui/error-codes/E0199.stderr +++ b/src/test/ui/error-codes/E0199.stderr @@ -6,4 +6,4 @@ LL | unsafe impl Bar for Foo { } //~ ERROR implementing the trait `Bar` is not u error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0199" +For more information about this error, try `rustc --explain E0199`. diff --git a/src/test/ui/error-codes/E0200.stderr b/src/test/ui/error-codes/E0200.stderr index 30731712045a..07f848b501e8 100644 --- a/src/test/ui/error-codes/E0200.stderr +++ b/src/test/ui/error-codes/E0200.stderr @@ -6,4 +6,4 @@ LL | impl Bar for Foo { } //~ ERROR E0200 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0200" +For more information about this error, try `rustc --explain E0200`. diff --git a/src/test/ui/error-codes/E0201.stderr b/src/test/ui/error-codes/E0201.stderr index 730453c416e5..2b9e51f76fdd 100644 --- a/src/test/ui/error-codes/E0201.stderr +++ b/src/test/ui/error-codes/E0201.stderr @@ -25,4 +25,4 @@ LL | type Quux = u32; //~ ERROR E0201 error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0201" +For more information about this error, try `rustc --explain E0201`. diff --git a/src/test/ui/error-codes/E0206.stderr b/src/test/ui/error-codes/E0206.stderr index 0cd22a454e12..d28bb876d4d6 100644 --- a/src/test/ui/error-codes/E0206.stderr +++ b/src/test/ui/error-codes/E0206.stderr @@ -21,5 +21,5 @@ LL | impl Copy for Foo { } error: aborting due to 3 previous errors -You've got a few errors: E0117, E0206 -If you want more information on an error, try using "rustc --explain E0117" +Some errors occurred: E0117, E0206. +For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/error-codes/E0207.stderr b/src/test/ui/error-codes/E0207.stderr index e1f8a68583fa..6ecab44878d9 100644 --- a/src/test/ui/error-codes/E0207.stderr +++ b/src/test/ui/error-codes/E0207.stderr @@ -6,4 +6,4 @@ LL | impl Foo { //~ ERROR E0207 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0207" +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr index 5fd3278dc883..c88e2d2077af 100644 --- a/src/test/ui/error-codes/E0214.stderr +++ b/src/test/ui/error-codes/E0214.stderr @@ -6,4 +6,4 @@ LL | let v: Vec(&str) = vec!["foo"]; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0214" +For more information about this error, try `rustc --explain E0214`. diff --git a/src/test/ui/error-codes/E0220.stderr b/src/test/ui/error-codes/E0220.stderr index 7a4f730c725a..c8a587f2b535 100644 --- a/src/test/ui/error-codes/E0220.stderr +++ b/src/test/ui/error-codes/E0220.stderr @@ -12,5 +12,5 @@ LL | type Foo = Trait; //~ ERROR E0220 error: aborting due to 2 previous errors -You've got a few errors: E0191, E0220 -If you want more information on an error, try using "rustc --explain E0191" +Some errors occurred: E0191, E0220. +For more information about an error, try `rustc --explain E0191`. diff --git a/src/test/ui/error-codes/E0221.stderr b/src/test/ui/error-codes/E0221.stderr index 07ce53e3b58c..fc9232e85ab4 100644 --- a/src/test/ui/error-codes/E0221.stderr +++ b/src/test/ui/error-codes/E0221.stderr @@ -27,4 +27,4 @@ LL | let _: Self::Err; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0221" +For more information about this error, try `rustc --explain E0221`. diff --git a/src/test/ui/error-codes/E0223.stderr b/src/test/ui/error-codes/E0223.stderr index 9df8c8975e55..f65e744c6259 100644 --- a/src/test/ui/error-codes/E0223.stderr +++ b/src/test/ui/error-codes/E0223.stderr @@ -8,4 +8,4 @@ LL | let foo: MyTrait::X; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0223" +For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/error-codes/E0225.stderr b/src/test/ui/error-codes/E0225.stderr index 8894791a2db6..6b9489c74c8a 100644 --- a/src/test/ui/error-codes/E0225.stderr +++ b/src/test/ui/error-codes/E0225.stderr @@ -6,4 +6,4 @@ LL | let _: Box; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0225" +For more information about this error, try `rustc --explain E0225`. diff --git a/src/test/ui/error-codes/E0229.stderr b/src/test/ui/error-codes/E0229.stderr index 202007a6c7cb..218faf2dfdd6 100644 --- a/src/test/ui/error-codes/E0229.stderr +++ b/src/test/ui/error-codes/E0229.stderr @@ -6,4 +6,4 @@ LL | fn baz(x: &>::A) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0229" +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/error-codes/E0232.stderr b/src/test/ui/error-codes/E0232.stderr index 84f5e45bff78..cb6cc44a7359 100644 --- a/src/test/ui/error-codes/E0232.stderr +++ b/src/test/ui/error-codes/E0232.stderr @@ -8,4 +8,4 @@ LL | #[rustc_on_unimplemented] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0232" +For more information about this error, try `rustc --explain E0232`. diff --git a/src/test/ui/error-codes/E0243.stderr b/src/test/ui/error-codes/E0243.stderr index 26c19707fa8e..0477d1b844a1 100644 --- a/src/test/ui/error-codes/E0243.stderr +++ b/src/test/ui/error-codes/E0243.stderr @@ -6,4 +6,4 @@ LL | struct Bar { x: Foo } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0243" +For more information about this error, try `rustc --explain E0243`. diff --git a/src/test/ui/error-codes/E0244.stderr b/src/test/ui/error-codes/E0244.stderr index 078c8e592615..e32397039625 100644 --- a/src/test/ui/error-codes/E0244.stderr +++ b/src/test/ui/error-codes/E0244.stderr @@ -6,4 +6,4 @@ LL | struct Bar { x: Foo } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0244" +For more information about this error, try `rustc --explain E0244`. diff --git a/src/test/ui/error-codes/E0252.stderr b/src/test/ui/error-codes/E0252.stderr index 8186c4590f08..a4271bf3a4df 100644 --- a/src/test/ui/error-codes/E0252.stderr +++ b/src/test/ui/error-codes/E0252.stderr @@ -14,4 +14,4 @@ LL | use bar::baz as other_baz; //~ ERROR E0252 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0252" +For more information about this error, try `rustc --explain E0252`. diff --git a/src/test/ui/error-codes/E0253.stderr b/src/test/ui/error-codes/E0253.stderr index 74e17e2aa957..9ab6c30eaa01 100644 --- a/src/test/ui/error-codes/E0253.stderr +++ b/src/test/ui/error-codes/E0253.stderr @@ -6,4 +6,4 @@ LL | use foo::MyTrait::do_something; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0253" +For more information about this error, try `rustc --explain E0253`. diff --git a/src/test/ui/error-codes/E0254.stderr b/src/test/ui/error-codes/E0254.stderr index f1e1b56a790d..a52215df0bbc 100644 --- a/src/test/ui/error-codes/E0254.stderr +++ b/src/test/ui/error-codes/E0254.stderr @@ -15,4 +15,4 @@ LL | use foo::alloc as other_alloc; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0254" +For more information about this error, try `rustc --explain E0254`. diff --git a/src/test/ui/error-codes/E0255.stderr b/src/test/ui/error-codes/E0255.stderr index 4d4053b1fb69..a077a43c152f 100644 --- a/src/test/ui/error-codes/E0255.stderr +++ b/src/test/ui/error-codes/E0255.stderr @@ -15,4 +15,4 @@ LL | use bar::foo as other_foo; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0255" +For more information about this error, try `rustc --explain E0255`. diff --git a/src/test/ui/error-codes/E0259.stderr b/src/test/ui/error-codes/E0259.stderr index 2cdd9aa66835..24a73544a35f 100644 --- a/src/test/ui/error-codes/E0259.stderr +++ b/src/test/ui/error-codes/E0259.stderr @@ -14,4 +14,4 @@ LL | extern crate libc as alloc; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0259" +For more information about this error, try `rustc --explain E0259`. diff --git a/src/test/ui/error-codes/E0260.stderr b/src/test/ui/error-codes/E0260.stderr index a249c80ea2c6..437794432b08 100644 --- a/src/test/ui/error-codes/E0260.stderr +++ b/src/test/ui/error-codes/E0260.stderr @@ -15,4 +15,4 @@ LL | extern crate alloc as other_alloc; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0260" +For more information about this error, try `rustc --explain E0260`. diff --git a/src/test/ui/error-codes/E0261.stderr b/src/test/ui/error-codes/E0261.stderr index a12878ab8964..e9140ec2c748 100644 --- a/src/test/ui/error-codes/E0261.stderr +++ b/src/test/ui/error-codes/E0261.stderr @@ -12,4 +12,4 @@ LL | x: &'a str, //~ ERROR E0261 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0261" +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/error-codes/E0262.stderr b/src/test/ui/error-codes/E0262.stderr index 8e9327b29f7b..1e5b5db692d8 100644 --- a/src/test/ui/error-codes/E0262.stderr +++ b/src/test/ui/error-codes/E0262.stderr @@ -6,4 +6,4 @@ LL | fn foo<'static>(x: &'static str) { } //~ ERROR E0262 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0262" +For more information about this error, try `rustc --explain E0262`. diff --git a/src/test/ui/error-codes/E0263.stderr b/src/test/ui/error-codes/E0263.stderr index 9cd41bed9845..1b52deea88d4 100644 --- a/src/test/ui/error-codes/E0263.stderr +++ b/src/test/ui/error-codes/E0263.stderr @@ -8,4 +8,4 @@ LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0263" +For more information about this error, try `rustc --explain E0263`. diff --git a/src/test/ui/error-codes/E0264.stderr b/src/test/ui/error-codes/E0264.stderr index aad8002fc464..69863d7bb83e 100644 --- a/src/test/ui/error-codes/E0264.stderr +++ b/src/test/ui/error-codes/E0264.stderr @@ -6,4 +6,4 @@ LL | fn cake(); //~ ERROR E0264 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0264" +For more information about this error, try `rustc --explain E0264`. diff --git a/src/test/ui/error-codes/E0267.stderr b/src/test/ui/error-codes/E0267.stderr index fbd7364d966b..b72109f0644e 100644 --- a/src/test/ui/error-codes/E0267.stderr +++ b/src/test/ui/error-codes/E0267.stderr @@ -6,4 +6,4 @@ LL | let w = || { break; }; //~ ERROR E0267 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0267" +For more information about this error, try `rustc --explain E0267`. diff --git a/src/test/ui/error-codes/E0268.stderr b/src/test/ui/error-codes/E0268.stderr index 377ec21c1dd2..e1b5b52085bc 100644 --- a/src/test/ui/error-codes/E0268.stderr +++ b/src/test/ui/error-codes/E0268.stderr @@ -6,4 +6,4 @@ LL | break; //~ ERROR E0268 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0268" +For more information about this error, try `rustc --explain E0268`. diff --git a/src/test/ui/error-codes/E0271.stderr b/src/test/ui/error-codes/E0271.stderr index 1a99afd6a9b0..04c7d244376e 100644 --- a/src/test/ui/error-codes/E0271.stderr +++ b/src/test/ui/error-codes/E0271.stderr @@ -14,4 +14,4 @@ LL | fn foo(t: T) where T: Trait { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0271" +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index 11ec85a5d09c..d5bcc94fb653 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -77,4 +77,4 @@ LL | trait Foo {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0275" +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/error-codes/E0276.stderr b/src/test/ui/error-codes/E0276.stderr index 849e2aafd5a4..4823adc250ae 100644 --- a/src/test/ui/error-codes/E0276.stderr +++ b/src/test/ui/error-codes/E0276.stderr @@ -9,4 +9,4 @@ LL | fn foo(x: T) where T: Copy {} //~ ERROR E0276 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0276" +For more information about this error, try `rustc --explain E0276`. diff --git a/src/test/ui/error-codes/E0277-2.stderr b/src/test/ui/error-codes/E0277-2.stderr index 987bb94bb958..bbe04cfc6e16 100644 --- a/src/test/ui/error-codes/E0277-2.stderr +++ b/src/test/ui/error-codes/E0277-2.stderr @@ -16,4 +16,4 @@ LL | fn is_send() { } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/error-codes/E0277.stderr b/src/test/ui/error-codes/E0277.stderr index 7541e161670f..477128d7d9f0 100644 --- a/src/test/ui/error-codes/E0277.stderr +++ b/src/test/ui/error-codes/E0277.stderr @@ -22,4 +22,4 @@ LL | fn some_func(foo: T) { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/error-codes/E0282.stderr b/src/test/ui/error-codes/E0282.stderr index da5a53a73590..f1319f413958 100644 --- a/src/test/ui/error-codes/E0282.stderr +++ b/src/test/ui/error-codes/E0282.stderr @@ -9,4 +9,4 @@ LL | let x = "hello".chars().rev().collect(); //~ ERROR E0282 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index 9de488cc7aa1..3f63881b61e4 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -12,4 +12,4 @@ LL | fn create() -> u32; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0283" +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/error-codes/E0296.stderr b/src/test/ui/error-codes/E0296.stderr index a35b634cc049..71db4b614a7c 100644 --- a/src/test/ui/error-codes/E0296.stderr +++ b/src/test/ui/error-codes/E0296.stderr @@ -6,4 +6,4 @@ LL | #![recursion_limit] //~ ERROR E0296 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0296" +For more information about this error, try `rustc --explain E0296`. diff --git a/src/test/ui/error-codes/E0297.stderr b/src/test/ui/error-codes/E0297.stderr index 67d5139d386c..d510fa99caec 100644 --- a/src/test/ui/error-codes/E0297.stderr +++ b/src/test/ui/error-codes/E0297.stderr @@ -6,4 +6,4 @@ LL | for Some(x) in xs {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0005" +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/error-codes/E0301.stderr b/src/test/ui/error-codes/E0301.stderr index 04ad3c972467..7d5100c516e5 100644 --- a/src/test/ui/error-codes/E0301.stderr +++ b/src/test/ui/error-codes/E0301.stderr @@ -6,4 +6,4 @@ LL | option if option.take().is_none() => {}, //~ ERROR E0301 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0301" +For more information about this error, try `rustc --explain E0301`. diff --git a/src/test/ui/error-codes/E0302.stderr b/src/test/ui/error-codes/E0302.stderr index a11b85850a9a..f55dd523f130 100644 --- a/src/test/ui/error-codes/E0302.stderr +++ b/src/test/ui/error-codes/E0302.stderr @@ -6,4 +6,4 @@ LL | option if { option = None; false } => { }, //~ ERROR E0302 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0302" +For more information about this error, try `rustc --explain E0302`. diff --git a/src/test/ui/error-codes/E0303.stderr b/src/test/ui/error-codes/E0303.stderr index c0a92ff55d1f..b9da037df0e6 100644 --- a/src/test/ui/error-codes/E0303.stderr +++ b/src/test/ui/error-codes/E0303.stderr @@ -15,5 +15,5 @@ LL | ref op_string_ref @ Some(s) => {}, error: aborting due to 2 previous errors -You've got a few errors: E0009, E0303 -If you want more information on an error, try using "rustc --explain E0009" +Some errors occurred: E0009, E0303. +For more information about an error, try `rustc --explain E0009`. diff --git a/src/test/ui/error-codes/E0308-4.stderr b/src/test/ui/error-codes/E0308-4.stderr index 057791b467f3..31875349bace 100644 --- a/src/test/ui/error-codes/E0308-4.stderr +++ b/src/test/ui/error-codes/E0308-4.stderr @@ -6,4 +6,4 @@ LL | 0u8...3i8 => (), //~ ERROR E0308 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/error-codes/E0308.stderr b/src/test/ui/error-codes/E0308.stderr index 04e5f9da5997..490a8e0ff0f1 100644 --- a/src/test/ui/error-codes/E0308.stderr +++ b/src/test/ui/error-codes/E0308.stderr @@ -9,4 +9,4 @@ LL | fn size_of(); //~ ERROR E0308 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/error-codes/E0365.stderr b/src/test/ui/error-codes/E0365.stderr index ce646eb96be8..efa21aa2e22c 100644 --- a/src/test/ui/error-codes/E0365.stderr +++ b/src/test/ui/error-codes/E0365.stderr @@ -8,4 +8,4 @@ LL | pub use foo as foo2; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0365" +For more information about this error, try `rustc --explain E0365`. diff --git a/src/test/ui/error-codes/E0370.stderr b/src/test/ui/error-codes/E0370.stderr index 60e077e063e0..f85d2cf5d0b0 100644 --- a/src/test/ui/error-codes/E0370.stderr +++ b/src/test/ui/error-codes/E0370.stderr @@ -8,4 +8,4 @@ LL | Y, //~ ERROR E0370 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0370" +For more information about this error, try `rustc --explain E0370`. diff --git a/src/test/ui/error-codes/E0374.stderr b/src/test/ui/error-codes/E0374.stderr index 3441f71dcd18..002e2b003af8 100644 --- a/src/test/ui/error-codes/E0374.stderr +++ b/src/test/ui/error-codes/E0374.stderr @@ -7,4 +7,4 @@ LL | | where T: CoerceUnsized {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0374" +For more information about this error, try `rustc --explain E0374`. diff --git a/src/test/ui/error-codes/E0375.stderr b/src/test/ui/error-codes/E0375.stderr index 7e5ddda61d01..3ffd25084b82 100644 --- a/src/test/ui/error-codes/E0375.stderr +++ b/src/test/ui/error-codes/E0375.stderr @@ -9,4 +9,4 @@ LL | impl CoerceUnsized> for Foo {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0375" +For more information about this error, try `rustc --explain E0375`. diff --git a/src/test/ui/error-codes/E0376.stderr b/src/test/ui/error-codes/E0376.stderr index 13c2e443113a..c850d13e6337 100644 --- a/src/test/ui/error-codes/E0376.stderr +++ b/src/test/ui/error-codes/E0376.stderr @@ -6,4 +6,4 @@ LL | impl CoerceUnsized for Foo {} //~ ERROR E0376 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0376" +For more information about this error, try `rustc --explain E0376`. diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 7c327970b949..d2263cd4034b 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -24,5 +24,5 @@ LL | static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0017 error: aborting due to 4 previous errors -You've got a few errors: E0017, E0596 -If you want more information on an error, try using "rustc --explain E0017" +Some errors occurred: E0017, E0596. +For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/error-codes/E0389.stderr b/src/test/ui/error-codes/E0389.stderr index a24491770c86..29e1ea9dd169 100644 --- a/src/test/ui/error-codes/E0389.stderr +++ b/src/test/ui/error-codes/E0389.stderr @@ -6,4 +6,4 @@ LL | fancy_ref.num = 6; //~ ERROR E0389 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0389" +For more information about this error, try `rustc --explain E0389`. diff --git a/src/test/ui/error-codes/E0390.stderr b/src/test/ui/error-codes/E0390.stderr index 70b62f5771e3..fda2c2e2fe01 100644 --- a/src/test/ui/error-codes/E0390.stderr +++ b/src/test/ui/error-codes/E0390.stderr @@ -12,4 +12,4 @@ LL | impl *mut Foo {} //~ ERROR E0390 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0390" +For more information about this error, try `rustc --explain E0390`. diff --git a/src/test/ui/error-codes/E0392.stderr b/src/test/ui/error-codes/E0392.stderr index 9ee85aa4de3a..cfa9c49b2eeb 100644 --- a/src/test/ui/error-codes/E0392.stderr +++ b/src/test/ui/error-codes/E0392.stderr @@ -8,4 +8,4 @@ LL | enum Foo { Bar } //~ ERROR E0392 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0392" +For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/error-codes/E0393.stderr b/src/test/ui/error-codes/E0393.stderr index f6e77cbb8007..c0e282308c15 100644 --- a/src/test/ui/error-codes/E0393.stderr +++ b/src/test/ui/error-codes/E0393.stderr @@ -8,4 +8,4 @@ LL | fn together_we_will_rule_the_galaxy(son: &A) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0393" +For more information about this error, try `rustc --explain E0393`. diff --git a/src/test/ui/error-codes/E0394.stderr b/src/test/ui/error-codes/E0394.stderr index 74cb5ed03765..6c89957de07e 100644 --- a/src/test/ui/error-codes/E0394.stderr +++ b/src/test/ui/error-codes/E0394.stderr @@ -8,4 +8,4 @@ LL | static B: u32 = A; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0394" +For more information about this error, try `rustc --explain E0394`. diff --git a/src/test/ui/error-codes/E0395.stderr b/src/test/ui/error-codes/E0395.stderr index 5f3d962877ac..ee90df798706 100644 --- a/src/test/ui/error-codes/E0395.stderr +++ b/src/test/ui/error-codes/E0395.stderr @@ -6,4 +6,4 @@ LL | static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; //~ ER error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0395" +For more information about this error, try `rustc --explain E0395`. diff --git a/src/test/ui/error-codes/E0396.stderr b/src/test/ui/error-codes/E0396.stderr index fe20b984216c..87dfd50dc973 100644 --- a/src/test/ui/error-codes/E0396.stderr +++ b/src/test/ui/error-codes/E0396.stderr @@ -6,4 +6,4 @@ LL | const VALUE: u8 = unsafe { *REG_ADDR }; //~ ERROR E0396 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0396" +For more information about this error, try `rustc --explain E0396`. diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index c306ff4a04f6..42c79602cf3a 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -32,4 +32,4 @@ LL | fn helper(sel: &Self) -> u8 { //~ ERROR E0401 error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0401" +For more information about this error, try `rustc --explain E0401`. diff --git a/src/test/ui/error-codes/E0403.stderr b/src/test/ui/error-codes/E0403.stderr index a83d6b674731..f9ccc31654aa 100644 --- a/src/test/ui/error-codes/E0403.stderr +++ b/src/test/ui/error-codes/E0403.stderr @@ -8,4 +8,4 @@ LL | fn foo(s: T, u: T) {} //~ ERROR E0403 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0403" +For more information about this error, try `rustc --explain E0403`. diff --git a/src/test/ui/error-codes/E0404.stderr b/src/test/ui/error-codes/E0404.stderr index ac1d2a00cf44..9f705da58616 100644 --- a/src/test/ui/error-codes/E0404.stderr +++ b/src/test/ui/error-codes/E0404.stderr @@ -12,4 +12,3 @@ LL | fn baz(_: T) {} //~ ERROR E0404 error: cannot continue compilation due to previous error -If you want more information on this error, try using "rustc --explain E0404" diff --git a/src/test/ui/error-codes/E0405.stderr b/src/test/ui/error-codes/E0405.stderr index 0019e16d7f37..b5901dd9c848 100644 --- a/src/test/ui/error-codes/E0405.stderr +++ b/src/test/ui/error-codes/E0405.stderr @@ -6,4 +6,3 @@ LL | impl SomeTrait for Foo {} //~ ERROR E0405 error: cannot continue compilation due to previous error -If you want more information on this error, try using "rustc --explain E0405" diff --git a/src/test/ui/error-codes/E0407.stderr b/src/test/ui/error-codes/E0407.stderr index 2e2bc3aeb55d..1be04a992c24 100644 --- a/src/test/ui/error-codes/E0407.stderr +++ b/src/test/ui/error-codes/E0407.stderr @@ -6,4 +6,4 @@ LL | fn b() {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0407" +For more information about this error, try `rustc --explain E0407`. diff --git a/src/test/ui/error-codes/E0408.stderr b/src/test/ui/error-codes/E0408.stderr index 1f928275bd5c..46845de1aadd 100644 --- a/src/test/ui/error-codes/E0408.stderr +++ b/src/test/ui/error-codes/E0408.stderr @@ -8,4 +8,4 @@ LL | Some(y) | None => {} //~ ERROR variable `y` is not bound in all pa error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0408" +For more information about this error, try `rustc --explain E0408`. diff --git a/src/test/ui/error-codes/E0411.stderr b/src/test/ui/error-codes/E0411.stderr index b0336d7d6688..a5f2e3a7b93d 100644 --- a/src/test/ui/error-codes/E0411.stderr +++ b/src/test/ui/error-codes/E0411.stderr @@ -6,4 +6,4 @@ LL | ::foo; //~ ERROR E0411 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0411" +For more information about this error, try `rustc --explain E0411`. diff --git a/src/test/ui/error-codes/E0412.stderr b/src/test/ui/error-codes/E0412.stderr index 4444af73a7ef..61115c8b2920 100644 --- a/src/test/ui/error-codes/E0412.stderr +++ b/src/test/ui/error-codes/E0412.stderr @@ -6,4 +6,4 @@ LL | impl Something {} //~ ERROR E0412 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0412" +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/error-codes/E0415.stderr b/src/test/ui/error-codes/E0415.stderr index 82c6284e4339..3f036f3a534b 100644 --- a/src/test/ui/error-codes/E0415.stderr +++ b/src/test/ui/error-codes/E0415.stderr @@ -6,4 +6,4 @@ LL | fn foo(f: i32, f: i32) {} //~ ERROR E0415 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0415" +For more information about this error, try `rustc --explain E0415`. diff --git a/src/test/ui/error-codes/E0416.stderr b/src/test/ui/error-codes/E0416.stderr index 35daf20a2234..8815bb2ad840 100644 --- a/src/test/ui/error-codes/E0416.stderr +++ b/src/test/ui/error-codes/E0416.stderr @@ -6,4 +6,4 @@ LL | (x, x) => {} //~ ERROR E0416 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0416" +For more information about this error, try `rustc --explain E0416`. diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index 112754e75b83..ef24295332d5 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -6,4 +6,4 @@ LL | let f = Foo(); //~ ERROR E0423 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0423" +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/error-codes/E0424.stderr b/src/test/ui/error-codes/E0424.stderr index 5f2d56730676..2c4f7f7c62b3 100644 --- a/src/test/ui/error-codes/E0424.stderr +++ b/src/test/ui/error-codes/E0424.stderr @@ -6,4 +6,4 @@ LL | self.bar(); //~ ERROR E0424 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0424" +For more information about this error, try `rustc --explain E0424`. diff --git a/src/test/ui/error-codes/E0425.stderr b/src/test/ui/error-codes/E0425.stderr index 9d27e4f59444..72756baf8efc 100644 --- a/src/test/ui/error-codes/E0425.stderr +++ b/src/test/ui/error-codes/E0425.stderr @@ -6,4 +6,4 @@ LL | elf; //~ ERROR E0425 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/error-codes/E0426.stderr b/src/test/ui/error-codes/E0426.stderr index 5e0bc69b1eb4..29249ab3919e 100644 --- a/src/test/ui/error-codes/E0426.stderr +++ b/src/test/ui/error-codes/E0426.stderr @@ -6,4 +6,4 @@ LL | break 'a; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0426" +For more information about this error, try `rustc --explain E0426`. diff --git a/src/test/ui/error-codes/E0428.stderr b/src/test/ui/error-codes/E0428.stderr index 20f734af0817..ebfe866625d8 100644 --- a/src/test/ui/error-codes/E0428.stderr +++ b/src/test/ui/error-codes/E0428.stderr @@ -10,4 +10,4 @@ LL | struct Bar; //~ ERROR E0428 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0428" +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/ui/error-codes/E0429.stderr b/src/test/ui/error-codes/E0429.stderr index a72c77360b57..d36155fb466e 100644 --- a/src/test/ui/error-codes/E0429.stderr +++ b/src/test/ui/error-codes/E0429.stderr @@ -6,4 +6,4 @@ LL | use std::fmt::self; //~ ERROR E0429 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0429" +For more information about this error, try `rustc --explain E0429`. diff --git a/src/test/ui/error-codes/E0430.stderr b/src/test/ui/error-codes/E0430.stderr index b6448ec18c3d..c50ed4ea5de8 100644 --- a/src/test/ui/error-codes/E0430.stderr +++ b/src/test/ui/error-codes/E0430.stderr @@ -22,5 +22,5 @@ LL | use std::fmt::{self, self as other_fmt}; //~ ERROR E0430 error: aborting due to 2 previous errors -You've got a few errors: E0252, E0430 -If you want more information on an error, try using "rustc --explain E0252" +Some errors occurred: E0252, E0430. +For more information about an error, try `rustc --explain E0252`. diff --git a/src/test/ui/error-codes/E0431.stderr b/src/test/ui/error-codes/E0431.stderr index 364ba0aa9578..75b8486aa5cc 100644 --- a/src/test/ui/error-codes/E0431.stderr +++ b/src/test/ui/error-codes/E0431.stderr @@ -6,4 +6,4 @@ LL | use {self}; //~ ERROR E0431 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0431" +For more information about this error, try `rustc --explain E0431`. diff --git a/src/test/ui/error-codes/E0432.stderr b/src/test/ui/error-codes/E0432.stderr index 747b337d3635..291bb4507559 100644 --- a/src/test/ui/error-codes/E0432.stderr +++ b/src/test/ui/error-codes/E0432.stderr @@ -6,4 +6,4 @@ LL | use something::Foo; //~ ERROR E0432 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0432" +For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/error-codes/E0433.stderr b/src/test/ui/error-codes/E0433.stderr index 7635d9738ad9..f8cf5f6f92f6 100644 --- a/src/test/ui/error-codes/E0433.stderr +++ b/src/test/ui/error-codes/E0433.stderr @@ -6,4 +6,4 @@ LL | let map = HashMap::new(); //~ ERROR E0433 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0433" +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/error-codes/E0434.stderr b/src/test/ui/error-codes/E0434.stderr index b13c0cf79717..bbbc7d16e3ba 100644 --- a/src/test/ui/error-codes/E0434.stderr +++ b/src/test/ui/error-codes/E0434.stderr @@ -8,4 +8,4 @@ LL | y //~ ERROR E0434 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0434" +For more information about this error, try `rustc --explain E0434`. diff --git a/src/test/ui/error-codes/E0435.stderr b/src/test/ui/error-codes/E0435.stderr index 5ca79e72c2b4..517fddfa1ac1 100644 --- a/src/test/ui/error-codes/E0435.stderr +++ b/src/test/ui/error-codes/E0435.stderr @@ -6,4 +6,4 @@ LL | let _: [u8; foo]; //~ ERROR E0435 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0435" +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/error-codes/E0437.stderr b/src/test/ui/error-codes/E0437.stderr index 408924b0439a..790e306f121b 100644 --- a/src/test/ui/error-codes/E0437.stderr +++ b/src/test/ui/error-codes/E0437.stderr @@ -6,4 +6,4 @@ LL | type Bar = bool; //~ ERROR E0437 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0437" +For more information about this error, try `rustc --explain E0437`. diff --git a/src/test/ui/error-codes/E0438.stderr b/src/test/ui/error-codes/E0438.stderr index b636236e41ab..5f311e9bca98 100644 --- a/src/test/ui/error-codes/E0438.stderr +++ b/src/test/ui/error-codes/E0438.stderr @@ -6,4 +6,4 @@ LL | const BAR: bool = true; //~ ERROR E0438 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0438" +For more information about this error, try `rustc --explain E0438`. diff --git a/src/test/ui/error-codes/E0439.stderr b/src/test/ui/error-codes/E0439.stderr index 27a090431258..1400633001ac 100644 --- a/src/test/ui/error-codes/E0439.stderr +++ b/src/test/ui/error-codes/E0439.stderr @@ -6,4 +6,4 @@ LL | fn simd_shuffle(a: A, b: A, c: [u32; 8]) -> B; //~ ERROR E0439 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0439" +For more information about this error, try `rustc --explain E0439`. diff --git a/src/test/ui/error-codes/E0440.stderr b/src/test/ui/error-codes/E0440.stderr index c9ac1b8261bd..acaa948a3315 100644 --- a/src/test/ui/error-codes/E0440.stderr +++ b/src/test/ui/error-codes/E0440.stderr @@ -6,4 +6,4 @@ LL | fn x86_mm_movemask_pd(x: f64x2) -> i32; //~ ERROR E0440 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0440" +For more information about this error, try `rustc --explain E0440`. diff --git a/src/test/ui/error-codes/E0441.stderr b/src/test/ui/error-codes/E0441.stderr index 1cb4193bd34b..8a01176dbbee 100644 --- a/src/test/ui/error-codes/E0441.stderr +++ b/src/test/ui/error-codes/E0441.stderr @@ -6,4 +6,4 @@ LL | fn x86_mm_adds_ep16(x: i16x8, y: i16x8) -> i16x8; //~ ERROR E0441 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0441" +For more information about this error, try `rustc --explain E0441`. diff --git a/src/test/ui/error-codes/E0442.stderr b/src/test/ui/error-codes/E0442.stderr index 2119ea11a663..01881e1b5c38 100644 --- a/src/test/ui/error-codes/E0442.stderr +++ b/src/test/ui/error-codes/E0442.stderr @@ -18,4 +18,4 @@ LL | fn x86_mm_adds_epi16(x: i8x16, y: i32x4) -> i64x2; error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0442" +For more information about this error, try `rustc --explain E0442`. diff --git a/src/test/ui/error-codes/E0443.stderr b/src/test/ui/error-codes/E0443.stderr index 8a08bd9762e0..b57c9423fce7 100644 --- a/src/test/ui/error-codes/E0443.stderr +++ b/src/test/ui/error-codes/E0443.stderr @@ -6,4 +6,4 @@ LL | fn x86_mm_adds_epi16(x: i16x8, y: i16x8) -> i64x8; //~ ERROR E0443 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0443" +For more information about this error, try `rustc --explain E0443`. diff --git a/src/test/ui/error-codes/E0444.stderr b/src/test/ui/error-codes/E0444.stderr index 7e20e47b165f..338c9dac75e3 100644 --- a/src/test/ui/error-codes/E0444.stderr +++ b/src/test/ui/error-codes/E0444.stderr @@ -6,4 +6,4 @@ LL | fn x86_mm_movemask_pd(x: f64x2, y: f64x2, z: f64x2) -> i32; //~ ERROR E error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0444" +For more information about this error, try `rustc --explain E0444`. diff --git a/src/test/ui/error-codes/E0445.stderr b/src/test/ui/error-codes/E0445.stderr index 6e0616277f4e..552de83a65e0 100644 --- a/src/test/ui/error-codes/E0445.stderr +++ b/src/test/ui/error-codes/E0445.stderr @@ -18,4 +18,4 @@ LL | pub fn foo (t: T) {} error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0445" +For more information about this error, try `rustc --explain E0445`. diff --git a/src/test/ui/error-codes/E0446.stderr b/src/test/ui/error-codes/E0446.stderr index 067fdb47da93..bb5ae494d6c8 100644 --- a/src/test/ui/error-codes/E0446.stderr +++ b/src/test/ui/error-codes/E0446.stderr @@ -8,4 +8,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0446" +For more information about this error, try `rustc --explain E0446`. diff --git a/src/test/ui/error-codes/E0449.stderr b/src/test/ui/error-codes/E0449.stderr index 68ec6379d711..480d8c40022d 100644 --- a/src/test/ui/error-codes/E0449.stderr +++ b/src/test/ui/error-codes/E0449.stderr @@ -20,4 +20,4 @@ LL | pub fn foo() {} //~ ERROR E0449 error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0449" +For more information about this error, try `rustc --explain E0449`. diff --git a/src/test/ui/error-codes/E0451.stderr b/src/test/ui/error-codes/E0451.stderr index 003a93811bd9..4d54e17d5070 100644 --- a/src/test/ui/error-codes/E0451.stderr +++ b/src/test/ui/error-codes/E0451.stderr @@ -12,4 +12,4 @@ LL | let f = Bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0451" +For more information about this error, try `rustc --explain E0451`. diff --git a/src/test/ui/error-codes/E0452.stderr b/src/test/ui/error-codes/E0452.stderr index 6e4b47e9631c..a915ca1d6746 100644 --- a/src/test/ui/error-codes/E0452.stderr +++ b/src/test/ui/error-codes/E0452.stderr @@ -6,4 +6,4 @@ LL | #![allow(foo = "")] //~ ERROR E0452 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0452" +For more information about this error, try `rustc --explain E0452`. diff --git a/src/test/ui/error-codes/E0453.stderr b/src/test/ui/error-codes/E0453.stderr index 646b98b84738..59e1a1cfdfc4 100644 --- a/src/test/ui/error-codes/E0453.stderr +++ b/src/test/ui/error-codes/E0453.stderr @@ -9,4 +9,4 @@ LL | #[allow(non_snake_case)] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0453" +For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/error-codes/E0454.stderr b/src/test/ui/error-codes/E0454.stderr index 11f1958bf96c..44dde5386660 100644 --- a/src/test/ui/error-codes/E0454.stderr +++ b/src/test/ui/error-codes/E0454.stderr @@ -6,4 +6,4 @@ LL | #[link(name = "")] extern {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0454" +For more information about this error, try `rustc --explain E0454`. diff --git a/src/test/ui/error-codes/E0458.stderr b/src/test/ui/error-codes/E0458.stderr index 4bcafa47d358..5304e7c2d271 100644 --- a/src/test/ui/error-codes/E0458.stderr +++ b/src/test/ui/error-codes/E0458.stderr @@ -12,5 +12,5 @@ LL | #[link(kind = "wonderful_unicorn")] extern {} //~ ERROR E0458 error: aborting due to 2 previous errors -You've got a few errors: E0458, E0459 -If you want more information on an error, try using "rustc --explain E0458" +Some errors occurred: E0458, E0459. +For more information about an error, try `rustc --explain E0458`. diff --git a/src/test/ui/error-codes/E0459.stderr b/src/test/ui/error-codes/E0459.stderr index c443e78ab3ad..8f31e7b4b13c 100644 --- a/src/test/ui/error-codes/E0459.stderr +++ b/src/test/ui/error-codes/E0459.stderr @@ -6,4 +6,4 @@ LL | #[link(kind = "dylib")] extern {} //~ ERROR E0459 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0459" +For more information about this error, try `rustc --explain E0459`. diff --git a/src/test/ui/error-codes/E0463.stderr b/src/test/ui/error-codes/E0463.stderr index 41575b70d15c..26403827e4a8 100644 --- a/src/test/ui/error-codes/E0463.stderr +++ b/src/test/ui/error-codes/E0463.stderr @@ -6,4 +6,4 @@ LL | #![plugin(cookie_monster)] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0463" +For more information about this error, try `rustc --explain E0463`. diff --git a/src/test/ui/error-codes/E0478.stderr b/src/test/ui/error-codes/E0478.stderr index bbc243a37574..44d8151303f7 100644 --- a/src/test/ui/error-codes/E0478.stderr +++ b/src/test/ui/error-codes/E0478.stderr @@ -17,4 +17,4 @@ LL | struct Prince<'kiss, 'SnowWhite> { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0478" +For more information about this error, try `rustc --explain E0478`. diff --git a/src/test/ui/error-codes/E0492.stderr b/src/test/ui/error-codes/E0492.stderr index 359c63bb8ff7..157a19296902 100644 --- a/src/test/ui/error-codes/E0492.stderr +++ b/src/test/ui/error-codes/E0492.stderr @@ -6,4 +6,4 @@ LL | static B: &'static AtomicUsize = &A; //~ ERROR E0492 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0492" +For more information about this error, try `rustc --explain E0492`. diff --git a/src/test/ui/error-codes/E0494.stderr b/src/test/ui/error-codes/E0494.stderr index 82dd74c012b0..65e6b1fe670f 100644 --- a/src/test/ui/error-codes/E0494.stderr +++ b/src/test/ui/error-codes/E0494.stderr @@ -6,4 +6,4 @@ LL | static A : &'static u32 = &S.a; //~ ERROR E0494 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0494" +For more information about this error, try `rustc --explain E0494`. diff --git a/src/test/ui/error-codes/E0496.stderr b/src/test/ui/error-codes/E0496.stderr index 945c2391d030..198daa512bda 100644 --- a/src/test/ui/error-codes/E0496.stderr +++ b/src/test/ui/error-codes/E0496.stderr @@ -8,4 +8,4 @@ LL | fn f<'a>(x: &'a i32) { //~ ERROR E0496 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0496" +For more information about this error, try `rustc --explain E0496`. diff --git a/src/test/ui/error-codes/E0499.stderr b/src/test/ui/error-codes/E0499.stderr index 5332df0c2354..dcb477ab1cb8 100644 --- a/src/test/ui/error-codes/E0499.stderr +++ b/src/test/ui/error-codes/E0499.stderr @@ -10,4 +10,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0499" +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/error-codes/E0502.stderr b/src/test/ui/error-codes/E0502.stderr index 07430990f0a5..d377fa883dd8 100644 --- a/src/test/ui/error-codes/E0502.stderr +++ b/src/test/ui/error-codes/E0502.stderr @@ -10,4 +10,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0502" +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/error-codes/E0503.stderr b/src/test/ui/error-codes/E0503.stderr index ac6634cb64f2..0342ebc41936 100644 --- a/src/test/ui/error-codes/E0503.stderr +++ b/src/test/ui/error-codes/E0503.stderr @@ -8,4 +8,4 @@ LL | let _sum = value + 1; //~ ERROR E0503 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0503" +For more information about this error, try `rustc --explain E0503`. diff --git a/src/test/ui/error-codes/E0504.stderr b/src/test/ui/error-codes/E0504.stderr index 9f3bd79dcfe7..cd1d3ec5ba47 100644 --- a/src/test/ui/error-codes/E0504.stderr +++ b/src/test/ui/error-codes/E0504.stderr @@ -9,4 +9,4 @@ LL | println!("child function: {}", fancy_num.num); //~ ERROR E0504 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0504" +For more information about this error, try `rustc --explain E0504`. diff --git a/src/test/ui/error-codes/E0505.stderr b/src/test/ui/error-codes/E0505.stderr index 71392857d0ae..64558ba8c7c0 100644 --- a/src/test/ui/error-codes/E0505.stderr +++ b/src/test/ui/error-codes/E0505.stderr @@ -8,4 +8,4 @@ LL | eat(x); //~ ERROR E0505 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0505" +For more information about this error, try `rustc --explain E0505`. diff --git a/src/test/ui/error-codes/E0507.stderr b/src/test/ui/error-codes/E0507.stderr index de94648ec0bc..3d9d8a5145d0 100644 --- a/src/test/ui/error-codes/E0507.stderr +++ b/src/test/ui/error-codes/E0507.stderr @@ -6,4 +6,4 @@ LL | x.borrow().nothing_is_true(); //~ ERROR E0507 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0507" +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/error-codes/E0509.stderr b/src/test/ui/error-codes/E0509.stderr index 3bc2a4450a18..3952081a2655 100644 --- a/src/test/ui/error-codes/E0509.stderr +++ b/src/test/ui/error-codes/E0509.stderr @@ -9,4 +9,4 @@ LL | let fancy_field = drop_struct.fancy; //~ ERROR E0509 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0509" +For more information about this error, try `rustc --explain E0509`. diff --git a/src/test/ui/error-codes/E0511.stderr b/src/test/ui/error-codes/E0511.stderr index 0273735562d9..1b8d125cf1a0 100644 --- a/src/test/ui/error-codes/E0511.stderr +++ b/src/test/ui/error-codes/E0511.stderr @@ -6,4 +6,4 @@ LL | unsafe { simd_add(0, 1); } //~ ERROR E0511 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0511" +For more information about this error, try `rustc --explain E0511`. diff --git a/src/test/ui/error-codes/E0512.stderr b/src/test/ui/error-codes/E0512.stderr index bcce48c0cd50..c91f6ad8f0af 100644 --- a/src/test/ui/error-codes/E0512.stderr +++ b/src/test/ui/error-codes/E0512.stderr @@ -9,4 +9,4 @@ LL | unsafe { takes_u8(::std::mem::transmute(0u16)); } //~ ERROR E0512 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0512" +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/error-codes/E0516.stderr b/src/test/ui/error-codes/E0516.stderr index bae85cabced5..d298e288859d 100644 --- a/src/test/ui/error-codes/E0516.stderr +++ b/src/test/ui/error-codes/E0516.stderr @@ -6,4 +6,4 @@ LL | let x: typeof(92) = 92; //~ ERROR E0516 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0516" +For more information about this error, try `rustc --explain E0516`. diff --git a/src/test/ui/error-codes/E0517.stderr b/src/test/ui/error-codes/E0517.stderr index fbaeb6fabbbd..4779fd08c684 100644 --- a/src/test/ui/error-codes/E0517.stderr +++ b/src/test/ui/error-codes/E0517.stderr @@ -33,4 +33,4 @@ LL | | } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0517" +For more information about this error, try `rustc --explain E0517`. diff --git a/src/test/ui/error-codes/E0518.stderr b/src/test/ui/error-codes/E0518.stderr index 3d199c7fa7fe..d8feec991406 100644 --- a/src/test/ui/error-codes/E0518.stderr +++ b/src/test/ui/error-codes/E0518.stderr @@ -17,4 +17,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0518" +For more information about this error, try `rustc --explain E0518`. diff --git a/src/test/ui/error-codes/E0520.stderr b/src/test/ui/error-codes/E0520.stderr index a79f11f63e7c..67ec1d427157 100644 --- a/src/test/ui/error-codes/E0520.stderr +++ b/src/test/ui/error-codes/E0520.stderr @@ -13,4 +13,4 @@ LL | default fn fly(&self) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0520" +For more information about this error, try `rustc --explain E0520`. diff --git a/src/test/ui/error-codes/E0522.stderr b/src/test/ui/error-codes/E0522.stderr index c67e7bea34d5..5a6331bca0bd 100644 --- a/src/test/ui/error-codes/E0522.stderr +++ b/src/test/ui/error-codes/E0522.stderr @@ -8,5 +8,5 @@ LL | #[lang = "cookie"] error: aborting due to 2 previous errors -You've got a few errors: E0522, E0601 -If you want more information on an error, try using "rustc --explain E0522" +Some errors occurred: E0522, E0601. +For more information about an error, try `rustc --explain E0522`. diff --git a/src/test/ui/error-codes/E0527.stderr b/src/test/ui/error-codes/E0527.stderr index d9f992240577..2060f1e69e0c 100644 --- a/src/test/ui/error-codes/E0527.stderr +++ b/src/test/ui/error-codes/E0527.stderr @@ -6,4 +6,4 @@ LL | &[a, b] => { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0527" +For more information about this error, try `rustc --explain E0527`. diff --git a/src/test/ui/error-codes/E0528.stderr b/src/test/ui/error-codes/E0528.stderr index 824fae59588a..ca9f8f454575 100644 --- a/src/test/ui/error-codes/E0528.stderr +++ b/src/test/ui/error-codes/E0528.stderr @@ -6,4 +6,4 @@ LL | &[a, b, c, rest..] => { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0528" +For more information about this error, try `rustc --explain E0528`. diff --git a/src/test/ui/error-codes/E0529.stderr b/src/test/ui/error-codes/E0529.stderr index 5031f717c82a..fcada0007906 100644 --- a/src/test/ui/error-codes/E0529.stderr +++ b/src/test/ui/error-codes/E0529.stderr @@ -6,4 +6,4 @@ LL | [a, b] => { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0529" +For more information about this error, try `rustc --explain E0529`. diff --git a/src/test/ui/error-codes/E0530.stderr b/src/test/ui/error-codes/E0530.stderr index 2a76eb140871..e157ca9042cd 100644 --- a/src/test/ui/error-codes/E0530.stderr +++ b/src/test/ui/error-codes/E0530.stderr @@ -9,4 +9,4 @@ LL | TEST => {} //~ ERROR E0530 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0530" +For more information about this error, try `rustc --explain E0530`. diff --git a/src/test/ui/error-codes/E0532.stderr b/src/test/ui/error-codes/E0532.stderr index 04102f4dbef1..faccd10ec6d0 100644 --- a/src/test/ui/error-codes/E0532.stderr +++ b/src/test/ui/error-codes/E0532.stderr @@ -6,4 +6,4 @@ LL | StructConst1(_) => { }, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0532" +For more information about this error, try `rustc --explain E0532`. diff --git a/src/test/ui/error-codes/E0534.stderr b/src/test/ui/error-codes/E0534.stderr index 7f56f6b11f17..30890882cc3e 100644 --- a/src/test/ui/error-codes/E0534.stderr +++ b/src/test/ui/error-codes/E0534.stderr @@ -6,4 +6,4 @@ LL | #[inline()] //~ ERROR E0534 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0534" +For more information about this error, try `rustc --explain E0534`. diff --git a/src/test/ui/error-codes/E0558.stderr b/src/test/ui/error-codes/E0558.stderr index cf2ee9a11600..0cb8af992941 100644 --- a/src/test/ui/error-codes/E0558.stderr +++ b/src/test/ui/error-codes/E0558.stderr @@ -6,4 +6,4 @@ LL | #[export_name] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0558" +For more information about this error, try `rustc --explain E0558`. diff --git a/src/test/ui/error-codes/E0559.stderr b/src/test/ui/error-codes/E0559.stderr index 5e0382de5c93..cb9059ee5380 100644 --- a/src/test/ui/error-codes/E0559.stderr +++ b/src/test/ui/error-codes/E0559.stderr @@ -8,4 +8,4 @@ LL | let s = Field::Fool { joke: 0 }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0559" +For more information about this error, try `rustc --explain E0559`. diff --git a/src/test/ui/error-codes/E0560.stderr b/src/test/ui/error-codes/E0560.stderr index 1b4e62425f0e..66fb04111dbd 100644 --- a/src/test/ui/error-codes/E0560.stderr +++ b/src/test/ui/error-codes/E0560.stderr @@ -8,4 +8,4 @@ LL | let s = Simba { mother: 1, father: 0 }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0560" +For more information about this error, try `rustc --explain E0560`. diff --git a/src/test/ui/error-codes/E0565-1.stderr b/src/test/ui/error-codes/E0565-1.stderr index f393aa56f9c7..745e79ba2ec0 100644 --- a/src/test/ui/error-codes/E0565-1.stderr +++ b/src/test/ui/error-codes/E0565-1.stderr @@ -6,4 +6,4 @@ LL | #[deprecated("since")] //~ ERROR E0565 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0565" +For more information about this error, try `rustc --explain E0565`. diff --git a/src/test/ui/error-codes/E0565.stderr b/src/test/ui/error-codes/E0565.stderr index c0c1b7b2743e..1d0f34be39be 100644 --- a/src/test/ui/error-codes/E0565.stderr +++ b/src/test/ui/error-codes/E0565.stderr @@ -6,4 +6,4 @@ LL | #[repr("C")] //~ ERROR E0565 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0565" +For more information about this error, try `rustc --explain E0565`. diff --git a/src/test/ui/error-codes/E0572.stderr b/src/test/ui/error-codes/E0572.stderr index 199476248a4f..b2896c3892d3 100644 --- a/src/test/ui/error-codes/E0572.stderr +++ b/src/test/ui/error-codes/E0572.stderr @@ -6,4 +6,4 @@ LL | const FOO: u32 = return 0; //~ ERROR E0572 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0572" +For more information about this error, try `rustc --explain E0572`. diff --git a/src/test/ui/error-codes/E0582.stderr b/src/test/ui/error-codes/E0582.stderr index 1bb3049a3f75..c92e0b9f1370 100644 --- a/src/test/ui/error-codes/E0582.stderr +++ b/src/test/ui/error-codes/E0582.stderr @@ -12,4 +12,4 @@ LL | where F: for<'a> Iterator error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0582" +For more information about this error, try `rustc --explain E0582`. diff --git a/src/test/ui/error-codes/E0585.stderr b/src/test/ui/error-codes/E0585.stderr index 063acd2e653b..ef0825939c36 100644 --- a/src/test/ui/error-codes/E0585.stderr +++ b/src/test/ui/error-codes/E0585.stderr @@ -8,4 +8,4 @@ LL | /// Hello! I'm useless... error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0585" +For more information about this error, try `rustc --explain E0585`. diff --git a/src/test/ui/error-codes/E0586.stderr b/src/test/ui/error-codes/E0586.stderr index 352927244984..bd72fbee1604 100644 --- a/src/test/ui/error-codes/E0586.stderr +++ b/src/test/ui/error-codes/E0586.stderr @@ -8,4 +8,4 @@ LL | let x = &tmp[1..=]; //~ ERROR E0586 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0586" +For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/error-codes/E0597.stderr b/src/test/ui/error-codes/E0597.stderr index 41035493bfca..5897cc13c94e 100644 --- a/src/test/ui/error-codes/E0597.stderr +++ b/src/test/ui/error-codes/E0597.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/error-codes/E0599.stderr b/src/test/ui/error-codes/E0599.stderr index a9bb3e502956..d118939d17a1 100644 --- a/src/test/ui/error-codes/E0599.stderr +++ b/src/test/ui/error-codes/E0599.stderr @@ -9,4 +9,4 @@ LL | || if let Foo::NotEvenReal() = Foo {}; //~ ERROR E0599 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/error-codes/E0600.stderr b/src/test/ui/error-codes/E0600.stderr index add05ac30622..500feb39f5e7 100644 --- a/src/test/ui/error-codes/E0600.stderr +++ b/src/test/ui/error-codes/E0600.stderr @@ -6,4 +6,4 @@ LL | !"a"; //~ ERROR E0600 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0600" +For more information about this error, try `rustc --explain E0600`. diff --git a/src/test/ui/error-codes/E0602.stderr b/src/test/ui/error-codes/E0602.stderr index fb1144b616d1..863600410261 100644 --- a/src/test/ui/error-codes/E0602.stderr +++ b/src/test/ui/error-codes/E0602.stderr @@ -4,4 +4,4 @@ error[E0602]: unknown lint: `bogus` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0602" +For more information about this error, try `rustc --explain E0602`. diff --git a/src/test/ui/error-codes/E0603.stderr b/src/test/ui/error-codes/E0603.stderr index db451cbc0fcd..3447f3378294 100644 --- a/src/test/ui/error-codes/E0603.stderr +++ b/src/test/ui/error-codes/E0603.stderr @@ -6,4 +6,4 @@ LL | SomeModule::PRIVATE; //~ ERROR E0603 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0603" +For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/error-codes/E0604.stderr b/src/test/ui/error-codes/E0604.stderr index 875f326df37e..6aa176d1313b 100644 --- a/src/test/ui/error-codes/E0604.stderr +++ b/src/test/ui/error-codes/E0604.stderr @@ -6,4 +6,4 @@ LL | 1u32 as char; //~ ERROR E0604 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0604" +For more information about this error, try `rustc --explain E0604`. diff --git a/src/test/ui/error-codes/E0605.stderr b/src/test/ui/error-codes/E0605.stderr index 4e1f47cebb72..e66e1c12d8f7 100644 --- a/src/test/ui/error-codes/E0605.stderr +++ b/src/test/ui/error-codes/E0605.stderr @@ -16,4 +16,4 @@ LL | v as &u8; //~ ERROR E0605 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0605" +For more information about this error, try `rustc --explain E0605`. diff --git a/src/test/ui/error-codes/E0606.stderr b/src/test/ui/error-codes/E0606.stderr index 3c90e2d4beba..bd5bc908f729 100644 --- a/src/test/ui/error-codes/E0606.stderr +++ b/src/test/ui/error-codes/E0606.stderr @@ -12,4 +12,4 @@ LL | &0u8 as u8; //~ ERROR E0606 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0606" +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/error-codes/E0607.stderr b/src/test/ui/error-codes/E0607.stderr index 62d2c2163bfa..d109908bc746 100644 --- a/src/test/ui/error-codes/E0607.stderr +++ b/src/test/ui/error-codes/E0607.stderr @@ -6,4 +6,4 @@ LL | v as *const [u8]; //~ ERROR E0607 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0607" +For more information about this error, try `rustc --explain E0607`. diff --git a/src/test/ui/error-codes/E0608.stderr b/src/test/ui/error-codes/E0608.stderr index 43227b4f0a35..d5955d1b0707 100644 --- a/src/test/ui/error-codes/E0608.stderr +++ b/src/test/ui/error-codes/E0608.stderr @@ -6,4 +6,4 @@ LL | 0u8[2]; //~ ERROR E0608 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0608" +For more information about this error, try `rustc --explain E0608`. diff --git a/src/test/ui/error-codes/E0609.stderr b/src/test/ui/error-codes/E0609.stderr index 70deb168168e..24581889ae95 100644 --- a/src/test/ui/error-codes/E0609.stderr +++ b/src/test/ui/error-codes/E0609.stderr @@ -14,4 +14,4 @@ LL | y.1; //~ ERROR E0609 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0609" +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/error-codes/E0610.stderr b/src/test/ui/error-codes/E0610.stderr index d6b14642546a..3f1cda3b447d 100644 --- a/src/test/ui/error-codes/E0610.stderr +++ b/src/test/ui/error-codes/E0610.stderr @@ -6,4 +6,4 @@ LL | let _ = x.foo; //~ ERROR E0610 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0610" +For more information about this error, try `rustc --explain E0610`. diff --git a/src/test/ui/error-codes/E0611.stderr b/src/test/ui/error-codes/E0611.stderr index 90194afe4ffe..c4b86e76c14e 100644 --- a/src/test/ui/error-codes/E0611.stderr +++ b/src/test/ui/error-codes/E0611.stderr @@ -6,4 +6,4 @@ LL | y.0; //~ ERROR E0611 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0611" +For more information about this error, try `rustc --explain E0611`. diff --git a/src/test/ui/error-codes/E0612.stderr b/src/test/ui/error-codes/E0612.stderr index 5c27635097f7..18013697a833 100644 --- a/src/test/ui/error-codes/E0612.stderr +++ b/src/test/ui/error-codes/E0612.stderr @@ -6,4 +6,4 @@ LL | y.1; //~ ERROR E0612 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0612" +For more information about this error, try `rustc --explain E0612`. diff --git a/src/test/ui/error-codes/E0614.stderr b/src/test/ui/error-codes/E0614.stderr index b68887ef36b7..571d6e76776a 100644 --- a/src/test/ui/error-codes/E0614.stderr +++ b/src/test/ui/error-codes/E0614.stderr @@ -6,4 +6,4 @@ LL | *y; //~ ERROR E0614 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0614" +For more information about this error, try `rustc --explain E0614`. diff --git a/src/test/ui/error-codes/E0615.stderr b/src/test/ui/error-codes/E0615.stderr index 39e63825d6a1..88317a34ee3f 100644 --- a/src/test/ui/error-codes/E0615.stderr +++ b/src/test/ui/error-codes/E0615.stderr @@ -8,4 +8,4 @@ LL | f.method; //~ ERROR E0615 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0615" +For more information about this error, try `rustc --explain E0615`. diff --git a/src/test/ui/error-codes/E0616.stderr b/src/test/ui/error-codes/E0616.stderr index 38065f048ad0..26525863c0d8 100644 --- a/src/test/ui/error-codes/E0616.stderr +++ b/src/test/ui/error-codes/E0616.stderr @@ -6,4 +6,4 @@ LL | f.x; //~ ERROR E0616 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0616" +For more information about this error, try `rustc --explain E0616`. diff --git a/src/test/ui/error-codes/E0617.stderr b/src/test/ui/error-codes/E0617.stderr index 11b1bf32ee01..114220532c3f 100644 --- a/src/test/ui/error-codes/E0617.stderr +++ b/src/test/ui/error-codes/E0617.stderr @@ -40,4 +40,4 @@ LL | printf(::std::ptr::null(), printf as unsafe extern "C" fn(*const i8 error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0617" +For more information about this error, try `rustc --explain E0617`. diff --git a/src/test/ui/error-codes/E0618.stderr b/src/test/ui/error-codes/E0618.stderr index 41ef37dca543..ef7ace44d59a 100644 --- a/src/test/ui/error-codes/E0618.stderr +++ b/src/test/ui/error-codes/E0618.stderr @@ -21,4 +21,4 @@ LL | x(); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0618" +For more information about this error, try `rustc --explain E0618`. diff --git a/src/test/ui/error-codes/E0620.stderr b/src/test/ui/error-codes/E0620.stderr index 310dddc26f08..f7450a331386 100644 --- a/src/test/ui/error-codes/E0620.stderr +++ b/src/test/ui/error-codes/E0620.stderr @@ -12,4 +12,4 @@ LL | let _foo = &[1_usize, 2] as [usize]; //~ ERROR E0620 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0620" +For more information about this error, try `rustc --explain E0620`. diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr index fa11d7c77c0f..58f0ede63080 100644 --- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr +++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.stderr @@ -27,4 +27,4 @@ LL | invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0495" +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/error-codes/E0622.stderr b/src/test/ui/error-codes/E0622.stderr index da4d43f60411..ef13084dea04 100644 --- a/src/test/ui/error-codes/E0622.stderr +++ b/src/test/ui/error-codes/E0622.stderr @@ -6,4 +6,4 @@ LL | pub static breakpoint : unsafe extern "rust-intrinsic" fn(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0622" +For more information about this error, try `rustc --explain E0622`. diff --git a/src/test/ui/error-codes/E0624.stderr b/src/test/ui/error-codes/E0624.stderr index 39061f9ec774..ac911b9b7c0b 100644 --- a/src/test/ui/error-codes/E0624.stderr +++ b/src/test/ui/error-codes/E0624.stderr @@ -6,4 +6,4 @@ LL | foo.method(); //~ ERROR method `method` is private [E0624] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0624" +For more information about this error, try `rustc --explain E0624`. diff --git a/src/test/ui/error-codes/E0637.stderr b/src/test/ui/error-codes/E0637.stderr index d44a60760a73..b8c926efb45a 100644 --- a/src/test/ui/error-codes/E0637.stderr +++ b/src/test/ui/error-codes/E0637.stderr @@ -18,4 +18,4 @@ LL | impl<'a: '_> Bar<'a> { //~ ERROR invalid lifetime bound name: `'_` error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0637" +For more information about this error, try `rustc --explain E0637`. diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr index 34952dc73c20..f05291420239 100644 --- a/src/test/ui/error-codes/E0657.stderr +++ b/src/test/ui/error-codes/E0657.stderr @@ -12,4 +12,4 @@ LL | -> Box Id>> error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0657" +For more information about this error, try `rustc --explain E0657`. diff --git a/src/test/ui/error-codes/E0658.stderr b/src/test/ui/error-codes/E0658.stderr index b3425b59f31f..5be05600ee51 100644 --- a/src/test/ui/error-codes/E0658.stderr +++ b/src/test/ui/error-codes/E0658.stderr @@ -8,4 +8,4 @@ LL | let _ = ::std::u128::MAX; //~ ERROR E0658 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/error-codes/E0659.stderr b/src/test/ui/error-codes/E0659.stderr index 31a381a6edd1..06176085b381 100644 --- a/src/test/ui/error-codes/E0659.stderr +++ b/src/test/ui/error-codes/E0659.stderr @@ -18,4 +18,4 @@ LL | pub use earth::*; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0659" +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index 231864e9655b..345691352b40 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -72,5 +72,5 @@ LL | v as *const [u8]; error: aborting due to 10 previous errors -You've got a few errors: E0054, E0368, E0425, E0599, E0600, E0603, E0604, E0605, E0606... -If you want more information on an error, try using "rustc --explain E0054" +Some errors occurred: E0054, E0368, E0425, E0599, E0600, E0603, E0604, E0605, E0606... +For more information about an error, try `rustc --explain E0054`. diff --git a/src/test/ui/fat-ptr-cast.stderr b/src/test/ui/fat-ptr-cast.stderr index 383b5eb46012..cf1dcfcb8ade 100644 --- a/src/test/ui/fat-ptr-cast.stderr +++ b/src/test/ui/fat-ptr-cast.stderr @@ -66,5 +66,5 @@ LL | let mut fail: *const str = 0 as *const str; //~ ERROR casting error: aborting due to 9 previous errors -You've got a few errors: E0605, E0606, E0607 -If you want more information on an error, try using "rustc --explain E0605" +Some errors occurred: E0605, E0606, E0607. +For more information about an error, try `rustc --explain E0605`. diff --git a/src/test/ui/feature-gate-abi-msp430-interrupt.stderr b/src/test/ui/feature-gate-abi-msp430-interrupt.stderr index ca55e95b914f..26babb8c3ff4 100644 --- a/src/test/ui/feature-gate-abi-msp430-interrupt.stderr +++ b/src/test/ui/feature-gate-abi-msp430-interrupt.stderr @@ -8,4 +8,4 @@ LL | extern "msp430-interrupt" fn foo() {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-abi.stderr b/src/test/ui/feature-gate-abi.stderr index c2d70cf8ec24..0f9309bfb0cf 100644 --- a/src/test/ui/feature-gate-abi.stderr +++ b/src/test/ui/feature-gate-abi.stderr @@ -448,4 +448,4 @@ LL | extern "thiscall" {} //~ ERROR thiscall is experimental and subject to chan error: aborting due to 56 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gate-abi_unadjusted.stderr index 2382b931244d..467102d18477 100644 --- a/src/test/ui/feature-gate-abi_unadjusted.stderr +++ b/src/test/ui/feature-gate-abi_unadjusted.stderr @@ -10,4 +10,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-advanced-slice-features.stderr b/src/test/ui/feature-gate-advanced-slice-features.stderr index b589a01df175..9d9e75549761 100644 --- a/src/test/ui/feature-gate-advanced-slice-features.stderr +++ b/src/test/ui/feature-gate-advanced-slice-features.stderr @@ -16,4 +16,4 @@ LL | [ 1, xs.., 5 ] => {} //~ ERROR multiple-element slice matches error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-allocator_internals.stderr b/src/test/ui/feature-gate-allocator_internals.stderr index 53aa45e86724..a9667e8011a9 100644 --- a/src/test/ui/feature-gate-allocator_internals.stderr +++ b/src/test/ui/feature-gate-allocator_internals.stderr @@ -8,4 +8,4 @@ LL | #![default_lib_allocator] //~ ERROR: attribute is an experimental feature error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr b/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr index eab713ed79f9..97e414118546 100644 --- a/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr +++ b/src/test/ui/feature-gate-allow-internal-unsafe-nested-macro.stderr @@ -11,4 +11,4 @@ LL | bar!(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr b/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr index e2d48999be48..2ecaaae89d10 100644 --- a/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr +++ b/src/test/ui/feature-gate-allow-internal-unstable-nested-macro.stderr @@ -11,4 +11,4 @@ LL | bar!(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr b/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr index 115927c04cd0..4ff5162b0c08 100644 --- a/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr +++ b/src/test/ui/feature-gate-allow-internal-unstable-struct.stderr @@ -8,4 +8,4 @@ LL | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-allow-internal-unstable.stderr b/src/test/ui/feature-gate-allow-internal-unstable.stderr index e46fce67aa9e..b691eed60d3d 100644 --- a/src/test/ui/feature-gate-allow-internal-unstable.stderr +++ b/src/test/ui/feature-gate-allow-internal-unstable.stderr @@ -8,4 +8,4 @@ LL | #[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-allow_fail.stderr b/src/test/ui/feature-gate-allow_fail.stderr index d73791fa7804..3f8ad32437df 100644 --- a/src/test/ui/feature-gate-allow_fail.stderr +++ b/src/test/ui/feature-gate-allow_fail.stderr @@ -8,4 +8,4 @@ LL | #[allow_fail] //~ ERROR allow_fail attribute is currently unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-arbitrary-self-types.stderr b/src/test/ui/feature-gate-arbitrary-self-types.stderr index b59c047e0649..ea259aa22adf 100644 --- a/src/test/ui/feature-gate-arbitrary-self-types.stderr +++ b/src/test/ui/feature-gate-arbitrary-self-types.stderr @@ -27,4 +27,4 @@ LL | fn bar(self: Box>) {} //~ ERROR arbitrary `self` types are uns error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr b/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr index 4748ebdad211..5ed9a0f4ed04 100644 --- a/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr +++ b/src/test/ui/feature-gate-arbitrary_self_types-raw-pointer.stderr @@ -27,4 +27,4 @@ LL | fn bar(self: *const Self) {} error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-asm.stderr b/src/test/ui/feature-gate-asm.stderr index 68fe0a71d5a5..3fab7c0ece58 100644 --- a/src/test/ui/feature-gate-asm.stderr +++ b/src/test/ui/feature-gate-asm.stderr @@ -8,4 +8,4 @@ LL | asm!(""); //~ ERROR inline assembly is not stable enough error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-asm2.stderr b/src/test/ui/feature-gate-asm2.stderr index 4d83ac6100ea..a0e881a3b99a 100644 --- a/src/test/ui/feature-gate-asm2.stderr +++ b/src/test/ui/feature-gate-asm2.stderr @@ -8,4 +8,4 @@ LL | println!("{}", asm!("")); //~ ERROR inline assembly is not stable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-assoc-type-defaults.stderr b/src/test/ui/feature-gate-assoc-type-defaults.stderr index 62a956d4aad5..86431842a836 100644 --- a/src/test/ui/feature-gate-assoc-type-defaults.stderr +++ b/src/test/ui/feature-gate-assoc-type-defaults.stderr @@ -8,4 +8,4 @@ LL | type Bar = u8; //~ ERROR associated type defaults are unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-box-expr.stderr b/src/test/ui/feature-gate-box-expr.stderr index db025be0ab2e..72f2f08b5b8e 100644 --- a/src/test/ui/feature-gate-box-expr.stderr +++ b/src/test/ui/feature-gate-box-expr.stderr @@ -8,4 +8,4 @@ LL | let x = box 'c'; //~ ERROR box expression syntax is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-box_patterns.stderr b/src/test/ui/feature-gate-box_patterns.stderr index 4e521f2519ca..a8edb842cfcd 100644 --- a/src/test/ui/feature-gate-box_patterns.stderr +++ b/src/test/ui/feature-gate-box_patterns.stderr @@ -8,4 +8,4 @@ LL | let box x = Box::new('c'); //~ ERROR box pattern syntax is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-box_syntax.stderr b/src/test/ui/feature-gate-box_syntax.stderr index 8835b2cb14c1..7058512417b1 100644 --- a/src/test/ui/feature-gate-box_syntax.stderr +++ b/src/test/ui/feature-gate-box_syntax.stderr @@ -8,4 +8,4 @@ LL | let x = box 3; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-catch_expr.stderr b/src/test/ui/feature-gate-catch_expr.stderr index 6d8b7f104d97..4ab71460c0da 100644 --- a/src/test/ui/feature-gate-catch_expr.stderr +++ b/src/test/ui/feature-gate-catch_expr.stderr @@ -12,4 +12,4 @@ LL | | }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-cfg-target-feature.stderr b/src/test/ui/feature-gate-cfg-target-feature.stderr index e990c38de19c..bf9e596e71a7 100644 --- a/src/test/ui/feature-gate-cfg-target-feature.stderr +++ b/src/test/ui/feature-gate-cfg-target-feature.stderr @@ -32,4 +32,4 @@ LL | cfg!(target_feature = "x"); error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-cfg-target-has-atomic.stderr b/src/test/ui/feature-gate-cfg-target-has-atomic.stderr index 505f6b397242..f3975b7ce8b2 100644 --- a/src/test/ui/feature-gate-cfg-target-has-atomic.stderr +++ b/src/test/ui/feature-gate-cfg-target-has-atomic.stderr @@ -120,4 +120,4 @@ LL | cfg!(target_has_atomic = "ptr"); error: aborting due to 15 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-cfg-target-thread-local.stderr b/src/test/ui/feature-gate-cfg-target-thread-local.stderr index a6af55b1b265..3467d4e482da 100644 --- a/src/test/ui/feature-gate-cfg-target-thread-local.stderr +++ b/src/test/ui/feature-gate-cfg-target-thread-local.stderr @@ -8,4 +8,4 @@ LL | #[cfg_attr(target_thread_local, thread_local)] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-cfg-target-vendor.stderr b/src/test/ui/feature-gate-cfg-target-vendor.stderr index f19a2b7997af..a625c7e4b247 100644 --- a/src/test/ui/feature-gate-cfg-target-vendor.stderr +++ b/src/test/ui/feature-gate-cfg-target-vendor.stderr @@ -32,4 +32,4 @@ LL | cfg!(target_vendor = "x"); error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-clone-closures.stderr b/src/test/ui/feature-gate-clone-closures.stderr index 2b594f7faf38..7038a76380d6 100644 --- a/src/test/ui/feature-gate-clone-closures.stderr +++ b/src/test/ui/feature-gate-clone-closures.stderr @@ -8,4 +8,4 @@ LL | let hello = hello.clone(); //~ ERROR no method named `clone` found for error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/feature-gate-compiler-builtins.stderr b/src/test/ui/feature-gate-compiler-builtins.stderr index 3f8ef665d7ad..5330d83c284a 100644 --- a/src/test/ui/feature-gate-compiler-builtins.stderr +++ b/src/test/ui/feature-gate-compiler-builtins.stderr @@ -8,4 +8,4 @@ LL | #![compiler_builtins] //~ ERROR the `#[compiler_builtins]` attribute is error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-concat_idents.stderr b/src/test/ui/feature-gate-concat_idents.stderr index 05e2e33e1915..2f1e3fe6a7d9 100644 --- a/src/test/ui/feature-gate-concat_idents.stderr +++ b/src/test/ui/feature-gate-concat_idents.stderr @@ -16,4 +16,4 @@ LL | let b = concat_idents!(X, Y_2); //~ ERROR `concat_idents` is not stable error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-concat_idents2.stderr b/src/test/ui/feature-gate-concat_idents2.stderr index 548e7dbdcca3..9312a6f5b361 100644 --- a/src/test/ui/feature-gate-concat_idents2.stderr +++ b/src/test/ui/feature-gate-concat_idents2.stderr @@ -8,4 +8,4 @@ LL | concat_idents!(a, b); //~ ERROR `concat_idents` is not stable enough error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-concat_idents3.stderr b/src/test/ui/feature-gate-concat_idents3.stderr index 2f5411fa7a58..1a86032d8a32 100644 --- a/src/test/ui/feature-gate-concat_idents3.stderr +++ b/src/test/ui/feature-gate-concat_idents3.stderr @@ -16,4 +16,4 @@ LL | assert_eq!(20, concat_idents!(X, Y_2)); //~ ERROR `concat_idents` is no error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-conservative_impl_trait.stderr b/src/test/ui/feature-gate-conservative_impl_trait.stderr index 68cd13446809..5400226450bf 100644 --- a/src/test/ui/feature-gate-conservative_impl_trait.stderr +++ b/src/test/ui/feature-gate-conservative_impl_trait.stderr @@ -8,4 +8,4 @@ LL | fn foo() -> impl Fn() { || {} } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-const_fn.stderr b/src/test/ui/feature-gate-const_fn.stderr index 09d377c0ace5..d7c00a3e0cb4 100644 --- a/src/test/ui/feature-gate-const_fn.stderr +++ b/src/test/ui/feature-gate-const_fn.stderr @@ -58,5 +58,5 @@ LL | const fn foo() -> u32 { 0 } //~ ERROR const fn is unstable error: aborting due to 8 previous errors -You've got a few errors: E0379, E0658 -If you want more information on an error, try using "rustc --explain E0379" +Some errors occurred: E0379, E0658. +For more information about an error, try `rustc --explain E0379`. diff --git a/src/test/ui/feature-gate-copy-closures.stderr b/src/test/ui/feature-gate-copy-closures.stderr index b06ada022387..e72680b69eae 100644 --- a/src/test/ui/feature-gate-copy-closures.stderr +++ b/src/test/ui/feature-gate-copy-closures.stderr @@ -10,4 +10,4 @@ LL | let c = hello; //~ ERROR use of moved value: `hello` [E0382] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/feature-gate-crate_in_paths.stderr b/src/test/ui/feature-gate-crate_in_paths.stderr index 21ae346e9c8c..1d0eed531987 100644 --- a/src/test/ui/feature-gate-crate_in_paths.stderr +++ b/src/test/ui/feature-gate-crate_in_paths.stderr @@ -8,4 +8,4 @@ LL | let _ = ::crate::S; //~ ERROR `crate` in paths is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-crate_visibility_modifier.stderr b/src/test/ui/feature-gate-crate_visibility_modifier.stderr index e5e7c8c74206..d0ee40504fb2 100644 --- a/src/test/ui/feature-gate-crate_visibility_modifier.stderr +++ b/src/test/ui/feature-gate-crate_visibility_modifier.stderr @@ -8,4 +8,4 @@ LL | crate struct Bender { //~ ERROR `crate` visibility modifier is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-custom_attribute.stderr b/src/test/ui/feature-gate-custom_attribute.stderr index dd428e89ea27..36f5898f1c70 100644 --- a/src/test/ui/feature-gate-custom_attribute.stderr +++ b/src/test/ui/feature-gate-custom_attribute.stderr @@ -104,4 +104,4 @@ LL | #[fake_doc(r"doc")] //~ ERROR attribute `fake_doc` is currently unknown error: aborting due to 13 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gate-custom_attribute2.stderr index 29cde7042f60..90be45a33eac 100644 --- a/src/test/ui/feature-gate-custom_attribute2.stderr +++ b/src/test/ui/feature-gate-custom_attribute2.stderr @@ -136,4 +136,4 @@ LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 error: aborting due to 17 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-custom_derive.stderr b/src/test/ui/feature-gate-custom_derive.stderr index 18c8a081b235..e633a5a9c993 100644 --- a/src/test/ui/feature-gate-custom_derive.stderr +++ b/src/test/ui/feature-gate-custom_derive.stderr @@ -8,4 +8,4 @@ LL | #[derive_Clone] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-decl_macro.stderr b/src/test/ui/feature-gate-decl_macro.stderr index 6438e81610e8..56c0dea02369 100644 --- a/src/test/ui/feature-gate-decl_macro.stderr +++ b/src/test/ui/feature-gate-decl_macro.stderr @@ -8,4 +8,4 @@ LL | macro m() {} //~ ERROR `macro` is experimental (see issue #39412) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-doc_cfg.stderr b/src/test/ui/feature-gate-doc_cfg.stderr index 0eaaab03eb58..5839e1dd611e 100644 --- a/src/test/ui/feature-gate-doc_cfg.stderr +++ b/src/test/ui/feature-gate-doc_cfg.stderr @@ -8,4 +8,4 @@ LL | #[doc(cfg(unix))] //~ ERROR: #[doc(cfg(...))] is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-doc_masked.stderr b/src/test/ui/feature-gate-doc_masked.stderr index f8885587115f..043397efde25 100644 --- a/src/test/ui/feature-gate-doc_masked.stderr +++ b/src/test/ui/feature-gate-doc_masked.stderr @@ -8,4 +8,4 @@ LL | #[doc(masked)] //~ ERROR: #[doc(masked)] is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-doc_spotlight.stderr b/src/test/ui/feature-gate-doc_spotlight.stderr index ed69f7edf0b5..98e7f38a4418 100644 --- a/src/test/ui/feature-gate-doc_spotlight.stderr +++ b/src/test/ui/feature-gate-doc_spotlight.stderr @@ -8,4 +8,4 @@ LL | #[doc(spotlight)] //~ ERROR: #[doc(spotlight)] is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr b/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr index ef88d3307d23..67f15be9d084 100644 --- a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr +++ b/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr @@ -8,4 +8,4 @@ LL | 0 ..= 3 => {} //~ ERROR `..=` syntax in patterns is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-dropck-ugeh.stderr b/src/test/ui/feature-gate-dropck-ugeh.stderr index c200de766154..33bb5f2d9897 100644 --- a/src/test/ui/feature-gate-dropck-ugeh.stderr +++ b/src/test/ui/feature-gate-dropck-ugeh.stderr @@ -8,4 +8,4 @@ LL | #[unsafe_destructor_blind_to_params] // This is the UGEH attribute error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-dyn-trait.stderr b/src/test/ui/feature-gate-dyn-trait.stderr index d8db0bd55367..6e6bdf1cbf0d 100644 --- a/src/test/ui/feature-gate-dyn-trait.stderr +++ b/src/test/ui/feature-gate-dyn-trait.stderr @@ -8,4 +8,4 @@ LL | type A = Box; //~ ERROR `dyn Trait` syntax is unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-exclusive-range-pattern.stderr b/src/test/ui/feature-gate-exclusive-range-pattern.stderr index 5a5ecb698a40..27fd49edcc69 100644 --- a/src/test/ui/feature-gate-exclusive-range-pattern.stderr +++ b/src/test/ui/feature-gate-exclusive-range-pattern.stderr @@ -8,4 +8,4 @@ LL | 0 .. 3 => {} //~ ERROR exclusive range pattern syntax is experiment error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-extern_absolute_paths.stderr b/src/test/ui/feature-gate-extern_absolute_paths.stderr index 730cfb9747ba..7a996abc7675 100644 --- a/src/test/ui/feature-gate-extern_absolute_paths.stderr +++ b/src/test/ui/feature-gate-extern_absolute_paths.stderr @@ -12,5 +12,5 @@ LL | let _: u8 = ::core::default::Default(); //~ ERROR failed to resolve error: aborting due to 2 previous errors -You've got a few errors: E0432, E0433 -If you want more information on an error, try using "rustc --explain E0432" +Some errors occurred: E0432, E0433. +For more information about an error, try `rustc --explain E0432`. diff --git a/src/test/ui/feature-gate-extern_in_paths.stderr b/src/test/ui/feature-gate-extern_in_paths.stderr index 11387e81de2b..535ed94565c6 100644 --- a/src/test/ui/feature-gate-extern_in_paths.stderr +++ b/src/test/ui/feature-gate-extern_in_paths.stderr @@ -8,4 +8,4 @@ LL | let _ = extern::std::vec::Vec::new(); //~ ERROR `extern` in paths is ex error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-extern_types.stderr b/src/test/ui/feature-gate-extern_types.stderr index 6dabd6ab4a40..47c74bda1779 100644 --- a/src/test/ui/feature-gate-extern_types.stderr +++ b/src/test/ui/feature-gate-extern_types.stderr @@ -8,4 +8,4 @@ LL | type T; //~ ERROR extern types are experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-external_doc.stderr b/src/test/ui/feature-gate-external_doc.stderr index 0582548b5ba7..272380f2336e 100644 --- a/src/test/ui/feature-gate-external_doc.stderr +++ b/src/test/ui/feature-gate-external_doc.stderr @@ -8,4 +8,4 @@ LL | #[doc(include="asdf.md")] //~ ERROR: #[doc(include = "...")] is experimenta error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-fundamental.stderr b/src/test/ui/feature-gate-fundamental.stderr index 2e91f1abbbd3..ac8430d7c1c0 100644 --- a/src/test/ui/feature-gate-fundamental.stderr +++ b/src/test/ui/feature-gate-fundamental.stderr @@ -8,4 +8,4 @@ LL | #[fundamental] //~ ERROR the `#[fundamental]` attribute is an experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-generators.stderr b/src/test/ui/feature-gate-generators.stderr index ec7aad53b764..91749894eb64 100644 --- a/src/test/ui/feature-gate-generators.stderr +++ b/src/test/ui/feature-gate-generators.stderr @@ -8,4 +8,4 @@ LL | yield true; //~ ERROR yield syntax is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-generic_associated_types.stderr b/src/test/ui/feature-gate-generic_associated_types.stderr index f545da0be968..5f23def88eb0 100644 --- a/src/test/ui/feature-gate-generic_associated_types.stderr +++ b/src/test/ui/feature-gate-generic_associated_types.stderr @@ -32,4 +32,4 @@ LL | type Pointer2 = Box; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-generic_param_attrs.stderr b/src/test/ui/feature-gate-generic_param_attrs.stderr index 2d05d96549cd..7b449242c326 100644 --- a/src/test/ui/feature-gate-generic_param_attrs.stderr +++ b/src/test/ui/feature-gate-generic_param_attrs.stderr @@ -136,4 +136,4 @@ LL | where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 error: aborting due to 17 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-global_allocator.stderr b/src/test/ui/feature-gate-global_allocator.stderr index 400af3a33bd4..5a3fd67d27bc 100644 --- a/src/test/ui/feature-gate-global_allocator.stderr +++ b/src/test/ui/feature-gate-global_allocator.stderr @@ -8,4 +8,4 @@ LL | #[global_allocator] //~ ERROR: attribute is an experimental feature error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-global_asm.stderr b/src/test/ui/feature-gate-global_asm.stderr index b506a8e60d7b..2219d49a2636 100644 --- a/src/test/ui/feature-gate-global_asm.stderr +++ b/src/test/ui/feature-gate-global_asm.stderr @@ -8,4 +8,4 @@ LL | global_asm!(""); //~ ERROR `global_asm!` is not stable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-i128_type.stderr b/src/test/ui/feature-gate-i128_type.stderr index 31802ff350a1..eb3b29f4f559 100644 --- a/src/test/ui/feature-gate-i128_type.stderr +++ b/src/test/ui/feature-gate-i128_type.stderr @@ -16,4 +16,4 @@ LL | 0u128; //~ ERROR 128-bit integers are not stable error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr index e3a7cf06cdfd..2348e7fe2c5b 100644 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ b/src/test/ui/feature-gate-i128_type2.stderr @@ -44,5 +44,5 @@ LL | | } error: aborting due to 6 previous errors -You've got a few errors: E0601, E0658 -If you want more information on an error, try using "rustc --explain E0601" +Some errors occurred: E0601, E0658. +For more information about an error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate-if_while_or_patterns.stderr b/src/test/ui/feature-gate-if_while_or_patterns.stderr index 6096804190ed..909046812d3b 100644 --- a/src/test/ui/feature-gate-if_while_or_patterns.stderr +++ b/src/test/ui/feature-gate-if_while_or_patterns.stderr @@ -20,4 +20,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-in_band_lifetimes.stderr b/src/test/ui/feature-gate-in_band_lifetimes.stderr index 2b72d13ae5ef..cc0855306e16 100644 --- a/src/test/ui/feature-gate-in_band_lifetimes.stderr +++ b/src/test/ui/feature-gate-in_band_lifetimes.stderr @@ -102,4 +102,4 @@ LL | fn borrowed_lifetime(&'b self) -> &'b u8 { &*self.0 } error: aborting due to 17 previous errors -If you want more information on this error, try using "rustc --explain E0261" +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/feature-gate-intrinsics.stderr b/src/test/ui/feature-gate-intrinsics.stderr index bd8774a0941f..e583569cb99f 100644 --- a/src/test/ui/feature-gate-intrinsics.stderr +++ b/src/test/ui/feature-gate-intrinsics.stderr @@ -19,4 +19,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-lang-items.stderr b/src/test/ui/feature-gate-lang-items.stderr index 3c7000447d94..ef3e79472808 100644 --- a/src/test/ui/feature-gate-lang-items.stderr +++ b/src/test/ui/feature-gate-lang-items.stderr @@ -8,4 +8,4 @@ LL | #[lang="foo"] //~ ERROR language items are subject to change error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-link_args.stderr b/src/test/ui/feature-gate-link_args.stderr index dbf5086d02aa..86a2818b3442 100644 --- a/src/test/ui/feature-gate-link_args.stderr +++ b/src/test/ui/feature-gate-link_args.stderr @@ -24,4 +24,4 @@ LL | #![link_args = "-l unexpected_use_as_inner_attr_on_mod"] error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-link_cfg.stderr b/src/test/ui/feature-gate-link_cfg.stderr index 91c3a7a21a26..1da8c3e922dd 100644 --- a/src/test/ui/feature-gate-link_cfg.stderr +++ b/src/test/ui/feature-gate-link_cfg.stderr @@ -8,4 +8,4 @@ LL | #[link(name = "foo", cfg(foo))] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-link_llvm_intrinsics.stderr b/src/test/ui/feature-gate-link_llvm_intrinsics.stderr index 4072ce3cefb0..7a9c5955958a 100644 --- a/src/test/ui/feature-gate-link_llvm_intrinsics.stderr +++ b/src/test/ui/feature-gate-link_llvm_intrinsics.stderr @@ -8,4 +8,4 @@ LL | fn sqrt(x: f32) -> f32; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-linkage.stderr b/src/test/ui/feature-gate-linkage.stderr index a598ca97aeee..2fc1a3e1ae53 100644 --- a/src/test/ui/feature-gate-linkage.stderr +++ b/src/test/ui/feature-gate-linkage.stderr @@ -8,4 +8,4 @@ LL | #[linkage = "extern_weak"] static foo: isize; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-linker-flavor.stderr b/src/test/ui/feature-gate-linker-flavor.stderr index d2f124397ccc..b8bccece2927 100644 --- a/src/test/ui/feature-gate-linker-flavor.stderr +++ b/src/test/ui/feature-gate-linker-flavor.stderr @@ -8,4 +8,4 @@ LL | #[used] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-log_syntax.stderr b/src/test/ui/feature-gate-log_syntax.stderr index 070fe99512e5..d9934be778e6 100644 --- a/src/test/ui/feature-gate-log_syntax.stderr +++ b/src/test/ui/feature-gate-log_syntax.stderr @@ -8,4 +8,4 @@ LL | log_syntax!() //~ ERROR `log_syntax!` is not stable enough error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-log_syntax2.stderr b/src/test/ui/feature-gate-log_syntax2.stderr index 8aedddcc8862..19e7de1a824f 100644 --- a/src/test/ui/feature-gate-log_syntax2.stderr +++ b/src/test/ui/feature-gate-log_syntax2.stderr @@ -8,4 +8,4 @@ LL | println!("{}", log_syntax!()); //~ ERROR `log_syntax!` is not stable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-macro-lifetime-matcher.stderr b/src/test/ui/feature-gate-macro-lifetime-matcher.stderr index 0e0977b2d1ac..b7805f6f5fbf 100644 --- a/src/test/ui/feature-gate-macro-lifetime-matcher.stderr +++ b/src/test/ui/feature-gate-macro-lifetime-matcher.stderr @@ -8,4 +8,4 @@ LL | macro_rules! m { ($lt:lifetime) => {} } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-macro-vis-matcher.stderr b/src/test/ui/feature-gate-macro-vis-matcher.stderr index 70a1374b0202..9d98091674e7 100644 --- a/src/test/ui/feature-gate-macro-vis-matcher.stderr +++ b/src/test/ui/feature-gate-macro-vis-matcher.stderr @@ -8,4 +8,4 @@ LL | macro_rules! m { ($v:vis) => {} } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-macro_at_most_once_rep.stderr b/src/test/ui/feature-gate-macro_at_most_once_rep.stderr index 6089b25ac444..8eba07e6c088 100644 --- a/src/test/ui/feature-gate-macro_at_most_once_rep.stderr +++ b/src/test/ui/feature-gate-macro_at_most_once_rep.stderr @@ -8,4 +8,4 @@ LL | macro_rules! m { ($(a)?) => {} } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-main.stderr b/src/test/ui/feature-gate-main.stderr index f6513f203d0d..34c9fd15f7cf 100644 --- a/src/test/ui/feature-gate-main.stderr +++ b/src/test/ui/feature-gate-main.stderr @@ -8,4 +8,4 @@ LL | fn foo() {} //~ ERROR: declaration of a nonstandard #[main] function may ch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-match_default_bindings.stderr b/src/test/ui/feature-gate-match_default_bindings.stderr index 51f0b8cd98fd..8fa553561de2 100644 --- a/src/test/ui/feature-gate-match_default_bindings.stderr +++ b/src/test/ui/feature-gate-match_default_bindings.stderr @@ -8,4 +8,4 @@ LL | Some(n) => {}, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-may-dangle.stderr b/src/test/ui/feature-gate-may-dangle.stderr index 555f4f456140..85707f6e9212 100644 --- a/src/test/ui/feature-gate-may-dangle.stderr +++ b/src/test/ui/feature-gate-may-dangle.stderr @@ -8,4 +8,4 @@ LL | impl<#[may_dangle] A> Drop for Pt { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-naked_functions.stderr b/src/test/ui/feature-gate-naked_functions.stderr index d4ba8ff4d73c..a2d3dfc83ae3 100644 --- a/src/test/ui/feature-gate-naked_functions.stderr +++ b/src/test/ui/feature-gate-naked_functions.stderr @@ -16,4 +16,4 @@ LL | #[naked] error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-needs-allocator.stderr b/src/test/ui/feature-gate-needs-allocator.stderr index a526873f42d3..13665b2a0eb2 100644 --- a/src/test/ui/feature-gate-needs-allocator.stderr +++ b/src/test/ui/feature-gate-needs-allocator.stderr @@ -8,4 +8,4 @@ LL | #![needs_allocator] //~ ERROR the `#[needs_allocator]` attribute is error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-negate-unsigned.stderr b/src/test/ui/feature-gate-negate-unsigned.stderr index 3c3056f9748b..1025b56f55bc 100644 --- a/src/test/ui/feature-gate-negate-unsigned.stderr +++ b/src/test/ui/feature-gate-negate-unsigned.stderr @@ -12,4 +12,4 @@ LL | let _y = -x; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0600" +For more information about this error, try `rustc --explain E0600`. diff --git a/src/test/ui/feature-gate-never_type.stderr b/src/test/ui/feature-gate-never_type.stderr index e0a194ca6e99..187be6d82913 100644 --- a/src/test/ui/feature-gate-never_type.stderr +++ b/src/test/ui/feature-gate-never_type.stderr @@ -40,4 +40,4 @@ LL | type Wub = !; //~ ERROR type is experimental error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-nll.stderr b/src/test/ui/feature-gate-nll.stderr index 8194680cef7a..f7b431d19be7 100644 --- a/src/test/ui/feature-gate-nll.stderr +++ b/src/test/ui/feature-gate-nll.stderr @@ -8,4 +8,4 @@ LL | x = 22; //~ ERROR cannot assign to `x` because it is borrowed [E0506] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0506" +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/feature-gate-no-debug.stderr b/src/test/ui/feature-gate-no-debug.stderr index 943d3530d156..55fad0d99cf0 100644 --- a/src/test/ui/feature-gate-no-debug.stderr +++ b/src/test/ui/feature-gate-no-debug.stderr @@ -8,4 +8,4 @@ LL | #[no_debug] //~ ERROR the `#[no_debug]` attribute was error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-no_core.stderr b/src/test/ui/feature-gate-no_core.stderr index caadb98a7107..c8813dcd991f 100644 --- a/src/test/ui/feature-gate-no_core.stderr +++ b/src/test/ui/feature-gate-no_core.stderr @@ -8,4 +8,4 @@ LL | #![no_core] //~ ERROR no_core is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-non_ascii_idents.stderr b/src/test/ui/feature-gate-non_ascii_idents.stderr index 38a2623267fd..69d7e38d431f 100644 --- a/src/test/ui/feature-gate-non_ascii_idents.stderr +++ b/src/test/ui/feature-gate-non_ascii_idents.stderr @@ -110,4 +110,4 @@ LL | fn qüx(); //~ ERROR non-ascii idents error: aborting due to 13 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-non_exhaustive.stderr b/src/test/ui/feature-gate-non_exhaustive.stderr index 468ef6e273c3..67f103d852a0 100644 --- a/src/test/ui/feature-gate-non_exhaustive.stderr +++ b/src/test/ui/feature-gate-non_exhaustive.stderr @@ -8,4 +8,4 @@ LL | #[non_exhaustive] //~ERROR non exhaustive is an experimental feature (see i error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr b/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr index ad8b12ea2548..253811400efd 100644 --- a/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr +++ b/src/test/ui/feature-gate-omit-gdb-pretty-printer-section.stderr @@ -8,4 +8,4 @@ LL | #[omit_gdb_pretty_printer_section] //~ ERROR the `#[omit_gdb_pretty_printer error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-on-unimplemented.stderr b/src/test/ui/feature-gate-on-unimplemented.stderr index 7cc956fa1f0e..a059f5e3c4d2 100644 --- a/src/test/ui/feature-gate-on-unimplemented.stderr +++ b/src/test/ui/feature-gate-on-unimplemented.stderr @@ -8,4 +8,4 @@ LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-optin-builtin-traits.stderr b/src/test/ui/feature-gate-optin-builtin-traits.stderr index ec7856338fb9..8bd07ffd1229 100644 --- a/src/test/ui/feature-gate-optin-builtin-traits.stderr +++ b/src/test/ui/feature-gate-optin-builtin-traits.stderr @@ -16,4 +16,4 @@ LL | impl !DummyTrait for DummyStruct {} error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-overlapping_marker_traits.stderr b/src/test/ui/feature-gate-overlapping_marker_traits.stderr index 2b30691c40d8..040ad019b9fc 100644 --- a/src/test/ui/feature-gate-overlapping_marker_traits.stderr +++ b/src/test/ui/feature-gate-overlapping_marker_traits.stderr @@ -8,4 +8,4 @@ LL | impl MyMarker for T {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/feature-gate-pattern_parentheses.stderr b/src/test/ui/feature-gate-pattern_parentheses.stderr index 4fc1441a0fad..fce024d20f4f 100644 --- a/src/test/ui/feature-gate-pattern_parentheses.stderr +++ b/src/test/ui/feature-gate-pattern_parentheses.stderr @@ -8,4 +8,4 @@ LL | (pat) => {} //~ ERROR parentheses in patterns are unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-placement-expr.stderr b/src/test/ui/feature-gate-placement-expr.stderr index 96b38812cb0b..b5c091763a1b 100644 --- a/src/test/ui/feature-gate-placement-expr.stderr +++ b/src/test/ui/feature-gate-placement-expr.stderr @@ -8,4 +8,4 @@ LL | let x = HEAP <- 'c'; //~ ERROR placement-in expression syntax is experi error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-plugin.stderr b/src/test/ui/feature-gate-plugin.stderr index f9a98b130440..366e293c1826 100644 --- a/src/test/ui/feature-gate-plugin.stderr +++ b/src/test/ui/feature-gate-plugin.stderr @@ -8,4 +8,4 @@ LL | #![plugin(foo)] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-plugin_registrar.stderr b/src/test/ui/feature-gate-plugin_registrar.stderr index 731cca8f6a92..3e6ffb6ef1a5 100644 --- a/src/test/ui/feature-gate-plugin_registrar.stderr +++ b/src/test/ui/feature-gate-plugin_registrar.stderr @@ -8,4 +8,4 @@ LL | pub fn registrar() {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-prelude_import.stderr b/src/test/ui/feature-gate-prelude_import.stderr index 6b791ee23808..6841df54067a 100644 --- a/src/test/ui/feature-gate-prelude_import.stderr +++ b/src/test/ui/feature-gate-prelude_import.stderr @@ -8,4 +8,4 @@ LL | #[prelude_import] //~ ERROR `#[prelude_import]` is for use by rustc only error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-profiler-runtime.stderr b/src/test/ui/feature-gate-profiler-runtime.stderr index ea321591143e..dd395742b4f4 100644 --- a/src/test/ui/feature-gate-profiler-runtime.stderr +++ b/src/test/ui/feature-gate-profiler-runtime.stderr @@ -8,4 +8,4 @@ LL | #![profiler_runtime] //~ ERROR the `#[profiler_runtime]` attribute is error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-repr-simd.stderr b/src/test/ui/feature-gate-repr-simd.stderr index 280dc4518dd4..8174f82060a1 100644 --- a/src/test/ui/feature-gate-repr-simd.stderr +++ b/src/test/ui/feature-gate-repr-simd.stderr @@ -8,4 +8,4 @@ LL | #[repr(simd)] //~ error: SIMD types are experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-repr128.stderr b/src/test/ui/feature-gate-repr128.stderr index fef28398df68..29cba831f545 100644 --- a/src/test/ui/feature-gate-repr128.stderr +++ b/src/test/ui/feature-gate-repr128.stderr @@ -10,4 +10,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-repr_transparent.stderr b/src/test/ui/feature-gate-repr_transparent.stderr index 161ab0af3416..a4ffaa266906 100644 --- a/src/test/ui/feature-gate-repr_transparent.stderr +++ b/src/test/ui/feature-gate-repr_transparent.stderr @@ -8,4 +8,4 @@ LL | #[repr(transparent)] //~ error: the `#[repr(transparent)]` attribute is exp error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gate-rustc-attrs.stderr index 6743f328f392..fda95a5b97a5 100644 --- a/src/test/ui/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gate-rustc-attrs.stderr @@ -24,4 +24,4 @@ LL | #[rustc_foo] error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-rustc_const_unstable.stderr b/src/test/ui/feature-gate-rustc_const_unstable.stderr index 25cc2e41016c..fa3f9807a04e 100644 --- a/src/test/ui/feature-gate-rustc_const_unstable.stderr +++ b/src/test/ui/feature-gate-rustc_const_unstable.stderr @@ -8,4 +8,4 @@ LL | #[rustc_const_unstable(feature="fzzzzzt")] //~ERROR internal feature error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-sanitizer-runtime.stderr b/src/test/ui/feature-gate-sanitizer-runtime.stderr index 6640f59255a8..fc93e1030053 100644 --- a/src/test/ui/feature-gate-sanitizer-runtime.stderr +++ b/src/test/ui/feature-gate-sanitizer-runtime.stderr @@ -8,4 +8,4 @@ LL | #![sanitizer_runtime] //~ ERROR the `#[sanitizer_runtime]` attribute is error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-simd.stderr b/src/test/ui/feature-gate-simd.stderr index b4ed7ee43c77..414a5d9eb5d0 100644 --- a/src/test/ui/feature-gate-simd.stderr +++ b/src/test/ui/feature-gate-simd.stderr @@ -8,4 +8,4 @@ LL | #[repr(simd)] //~ ERROR SIMD types are experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gate-slice-patterns.stderr index 0f61313e092c..7c216fad933e 100644 --- a/src/test/ui/feature-gate-slice-patterns.stderr +++ b/src/test/ui/feature-gate-slice-patterns.stderr @@ -8,4 +8,4 @@ LL | [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-start.stderr b/src/test/ui/feature-gate-start.stderr index 533cc31fb0a3..cf590d2a0e3a 100644 --- a/src/test/ui/feature-gate-start.stderr +++ b/src/test/ui/feature-gate-start.stderr @@ -8,4 +8,4 @@ LL | fn foo() {} //~ ERROR: a #[start] function is an experimental feature error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-static-nobundle.stderr b/src/test/ui/feature-gate-static-nobundle.stderr index d872b8f4c52b..fd9f2b371f60 100644 --- a/src/test/ui/feature-gate-static-nobundle.stderr +++ b/src/test/ui/feature-gate-static-nobundle.stderr @@ -8,4 +8,4 @@ LL | #[link(name="foo", kind="static-nobundle")] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-stmt_expr_attributes.stderr b/src/test/ui/feature-gate-stmt_expr_attributes.stderr index 8aca511ec160..cd3af90dfd3a 100644 --- a/src/test/ui/feature-gate-stmt_expr_attributes.stderr +++ b/src/test/ui/feature-gate-stmt_expr_attributes.stderr @@ -8,4 +8,4 @@ LL | const X: i32 = #[allow(dead_code)] 8; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-target_feature.stderr b/src/test/ui/feature-gate-target_feature.stderr index 0b7313de04d9..0f31abf7b42c 100644 --- a/src/test/ui/feature-gate-target_feature.stderr +++ b/src/test/ui/feature-gate-target_feature.stderr @@ -8,4 +8,4 @@ LL | #[target_feature = "+sse2"] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-thread_local.stderr b/src/test/ui/feature-gate-thread_local.stderr index 0bbcb6a24b21..9b44c3f95901 100644 --- a/src/test/ui/feature-gate-thread_local.stderr +++ b/src/test/ui/feature-gate-thread_local.stderr @@ -8,4 +8,4 @@ LL | #[thread_local] //~ ERROR `#[thread_local]` is an experimental feature error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-trace_macros.stderr b/src/test/ui/feature-gate-trace_macros.stderr index 56d69bbbb405..a31f618bbbe9 100644 --- a/src/test/ui/feature-gate-trace_macros.stderr +++ b/src/test/ui/feature-gate-trace_macros.stderr @@ -8,4 +8,4 @@ LL | trace_macros!(true); //~ ERROR: `trace_macros` is not stable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-type_ascription.stderr b/src/test/ui/feature-gate-type_ascription.stderr index bd0ff84c4385..2bd475b68b20 100644 --- a/src/test/ui/feature-gate-type_ascription.stderr +++ b/src/test/ui/feature-gate-type_ascription.stderr @@ -8,4 +8,4 @@ LL | let a = 10: u8; //~ ERROR type ascription is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr index 5d1f4d092279..6dfcdfc25671 100644 --- a/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr +++ b/src/test/ui/feature-gate-unboxed-closures-manual-impls.stderr @@ -32,4 +32,4 @@ LL | extern "rust-call" fn call_once(&self, args: ()) -> () {} error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr b/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr index 7eb938110f3a..cc8615d3620e 100644 --- a/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr +++ b/src/test/ui/feature-gate-unboxed-closures-method-calls.stderr @@ -24,4 +24,4 @@ LL | f.call_once(()); //~ ERROR use of unstable library feature 'fn_traits' error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr b/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr index 5db2ea6167cb..26dd983e877d 100644 --- a/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr +++ b/src/test/ui/feature-gate-unboxed-closures-ufcs-calls.stderr @@ -24,4 +24,4 @@ LL | FnOnce::call_once(f, ()); //~ ERROR use of unstable library feature 'fn error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gate-unboxed-closures.stderr index 54e75ce8ef4c..a5b1ed9bbc4f 100644 --- a/src/test/ui/feature-gate-unboxed-closures.stderr +++ b/src/test/ui/feature-gate-unboxed-closures.stderr @@ -10,4 +10,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-underscore-lifetimes.stderr b/src/test/ui/feature-gate-underscore-lifetimes.stderr index b92662f8a82e..c1cddcd763eb 100644 --- a/src/test/ui/feature-gate-underscore-lifetimes.stderr +++ b/src/test/ui/feature-gate-underscore-lifetimes.stderr @@ -8,4 +8,4 @@ LL | fn foo(x: &u8) -> Foo<'_> { //~ ERROR underscore lifetimes are unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-universal.stderr b/src/test/ui/feature-gate-universal.stderr index 8d2e81055fe5..dc1a6b29c72c 100644 --- a/src/test/ui/feature-gate-universal.stderr +++ b/src/test/ui/feature-gate-universal.stderr @@ -8,4 +8,4 @@ LL | fn foo(x: impl std::fmt::Debug) { print!("{:?}", x); } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-unsized_tuple_coercion.stderr b/src/test/ui/feature-gate-unsized_tuple_coercion.stderr index e0bfab164ff2..bf790a3b0039 100644 --- a/src/test/ui/feature-gate-unsized_tuple_coercion.stderr +++ b/src/test/ui/feature-gate-unsized_tuple_coercion.stderr @@ -8,4 +8,4 @@ LL | let _ : &(Send,) = &((),); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gate-untagged_unions.stderr index eef42e8b6fd6..e0c845b77685 100644 --- a/src/test/ui/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gate-untagged_unions.stderr @@ -30,4 +30,4 @@ LL | | } error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-unwind-attributes.stderr b/src/test/ui/feature-gate-unwind-attributes.stderr index d22b56ca386a..4c6e6f420de3 100644 --- a/src/test/ui/feature-gate-unwind-attributes.stderr +++ b/src/test/ui/feature-gate-unwind-attributes.stderr @@ -8,4 +8,4 @@ LL | #[unwind] //~ ERROR #[unwind] is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-used.stderr b/src/test/ui/feature-gate-used.stderr index 44c7c142c55a..d650b5ebb3b1 100644 --- a/src/test/ui/feature-gate-used.stderr +++ b/src/test/ui/feature-gate-used.stderr @@ -8,4 +8,4 @@ LL | #[used] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr index 1d33bc556113..f9f1cce91f1c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr @@ -2,4 +2,4 @@ error[E0601]: main function not found error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr index 40a81171a898..36320be1dc81 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr @@ -41,5 +41,5 @@ LL | #[inline = "2100"] impl S { } error: aborting due to 6 previous errors -You've got a few errors: E0518, E0601 -If you want more information on an error, try using "rustc --explain E0518" +Some errors occurred: E0518, E0601. +For more information about an error, try `rustc --explain E0518`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index 5e540f9139eb..d1d37720a55d 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -10,4 +10,4 @@ error[E0601]: main function not found error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr index 5a184897a093..c7654a3f258c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr @@ -38,4 +38,4 @@ error[E0601]: main function not found error: aborting due to 7 previous errors -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr index 1d4530852562..5a1dd706ff3c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr @@ -44,4 +44,4 @@ LL | #[rustc_deprecated = "1500"] impl S { } error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr index f7f426299dac..bee9b8e96820 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr @@ -44,4 +44,4 @@ LL | #[stable = "1300"] impl S { } error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr index 1d33bc556113..f9f1cce91f1c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr @@ -2,4 +2,4 @@ error[E0601]: main function not found error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr index afa444217119..970cc2f2a349 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr @@ -44,4 +44,4 @@ LL | #[unstable = "1200"] impl S { } error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 0943b64c5c09..abbe6d5b11c6 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -40,4 +40,4 @@ LL | fn sync(_: T) {} error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index 8f78bb8fa884..cd83915fe82d 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -33,5 +33,5 @@ LL | fn assert_foo(f: T) {} error: aborting due to 2 previous errors -You've got a few errors: E0277, E0279 -If you want more information on an error, try using "rustc --explain E0277" +Some errors occurred: E0277, E0279. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/borrowing.stderr b/src/test/ui/generator/borrowing.stderr index a27d950c0459..2a5de3790ada 100644 --- a/src/test/ui/generator/borrowing.stderr +++ b/src/test/ui/generator/borrowing.stderr @@ -27,4 +27,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/generator/dropck.stderr b/src/test/ui/generator/dropck.stderr index c4ae9051138b..4a22d299701b 100644 --- a/src/test/ui/generator/dropck.stderr +++ b/src/test/ui/generator/dropck.stderr @@ -14,4 +14,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/generator/generator-with-nll.stderr b/src/test/ui/generator/generator-with-nll.stderr index 49542dd0ac35..7e39d3c54590 100644 --- a/src/test/ui/generator/generator-with-nll.stderr +++ b/src/test/ui/generator/generator-with-nll.stderr @@ -27,4 +27,4 @@ LL | yield (); error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0626" +For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/generator/issue-48048.stderr b/src/test/ui/generator/issue-48048.stderr index 759187667549..f0654685deba 100644 --- a/src/test/ui/generator/issue-48048.stderr +++ b/src/test/ui/generator/issue-48048.stderr @@ -8,4 +8,4 @@ LL | yield; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0626" +For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/generator/no-arguments-on-generators.stderr b/src/test/ui/generator/no-arguments-on-generators.stderr index 6091946f2fa7..6520f8b20231 100644 --- a/src/test/ui/generator/no-arguments-on-generators.stderr +++ b/src/test/ui/generator/no-arguments-on-generators.stderr @@ -6,4 +6,4 @@ LL | let gen = |start| { //~ ERROR generators cannot have explicit arguments error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0628" +For more information about this error, try `rustc --explain E0628`. diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 6ca583bf16d6..7ef6edfacf47 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -30,4 +30,4 @@ LL | fn assert_sync(_: T) {} error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/pattern-borrow.stderr b/src/test/ui/generator/pattern-borrow.stderr index 6acfd96d8871..48f23486a317 100644 --- a/src/test/ui/generator/pattern-borrow.stderr +++ b/src/test/ui/generator/pattern-borrow.stderr @@ -8,4 +8,4 @@ LL | yield (); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0626" +For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr index 7cd07adf0b1c..65817e30c4de 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/generator/sized-yield.stderr b/src/test/ui/generator/sized-yield.stderr index c10adad99ebc..fc99c7e3bd74 100644 --- a/src/test/ui/generator/sized-yield.stderr +++ b/src/test/ui/generator/sized-yield.stderr @@ -20,4 +20,4 @@ LL | gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/generator/unsafe-immovable.stderr b/src/test/ui/generator/unsafe-immovable.stderr index a6755283bce0..b2add55613d5 100644 --- a/src/test/ui/generator/unsafe-immovable.stderr +++ b/src/test/ui/generator/unsafe-immovable.stderr @@ -8,4 +8,4 @@ LL | | }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0133" +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/generator/yield-in-args.stderr b/src/test/ui/generator/yield-in-args.stderr index 26152f73f5a9..3219939e89b2 100644 --- a/src/test/ui/generator/yield-in-args.stderr +++ b/src/test/ui/generator/yield-in-args.stderr @@ -6,4 +6,4 @@ LL | foo(&b, yield); //~ ERROR error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0626" +For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/generator/yield-in-const.stderr b/src/test/ui/generator/yield-in-const.stderr index 119f94695e72..41a20893f5c4 100644 --- a/src/test/ui/generator/yield-in-const.stderr +++ b/src/test/ui/generator/yield-in-const.stderr @@ -8,5 +8,5 @@ LL | const A: u8 = { yield 3u8; 3u8}; error: aborting due to 2 previous errors -You've got a few errors: E0601, E0627 -If you want more information on an error, try using "rustc --explain E0601" +Some errors occurred: E0601, E0627. +For more information about an error, try `rustc --explain E0601`. diff --git a/src/test/ui/generator/yield-in-function.stderr b/src/test/ui/generator/yield-in-function.stderr index b1d76b41fa2b..35be1fcd28d1 100644 --- a/src/test/ui/generator/yield-in-function.stderr +++ b/src/test/ui/generator/yield-in-function.stderr @@ -6,4 +6,4 @@ LL | fn main() { yield; } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0627" +For more information about this error, try `rustc --explain E0627`. diff --git a/src/test/ui/generator/yield-in-static.stderr b/src/test/ui/generator/yield-in-static.stderr index 0a2da21e6924..71ebc189035a 100644 --- a/src/test/ui/generator/yield-in-static.stderr +++ b/src/test/ui/generator/yield-in-static.stderr @@ -8,5 +8,5 @@ LL | static B: u8 = { yield 3u8; 3u8}; error: aborting due to 2 previous errors -You've got a few errors: E0601, E0627 -If you want more information on an error, try using "rustc --explain E0601" +Some errors occurred: E0601, E0627. +For more information about an error, try `rustc --explain E0601`. diff --git a/src/test/ui/generator/yield-while-iterating.stderr b/src/test/ui/generator/yield-while-iterating.stderr index c1a047f6c2a1..c20b1348e279 100644 --- a/src/test/ui/generator/yield-while-iterating.stderr +++ b/src/test/ui/generator/yield-while-iterating.stderr @@ -22,5 +22,5 @@ LL | } error: aborting due to 2 previous errors -You've got a few errors: E0502, E0626 -If you want more information on an error, try using "rustc --explain E0502" +Some errors occurred: E0502, E0626. +For more information about an error, try `rustc --explain E0502`. diff --git a/src/test/ui/generator/yield-while-local-borrowed.stderr b/src/test/ui/generator/yield-while-local-borrowed.stderr index 7417cdd9aa5f..a7f9862a726f 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.stderr +++ b/src/test/ui/generator/yield-while-local-borrowed.stderr @@ -36,4 +36,4 @@ LL | yield(); error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0626" +For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.stderr index 57d688e78f69..8139814c7f2b 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.stderr +++ b/src/test/ui/generator/yield-while-ref-reborrowed.stderr @@ -14,4 +14,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0501" +For more information about this error, try `rustc --explain E0501`. diff --git a/src/test/ui/generic-type-less-params-with-defaults.stderr b/src/test/ui/generic-type-less-params-with-defaults.stderr index 327a36df80c5..28867eb2254e 100644 --- a/src/test/ui/generic-type-less-params-with-defaults.stderr +++ b/src/test/ui/generic-type-less-params-with-defaults.stderr @@ -6,4 +6,4 @@ LL | let _: Vec; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0243" +For more information about this error, try `rustc --explain E0243`. diff --git a/src/test/ui/generic-type-more-params-with-defaults.stderr b/src/test/ui/generic-type-more-params-with-defaults.stderr index 1f60d7997e32..684a22ce45c9 100644 --- a/src/test/ui/generic-type-more-params-with-defaults.stderr +++ b/src/test/ui/generic-type-more-params-with-defaults.stderr @@ -6,4 +6,4 @@ LL | let _: Vec; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0244" +For more information about this error, try `rustc --explain E0244`. diff --git a/src/test/ui/if-let-arm-types.stderr b/src/test/ui/if-let-arm-types.stderr index b20426103f44..2e6b71dadf13 100644 --- a/src/test/ui/if-let-arm-types.stderr +++ b/src/test/ui/if-let-arm-types.stderr @@ -23,4 +23,4 @@ LL | | }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-duplicate-methods.stderr b/src/test/ui/impl-duplicate-methods.stderr index dcbac5cfa0b1..99e1e56e3233 100644 --- a/src/test/ui/impl-duplicate-methods.stderr +++ b/src/test/ui/impl-duplicate-methods.stderr @@ -8,4 +8,4 @@ LL | fn orange(&self) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0201" +For more information about this error, try `rustc --explain E0201`. diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index bf7705881c91..71ca8675db4e 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -58,5 +58,5 @@ LL | fn cycle1() -> impl Clone { error: aborting due to 3 previous errors -You've got a few errors: E0277, E0391 -If you want more information on an error, try using "rustc --explain E0277" +Some errors occurred: E0277, E0391. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 0c72468a2670..0f310df07142 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -53,5 +53,5 @@ LL | x.0); error: aborting due to 6 previous errors -You've got a few errors: E0277, E0308 -If you want more information on an error, try using "rustc --explain E0277" +Some errors occurred: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/impl-trait-plus-priority.stderr b/src/test/ui/impl-trait/impl-trait-plus-priority.stderr index 1d4159aaa45e..2a9199b25bcf 100644 --- a/src/test/ui/impl-trait/impl-trait-plus-priority.stderr +++ b/src/test/ui/impl-trait/impl-trait-plus-priority.stderr @@ -66,4 +66,4 @@ LL | type A = &A + B; error: aborting due to 11 previous errors -If you want more information on this error, try using "rustc --explain E0178" +For more information about this error, try `rustc --explain E0178`. diff --git a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr index d80251200b29..89bc53884943 100644 --- a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr +++ b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr @@ -13,4 +13,4 @@ LL | f1.foo(1usize); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr index b441ff518bdd..438d29f05353 100644 --- a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr +++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr @@ -15,4 +15,4 @@ LL | foo(|s| s.is_empty()); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index d5250b42cc21..bc4afb931098 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -255,4 +255,4 @@ LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).me error: aborting due to 24 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr index 6c2fde03de37..c91ebb705dee 100644 --- a/src/test/ui/impl-trait/trait_type.stderr +++ b/src/test/ui/impl-trait/trait_type.stderr @@ -33,5 +33,5 @@ LL | impl std::fmt::Display for MyType4 {} error: aborting due to 4 previous errors -You've got a few errors: E0046, E0050, E0053, E0186 -If you want more information on an error, try using "rustc --explain E0046" +Some errors occurred: E0046, E0050, E0053, E0186. +For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr index 67b3dacdaf56..64f1aff13bdb 100644 --- a/src/test/ui/impl-trait/universal-mismatched-type.stderr +++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr @@ -11,4 +11,4 @@ LL | x //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr index 4309c1a9bc9e..61f52ff25fb1 100644 --- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr +++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr @@ -9,4 +9,4 @@ LL | a = y; //~ ERROR mismatched error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index 6cf0baa5fcce..a02fc1f748fa 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -26,5 +26,3 @@ LL | use std::fmt::Debug; error: cannot continue compilation due to previous error -You've got a few errors: E0405, E0425 -If you want more information on an error, try using "rustc --explain E0405" diff --git a/src/test/ui/impl-unused-rps-in-assoc-type.stderr b/src/test/ui/impl-unused-rps-in-assoc-type.stderr index fb3cf9a30c80..1f7f790b1e4a 100644 --- a/src/test/ui/impl-unused-rps-in-assoc-type.stderr +++ b/src/test/ui/impl-unused-rps-in-assoc-type.stderr @@ -6,4 +6,4 @@ LL | impl<'a> Fun for Holder { //~ ERROR E0207 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0207" +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/impl_trait_projections.stderr b/src/test/ui/impl_trait_projections.stderr index f519f21215ef..9b38de614fc1 100644 --- a/src/test/ui/impl_trait_projections.stderr +++ b/src/test/ui/impl_trait_projections.stderr @@ -32,5 +32,5 @@ LL | fn projection_is_disallowed(x: impl Iterator) -> ::Item { error: aborting due to 5 previous errors -You've got a few errors: E0223, E0667 -If you want more information on an error, try using "rustc --explain E0223" +Some errors occurred: E0223, E0667. +For more information about an error, try `rustc --explain E0223`. diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr index 0715674077a7..452e3e1e2008 100644 --- a/src/test/ui/imports/duplicate.stderr +++ b/src/test/ui/imports/duplicate.stderr @@ -86,5 +86,5 @@ LL | use self::m2::*; error: aborting due to 5 previous errors -You've got a few errors: E0252, E0659 -If you want more information on an error, try using "rustc --explain E0252" +Some errors occurred: E0252, E0659. +For more information about an error, try `rustc --explain E0252`. diff --git a/src/test/ui/imports/macro-paths.stderr b/src/test/ui/imports/macro-paths.stderr index 815694919c76..1422fb0904d0 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -40,5 +40,5 @@ error[E0601]: main function not found error: aborting due to 3 previous errors -You've got a few errors: E0601, E0659 -If you want more information on an error, try using "rustc --explain E0601" +Some errors occurred: E0601, E0659. +For more information about an error, try `rustc --explain E0601`. diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr index c32fb56cd5d8..d74020ecab29 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -55,5 +55,5 @@ error[E0601]: main function not found error: aborting due to 4 previous errors -You've got a few errors: E0601, E0659 -If you want more information on an error, try using "rustc --explain E0601" +Some errors occurred: E0601, E0659. +For more information about an error, try `rustc --explain E0601`. diff --git a/src/test/ui/imports/shadow_builtin_macros.stderr b/src/test/ui/imports/shadow_builtin_macros.stderr index 8c72d27d6aae..c9d80ada4725 100644 --- a/src/test/ui/imports/shadow_builtin_macros.stderr +++ b/src/test/ui/imports/shadow_builtin_macros.stderr @@ -57,4 +57,4 @@ LL | #[macro_use(n)] error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0659" +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/impossible_range.stderr b/src/test/ui/impossible_range.stderr index 0754dbc796b4..d941b522defe 100644 --- a/src/test/ui/impossible_range.stderr +++ b/src/test/ui/impossible_range.stderr @@ -16,4 +16,4 @@ LL | 0..=; //~ERROR inclusive range with no end error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0586" +For more information about this error, try `rustc --explain E0586`. diff --git a/src/test/ui/in-band-lifetimes/E0687.stderr b/src/test/ui/in-band-lifetimes/E0687.stderr index e1fa4164cc4c..441494d738a7 100644 --- a/src/test/ui/in-band-lifetimes/E0687.stderr +++ b/src/test/ui/in-band-lifetimes/E0687.stderr @@ -24,4 +24,4 @@ LL | fn bar(&self, x: fn(&'a u32)) {} //~ ERROR must be explicitly error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0687" +For more information about this error, try `rustc --explain E0687`. diff --git a/src/test/ui/in-band-lifetimes/E0687_where.stderr b/src/test/ui/in-band-lifetimes/E0687_where.stderr index 74da124c9c70..a2ad5cf0f83b 100644 --- a/src/test/ui/in-band-lifetimes/E0687_where.stderr +++ b/src/test/ui/in-band-lifetimes/E0687_where.stderr @@ -12,4 +12,4 @@ LL | fn baz(x: &impl Fn(&'a u32)) {} //~ ERROR must be explicitly error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0687" +For more information about this error, try `rustc --explain E0687`. diff --git a/src/test/ui/in-band-lifetimes/E0688.stderr b/src/test/ui/in-band-lifetimes/E0688.stderr index 3521e370dc57..66dca227941a 100644 --- a/src/test/ui/in-band-lifetimes/E0688.stderr +++ b/src/test/ui/in-band-lifetimes/E0688.stderr @@ -24,4 +24,4 @@ LL | impl<'b> Foo<'a> { //~ ERROR cannot mix error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0688" +For more information about this error, try `rustc --explain E0688`. diff --git a/src/test/ui/in-band-lifetimes/mismatched.stderr b/src/test/ui/in-band-lifetimes/mismatched.stderr index 9485c9652a97..d2748b2da4b6 100644 --- a/src/test/ui/in-band-lifetimes/mismatched.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched.stderr @@ -16,5 +16,5 @@ LL | fn foo2(x: &'a u32, y: &'b u32) -> &'a u32 { y } //~ ERROR lifetime mismatc error: aborting due to 2 previous errors -You've got a few errors: E0621, E0623 -If you want more information on an error, try using "rustc --explain E0621" +Some errors occurred: E0621, E0623. +For more information about an error, try `rustc --explain E0621`. diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait.stderr index 5007701afdbd..71b46f6d4d60 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait.stderr @@ -8,4 +8,4 @@ LL | y //~ ERROR explicit lifetime required error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr index bc55b1c56cf2..a3d05e72ed9f 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -20,5 +20,5 @@ LL | | } error: aborting due to 2 previous errors -You've got a few errors: E0495, E0601 -If you want more information on an error, try using "rustc --explain E0495" +Some errors occurred: E0495, E0601. +For more information about an error, try `rustc --explain E0495`. diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index 41b0c77ea148..675ae1695b55 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -22,4 +22,4 @@ LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0495" +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/in-band-lifetimes/mut_while_borrow.stderr b/src/test/ui/in-band-lifetimes/mut_while_borrow.stderr index 258b369f257e..1498eb7ac1da 100644 --- a/src/test/ui/in-band-lifetimes/mut_while_borrow.stderr +++ b/src/test/ui/in-band-lifetimes/mut_while_borrow.stderr @@ -8,4 +8,4 @@ LL | p += 1; //~ ERROR cannot assign to `p` because it is borrowed error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0506" +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr index 7cba013c96b7..da46cb7f22e3 100644 --- a/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr +++ b/src/test/ui/in-band-lifetimes/no_in_band_in_struct.stderr @@ -12,4 +12,4 @@ LL | Baz(&'test u32), //~ ERROR undeclared lifetime error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0261" +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr index 7b1d0509bbdc..d53b71907a42 100644 --- a/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr +++ b/src/test/ui/in-band-lifetimes/no_introducing_in_band_in_locals.stderr @@ -12,4 +12,4 @@ LL | let y: fn(&'test u32) = foo2; //~ ERROR use of undeclared lifetime error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0261" +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/in-band-lifetimes/shadow.stderr b/src/test/ui/in-band-lifetimes/shadow.stderr index b22b18aa9294..0ee228fca312 100644 --- a/src/test/ui/in-band-lifetimes/shadow.stderr +++ b/src/test/ui/in-band-lifetimes/shadow.stderr @@ -17,4 +17,4 @@ LL | fn baz(x: for<'s> fn(&'s u32)) {} //~ ERROR shadows a lifetime name error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0496" +For more information about this error, try `rustc --explain E0496`. diff --git a/src/test/ui/index-help.stderr b/src/test/ui/index-help.stderr index ae3cd529ac42..669c0837fdab 100644 --- a/src/test/ui/index-help.stderr +++ b/src/test/ui/index-help.stderr @@ -9,4 +9,4 @@ LL | x[0i32]; //~ ERROR E0277 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/infinite-recursion-const-fn.stderr b/src/test/ui/infinite-recursion-const-fn.stderr index bc062ecce258..81717fe1f092 100644 --- a/src/test/ui/infinite-recursion-const-fn.stderr +++ b/src/test/ui/infinite-recursion-const-fn.stderr @@ -69,4 +69,4 @@ LL | const ARR: [i32; a()] = [5; 6]; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0080" +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr index e27353eda099..4c489c5964ba 100644 --- a/src/test/ui/interior-mutability/interior-mutability.stderr +++ b/src/test/ui/interior-mutability/interior-mutability.stderr @@ -12,4 +12,4 @@ LL | catch_unwind(|| { x.set(23); }); //~ ERROR the trait bound error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr index 2dac52d6f81e..2dd62ec05007 100644 --- a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr +++ b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr @@ -8,4 +8,4 @@ LL | pub mod baz; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0583" +For more information about this error, try `rustc --explain E0583`. diff --git a/src/test/ui/invalid-path-in-const.stderr b/src/test/ui/invalid-path-in-const.stderr index 06eb6005d71d..9214800b93a5 100644 --- a/src/test/ui/invalid-path-in-const.stderr +++ b/src/test/ui/invalid-path-in-const.stderr @@ -6,4 +6,4 @@ LL | fn f(a: [u8; u32::DOESNOTEXIST]) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issue-10969.stderr b/src/test/ui/issue-10969.stderr index b4d365dcc004..edc4ecbab525 100644 --- a/src/test/ui/issue-10969.stderr +++ b/src/test/ui/issue-10969.stderr @@ -16,4 +16,4 @@ LL | i(); //~ERROR expected function, found `i32` error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0618" +For more information about this error, try `rustc --explain E0618`. diff --git a/src/test/ui/issue-11004.stderr b/src/test/ui/issue-11004.stderr index 268c3cd6d2af..215120c9c25e 100644 --- a/src/test/ui/issue-11004.stderr +++ b/src/test/ui/issue-11004.stderr @@ -12,4 +12,4 @@ LL | let y : f64 = n.y; //~ no field `y` on type `*mut A` error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0609" +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/issue-11319.stderr b/src/test/ui/issue-11319.stderr index b94f8001ccf5..8189cf5ea170 100644 --- a/src/test/ui/issue-11319.stderr +++ b/src/test/ui/issue-11319.stderr @@ -17,4 +17,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-12187-1.stderr b/src/test/ui/issue-12187-1.stderr index 29b1e985183d..7d4df2901fe3 100644 --- a/src/test/ui/issue-12187-1.stderr +++ b/src/test/ui/issue-12187-1.stderr @@ -9,4 +9,4 @@ LL | let &v = new(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issue-12187-2.stderr b/src/test/ui/issue-12187-2.stderr index 327105bee162..f7ecbd447729 100644 --- a/src/test/ui/issue-12187-2.stderr +++ b/src/test/ui/issue-12187-2.stderr @@ -9,4 +9,4 @@ LL | let &v = new(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issue-12511.stderr b/src/test/ui/issue-12511.stderr index 3f0c0e7ee13d..c1612b8cb678 100644 --- a/src/test/ui/issue-12511.stderr +++ b/src/test/ui/issue-12511.stderr @@ -18,4 +18,4 @@ LL | trait t1 : t2 { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0391" +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issue-13058.stderr b/src/test/ui/issue-13058.stderr index 30936d4c90d8..cef5f5ae475b 100644 --- a/src/test/ui/issue-13058.stderr +++ b/src/test/ui/issue-13058.stderr @@ -21,5 +21,5 @@ LL | check((3, 5)); error: aborting due to 2 previous errors -You've got a few errors: E0308, E0621 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0621. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-14092.stderr b/src/test/ui/issue-14092.stderr index 209ca27a20be..f90ea4776ab7 100644 --- a/src/test/ui/issue-14092.stderr +++ b/src/test/ui/issue-14092.stderr @@ -6,4 +6,4 @@ LL | fn fn1(0: Box) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0243" +For more information about this error, try `rustc --explain E0243`. diff --git a/src/test/ui/issue-15260.stderr b/src/test/ui/issue-15260.stderr index 1b0a39d02f5b..10cb79e0fc54 100644 --- a/src/test/ui/issue-15260.stderr +++ b/src/test/ui/issue-15260.stderr @@ -33,4 +33,4 @@ LL | a: x error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0025" +For more information about this error, try `rustc --explain E0025`. diff --git a/src/test/ui/issue-15524.stderr b/src/test/ui/issue-15524.stderr index e26766eca373..a116e621a95d 100644 --- a/src/test/ui/issue-15524.stderr +++ b/src/test/ui/issue-15524.stderr @@ -26,4 +26,4 @@ LL | E = N, error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0081" +For more information about this error, try `rustc --explain E0081`. diff --git a/src/test/ui/issue-17263.stderr b/src/test/ui/issue-17263.stderr index e321a9f45626..4767fbbcfbbd 100644 --- a/src/test/ui/issue-17263.stderr +++ b/src/test/ui/issue-17263.stderr @@ -22,5 +22,5 @@ LL | } error: aborting due to 2 previous errors -You've got a few errors: E0499, E0502 -If you want more information on an error, try using "rustc --explain E0499" +Some errors occurred: E0499, E0502. +For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/ui/issue-17441.stderr b/src/test/ui/issue-17441.stderr index ec0f33caffc7..80ba49cce1a0 100644 --- a/src/test/ui/issue-17441.stderr +++ b/src/test/ui/issue-17441.stderr @@ -44,4 +44,4 @@ LL | let _quux = [1_usize, 2] as [usize]; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0620" +For more information about this error, try `rustc --explain E0620`. diff --git a/src/test/ui/issue-18183.stderr b/src/test/ui/issue-18183.stderr index 93cd351cbc58..169a3019d521 100644 --- a/src/test/ui/issue-18183.stderr +++ b/src/test/ui/issue-18183.stderr @@ -6,4 +6,4 @@ LL | pub struct Foo(Bar); //~ ERROR E0128 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0128" +For more information about this error, try `rustc --explain E0128`. diff --git a/src/test/ui/issue-18819.stderr b/src/test/ui/issue-18819.stderr index e714707c2c3d..86926863598b 100644 --- a/src/test/ui/issue-18819.stderr +++ b/src/test/ui/issue-18819.stderr @@ -9,4 +9,4 @@ LL | print_x(X); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0061" +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/issue-19498.stderr b/src/test/ui/issue-19498.stderr index b2793dff2bf8..839ab778061c 100644 --- a/src/test/ui/issue-19498.stderr +++ b/src/test/ui/issue-19498.stderr @@ -44,4 +44,4 @@ LL | use C::D as OtherD; error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0255" +For more information about this error, try `rustc --explain E0255`. diff --git a/src/test/ui/issue-19707.stderr b/src/test/ui/issue-19707.stderr index 22a892c9252b..56088d38aaf9 100644 --- a/src/test/ui/issue-19707.stderr +++ b/src/test/ui/issue-19707.stderr @@ -16,4 +16,4 @@ LL | fn bar &u8>(f: &F) {} //~ ERROR missing lifetime specifi error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0106" +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/issue-19922.stderr b/src/test/ui/issue-19922.stderr index ac64cb12ef0b..a5bc579e1924 100644 --- a/src/test/ui/issue-19922.stderr +++ b/src/test/ui/issue-19922.stderr @@ -8,4 +8,4 @@ LL | let homura = Homura::Akemi { kaname: () }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0559" +For more information about this error, try `rustc --explain E0559`. diff --git a/src/test/ui/issue-20692.stderr b/src/test/ui/issue-20692.stderr index 1c23f42f3cc4..1316773f6b78 100644 --- a/src/test/ui/issue-20692.stderr +++ b/src/test/ui/issue-20692.stderr @@ -17,4 +17,4 @@ LL | let _ = x error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/issue-21546.stderr b/src/test/ui/issue-21546.stderr index 6f8000f24924..bff79e52aa18 100644 --- a/src/test/ui/issue-21546.stderr +++ b/src/test/ui/issue-21546.stderr @@ -66,4 +66,4 @@ LL | mod Corge { } error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0428" +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/ui/issue-21600.stderr b/src/test/ui/issue-21600.stderr index b1dcf1cd7300..873dc7448be2 100644 --- a/src/test/ui/issue-21600.stderr +++ b/src/test/ui/issue-21600.stderr @@ -29,4 +29,4 @@ LL | call_it(|| x.gen_mut()); //~ ERROR cannot borrow data mutably in a error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0387" +For more information about this error, try `rustc --explain E0387`. diff --git a/src/test/ui/issue-21950.stderr b/src/test/ui/issue-21950.stderr index 9d33e1fd0ab0..a2f74a29aab7 100644 --- a/src/test/ui/issue-21950.stderr +++ b/src/test/ui/issue-21950.stderr @@ -14,5 +14,5 @@ LL | &Add; error: aborting due to 2 previous errors -You've got a few errors: E0191, E0393 -If you want more information on an error, try using "rustc --explain E0191" +Some errors occurred: E0191, E0393. +For more information about an error, try `rustc --explain E0191`. diff --git a/src/test/ui/issue-22370.stderr b/src/test/ui/issue-22370.stderr index 79362ce7aa3a..b3691503fc19 100644 --- a/src/test/ui/issue-22370.stderr +++ b/src/test/ui/issue-22370.stderr @@ -8,4 +8,4 @@ LL | fn f(a: &A) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0393" +For more information about this error, try `rustc --explain E0393`. diff --git a/src/test/ui/issue-22560.stderr b/src/test/ui/issue-22560.stderr index 907b0d8822dc..b5524036fae9 100644 --- a/src/test/ui/issue-22560.stderr +++ b/src/test/ui/issue-22560.stderr @@ -32,5 +32,5 @@ LL | | Sub; error: aborting due to 4 previous errors -You've got a few errors: E0191, E0225, E0393 -If you want more information on an error, try using "rustc --explain E0191" +Some errors occurred: E0191, E0225, E0393. +For more information about an error, try `rustc --explain E0191`. diff --git a/src/test/ui/issue-22886.stderr b/src/test/ui/issue-22886.stderr index 4a69e6bc4c25..0e05cbfa7eed 100644 --- a/src/test/ui/issue-22886.stderr +++ b/src/test/ui/issue-22886.stderr @@ -6,4 +6,4 @@ LL | impl<'a> Iterator for Newtype { //~ ERROR E0207 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0207" +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/issue-22933-2.stderr b/src/test/ui/issue-22933-2.stderr index 41324fd8b753..435a89b716f9 100644 --- a/src/test/ui/issue-22933-2.stderr +++ b/src/test/ui/issue-22933-2.stderr @@ -9,4 +9,4 @@ LL | ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issue-23041.stderr b/src/test/ui/issue-23041.stderr index cf4e677ed0c4..f89bce09c7ed 100644 --- a/src/test/ui/issue-23041.stderr +++ b/src/test/ui/issue-23041.stderr @@ -6,4 +6,4 @@ LL | b.downcast_ref::_>(); //~ ERROR E0282 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issue-23173.stderr b/src/test/ui/issue-23173.stderr index bf2c67f93f88..d58a4d2b8f8a 100644 --- a/src/test/ui/issue-23173.stderr +++ b/src/test/ui/issue-23173.stderr @@ -36,4 +36,4 @@ LL | Struct::Assoc; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr index 7abe4bd7b213..be9ec9d73c21 100644 --- a/src/test/ui/issue-23217.stderr +++ b/src/test/ui/issue-23217.stderr @@ -8,4 +8,4 @@ LL | B = SomeEnum::A, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issue-23302-1.stderr b/src/test/ui/issue-23302-1.stderr index 087eae43a299..c587c00279bd 100644 --- a/src/test/ui/issue-23302-1.stderr +++ b/src/test/ui/issue-23302-1.stderr @@ -18,4 +18,4 @@ LL | A = X::A as isize, //~ ERROR E0391 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0391" +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issue-23302-2.stderr b/src/test/ui/issue-23302-2.stderr index 66ba5c325821..553ddaa1a810 100644 --- a/src/test/ui/issue-23302-2.stderr +++ b/src/test/ui/issue-23302-2.stderr @@ -18,4 +18,4 @@ LL | A = Y::B as isize, //~ ERROR E0391 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0391" +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issue-23302-3.stderr b/src/test/ui/issue-23302-3.stderr index 31168579394d..8cf296bc6db6 100644 --- a/src/test/ui/issue-23302-3.stderr +++ b/src/test/ui/issue-23302-3.stderr @@ -28,4 +28,4 @@ LL | const B: i32 = A; //~ ERROR cyclic dependency detected error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0391" +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issue-23543.stderr b/src/test/ui/issue-23543.stderr index c62af8f0635b..ea443f1cbbba 100644 --- a/src/test/ui/issue-23543.stderr +++ b/src/test/ui/issue-23543.stderr @@ -6,4 +6,4 @@ LL | where T: A; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0229" +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/issue-23544.stderr b/src/test/ui/issue-23544.stderr index 882703cdb5ae..147e2a212edd 100644 --- a/src/test/ui/issue-23544.stderr +++ b/src/test/ui/issue-23544.stderr @@ -6,4 +6,4 @@ LL | where T: A; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0229" +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/issue-23716.stderr b/src/test/ui/issue-23716.stderr index 739c8d66e713..fd268c1b5a19 100644 --- a/src/test/ui/issue-23716.stderr +++ b/src/test/ui/issue-23716.stderr @@ -18,4 +18,4 @@ LL | fn question(answer: i32) {} error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0530" +For more information about this error, try `rustc --explain E0530`. diff --git a/src/test/ui/issue-24036.stderr b/src/test/ui/issue-24036.stderr index bbf64d8305de..24995be773e7 100644 --- a/src/test/ui/issue-24036.stderr +++ b/src/test/ui/issue-24036.stderr @@ -29,4 +29,4 @@ LL | | }; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-24081.stderr b/src/test/ui/issue-24081.stderr index 257e32f91980..17cd3ec0aa6d 100644 --- a/src/test/ui/issue-24081.stderr +++ b/src/test/ui/issue-24081.stderr @@ -75,4 +75,4 @@ LL | use std::ops::Rem as OtherRem; error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0255" +For more information about this error, try `rustc --explain E0255`. diff --git a/src/test/ui/issue-24424.stderr b/src/test/ui/issue-24424.stderr index c3d5211cddc9..7bcf67a50480 100644 --- a/src/test/ui/issue-24424.stderr +++ b/src/test/ui/issue-24424.stderr @@ -12,4 +12,4 @@ LL | trait Trait0<'l0> {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0283" +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/issue-25385.stderr b/src/test/ui/issue-25385.stderr index 88e30d7fae05..f12388d4b458 100644 --- a/src/test/ui/issue-25385.stderr +++ b/src/test/ui/issue-25385.stderr @@ -15,4 +15,4 @@ LL | foo!(1i32.foo()); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issue-25793.stderr b/src/test/ui/issue-25793.stderr index 2d8b5d6f4995..926a744f69e8 100644 --- a/src/test/ui/issue-25793.stderr +++ b/src/test/ui/issue-25793.stderr @@ -11,4 +11,4 @@ LL | self.get_size(width!(self)) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0503" +For more information about this error, try `rustc --explain E0503`. diff --git a/src/test/ui/issue-25826.stderr b/src/test/ui/issue-25826.stderr index 94cbcf53f430..fed9e8efa848 100644 --- a/src/test/ui/issue-25826.stderr +++ b/src/test/ui/issue-25826.stderr @@ -6,4 +6,4 @@ LL | const A: bool = id:: as *const () < id:: as *const (); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0395" +For more information about this error, try `rustc --explain E0395`. diff --git a/src/test/ui/issue-26056.stderr b/src/test/ui/issue-26056.stderr index c806308562ce..51a48af81a16 100644 --- a/src/test/ui/issue-26056.stderr +++ b/src/test/ui/issue-26056.stderr @@ -8,4 +8,4 @@ LL | as &Map; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/issue-26093.stderr b/src/test/ui/issue-26093.stderr index 29ffd9635c64..1abe313bbf66 100644 --- a/src/test/ui/issue-26093.stderr +++ b/src/test/ui/issue-26093.stderr @@ -9,4 +9,4 @@ LL | not_a_place!(99); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0070" +For more information about this error, try `rustc --explain E0070`. diff --git a/src/test/ui/issue-26472.stderr b/src/test/ui/issue-26472.stderr index 345008b45787..26f54f61a7ee 100644 --- a/src/test/ui/issue-26472.stderr +++ b/src/test/ui/issue-26472.stderr @@ -8,4 +8,4 @@ LL | let v = s.len; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0616" +For more information about this error, try `rustc --explain E0616`. diff --git a/src/test/ui/issue-26638.stderr b/src/test/ui/issue-26638.stderr index a5fc3ba26d66..cf6fcd9f01cc 100644 --- a/src/test/ui/issue-26638.stderr +++ b/src/test/ui/issue-26638.stderr @@ -26,4 +26,4 @@ LL | fn parse_type_3() -> &str { unimplemented!() } error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0106" +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/issue-26886.stderr b/src/test/ui/issue-26886.stderr index dc812d1bae3b..759426239410 100644 --- a/src/test/ui/issue-26886.stderr +++ b/src/test/ui/issue-26886.stderr @@ -29,4 +29,4 @@ LL | use std::sync as other_sync; //~ ERROR the name `sync` is defined multiple error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0252" +For more information about this error, try `rustc --explain E0252`. diff --git a/src/test/ui/issue-27842.stderr b/src/test/ui/issue-27842.stderr index 98f2b18dc77b..026594811e47 100644 --- a/src/test/ui/issue-27842.stderr +++ b/src/test/ui/issue-27842.stderr @@ -14,4 +14,4 @@ LL | let _ = tup[i]; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0608" +For more information about this error, try `rustc --explain E0608`. diff --git a/src/test/ui/issue-27942.stderr b/src/test/ui/issue-27942.stderr index 19654a647c57..879eda0f8564 100644 --- a/src/test/ui/issue-27942.stderr +++ b/src/test/ui/issue-27942.stderr @@ -38,4 +38,4 @@ LL | fn select(&self) -> BufferViewHandle; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-2848.stderr b/src/test/ui/issue-2848.stderr index 6ab018b0014b..8f7ebbf95dd9 100644 --- a/src/test/ui/issue-2848.stderr +++ b/src/test/ui/issue-2848.stderr @@ -8,4 +8,4 @@ LL | alpha | beta => {} //~ ERROR variable `beta` is not bound in all pat error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0408" +For more information about this error, try `rustc --explain E0408`. diff --git a/src/test/ui/issue-28568.stderr b/src/test/ui/issue-28568.stderr index fecc5a41b3b9..3208074642f0 100644 --- a/src/test/ui/issue-28568.stderr +++ b/src/test/ui/issue-28568.stderr @@ -9,4 +9,4 @@ LL | impl Drop for MyStruct { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/issue-28776.stderr b/src/test/ui/issue-28776.stderr index e426f05ddf6d..3b468a882054 100644 --- a/src/test/ui/issue-28776.stderr +++ b/src/test/ui/issue-28776.stderr @@ -6,4 +6,4 @@ LL | (&ptr::write)(1 as *mut _, 42); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0133" +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/issue-28837.stderr b/src/test/ui/issue-28837.stderr index 62fc0ebec32f..88994eaeb937 100644 --- a/src/test/ui/issue-28837.stderr +++ b/src/test/ui/issue-28837.stderr @@ -120,4 +120,4 @@ LL | a >= a; //~ ERROR binary operation `>=` cannot be applied to type `A` error: aborting due to 15 previous errors -If you want more information on this error, try using "rustc --explain E0369" +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr index ebd759a9c3cc..81d8d97963bd 100644 --- a/src/test/ui/issue-28971.stderr +++ b/src/test/ui/issue-28971.stderr @@ -9,4 +9,4 @@ LL | Foo::Baz(..) => (), error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issue-29124.stderr b/src/test/ui/issue-29124.stderr index 091671b23097..bd00772dfd28 100644 --- a/src/test/ui/issue-29124.stderr +++ b/src/test/ui/issue-29124.stderr @@ -16,4 +16,4 @@ LL | func.x(); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issue-29723.stderr b/src/test/ui/issue-29723.stderr index 1b4c750471fa..48e50b9dea9c 100644 --- a/src/test/ui/issue-29723.stderr +++ b/src/test/ui/issue-29723.stderr @@ -11,4 +11,4 @@ LL | s error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/issue-3008-1.stderr b/src/test/ui/issue-3008-1.stderr index 282181d51cde..05c1f2aae814 100644 --- a/src/test/ui/issue-3008-1.stderr +++ b/src/test/ui/issue-3008-1.stderr @@ -11,4 +11,4 @@ LL | BarSome(Bar) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/issue-3008-2.stderr b/src/test/ui/issue-3008-2.stderr index a015e6d621db..d02fb45be496 100644 --- a/src/test/ui/issue-3008-2.stderr +++ b/src/test/ui/issue-3008-2.stderr @@ -10,4 +10,4 @@ LL | struct bar { x: bar } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/issue-30255.stderr b/src/test/ui/issue-30255.stderr index 6a55025d7b1d..9556f6d9e230 100644 --- a/src/test/ui/issue-30255.stderr +++ b/src/test/ui/issue-30255.stderr @@ -24,4 +24,4 @@ LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0106" +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/issue-30302.stderr b/src/test/ui/issue-30302.stderr index 6528058428a4..42dfdadf9c46 100644 --- a/src/test/ui/issue-30302.stderr +++ b/src/test/ui/issue-30302.stderr @@ -23,3 +23,4 @@ LL | #![deny(unreachable_patterns)] error: aborting due to previous error +For more information about this error, try `rustc --explain E0170`. diff --git a/src/test/ui/issue-3044.stderr b/src/test/ui/issue-3044.stderr index 00f9b302ffbf..cdca9be48ac6 100644 --- a/src/test/ui/issue-3044.stderr +++ b/src/test/ui/issue-3044.stderr @@ -6,4 +6,4 @@ LL | needlesArr.iter().fold(|x, y| { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0061" +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/issue-32326.stderr b/src/test/ui/issue-32326.stderr index 290c491b489a..1aa99c402ed8 100644 --- a/src/test/ui/issue-32326.stderr +++ b/src/test/ui/issue-32326.stderr @@ -12,4 +12,4 @@ LL | Plus(Expr, Expr), error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/issue-33525.stderr b/src/test/ui/issue-33525.stderr index ad308b87b376..2b365e1cc98b 100644 --- a/src/test/ui/issue-33525.stderr +++ b/src/test/ui/issue-33525.stderr @@ -18,5 +18,5 @@ LL | "".ipsum; //~ ERROR no field error: aborting due to 3 previous errors -You've got a few errors: E0425, E0609 -If you want more information on an error, try using "rustc --explain E0425" +Some errors occurred: E0425, E0609. +For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/issue-33941.stderr b/src/test/ui/issue-33941.stderr index ef76158682b7..f20b87fa371f 100644 --- a/src/test/ui/issue-33941.stderr +++ b/src/test/ui/issue-33941.stderr @@ -19,4 +19,4 @@ LL | for _ in HashMap::new().iter().cloned() {} //~ ERROR type mismatch error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0271" +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/issue-34047.stderr b/src/test/ui/issue-34047.stderr index efd6222db20e..10804cc6fff4 100644 --- a/src/test/ui/issue-34047.stderr +++ b/src/test/ui/issue-34047.stderr @@ -9,4 +9,4 @@ LL | mut C => {} //~ ERROR match bindings cannot shadow constants error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0530" +For more information about this error, try `rustc --explain E0530`. diff --git a/src/test/ui/issue-34209.stderr b/src/test/ui/issue-34209.stderr index faf3f3856fd6..5c31acea5b60 100644 --- a/src/test/ui/issue-34209.stderr +++ b/src/test/ui/issue-34209.stderr @@ -8,4 +8,4 @@ LL | S::B{ } => { }, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0223" +For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/issue-35139.stderr b/src/test/ui/issue-35139.stderr index 79b0ecff94ed..7ec1459dd169 100644 --- a/src/test/ui/issue-35139.stderr +++ b/src/test/ui/issue-35139.stderr @@ -6,4 +6,4 @@ LL | impl<'a> MethodType for MTFn { //~ ERROR E0207 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0207" +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/issue-35241.stderr b/src/test/ui/issue-35241.stderr index be0b21f94601..42bf0aae5b12 100644 --- a/src/test/ui/issue-35241.stderr +++ b/src/test/ui/issue-35241.stderr @@ -13,4 +13,4 @@ LL | fn test() -> Foo { Foo } //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-35675.stderr b/src/test/ui/issue-35675.stderr index 84054b532de8..fef8de3a28d9 100644 --- a/src/test/ui/issue-35675.stderr +++ b/src/test/ui/issue-35675.stderr @@ -65,5 +65,5 @@ LL | fn qux() -> Some { error: aborting due to 7 previous errors -You've got a few errors: E0412, E0425, E0573 -If you want more information on an error, try using "rustc --explain E0412" +Some errors occurred: E0412, E0425, E0573. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/issue-35869.stderr b/src/test/ui/issue-35869.stderr index e90906ee8416..fa971c111a40 100644 --- a/src/test/ui/issue-35869.stderr +++ b/src/test/ui/issue-35869.stderr @@ -48,4 +48,4 @@ LL | fn qux() -> u16 { 5u16 } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0053" +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/issue-36163.stderr b/src/test/ui/issue-36163.stderr index 4323eb4858f4..7ab4bd46ebf4 100644 --- a/src/test/ui/issue-36163.stderr +++ b/src/test/ui/issue-36163.stderr @@ -28,4 +28,4 @@ LL | const A: isize = Foo::B as isize; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0391" +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/issue-36400.stderr b/src/test/ui/issue-36400.stderr index 4a632356b4e1..dbd6999b4f29 100644 --- a/src/test/ui/issue-36400.stderr +++ b/src/test/ui/issue-36400.stderr @@ -8,4 +8,4 @@ LL | f(&mut *x); //~ ERROR cannot borrow immutable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/issue-36708.stderr b/src/test/ui/issue-36708.stderr index d2aa5b6c0ec3..4e28a769f506 100644 --- a/src/test/ui/issue-36708.stderr +++ b/src/test/ui/issue-36708.stderr @@ -6,4 +6,4 @@ LL | fn foo() {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0049" +For more information about this error, try `rustc --explain E0049`. diff --git a/src/test/ui/issue-3779.stderr b/src/test/ui/issue-3779.stderr index 6dcbabbe39a5..f5e89638f161 100644 --- a/src/test/ui/issue-3779.stderr +++ b/src/test/ui/issue-3779.stderr @@ -11,4 +11,4 @@ LL | element: Option error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/issue-37884.stderr b/src/test/ui/issue-37884.stderr index d1f6cb7d9226..73fbb2d32038 100644 --- a/src/test/ui/issue-37884.stderr +++ b/src/test/ui/issue-37884.stderr @@ -29,4 +29,4 @@ LL | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr index 999583dcd311..70be30e4f71d 100644 --- a/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr +++ b/src/test/ui/issue-40402-ref-hints/issue-40402-1.stderr @@ -9,4 +9,4 @@ LL | let e = f.v[0]; //~ ERROR cannot move out of indexed content error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0507" +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr index 3703d32be064..4ed28963b5b9 100644 --- a/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr +++ b/src/test/ui/issue-40402-ref-hints/issue-40402-2.stderr @@ -9,4 +9,4 @@ LL | let (a, b) = x[0]; //~ ERROR cannot move out of indexed content error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0507" +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/issue-41652/issue_41652.stderr b/src/test/ui/issue-41652/issue_41652.stderr index df7b8a6525f8..3f76b25692cf 100644 --- a/src/test/ui/issue-41652/issue_41652.stderr +++ b/src/test/ui/issue-41652/issue_41652.stderr @@ -10,4 +10,4 @@ LL | 3_i32.f() error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0689" +For more information about this error, try `rustc --explain E0689`. diff --git a/src/test/ui/issue-42106.stderr b/src/test/ui/issue-42106.stderr index c9629cc6e61d..b8944bb24239 100644 --- a/src/test/ui/issue-42106.stderr +++ b/src/test/ui/issue-42106.stderr @@ -10,4 +10,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0502" +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/issue-4335.stderr b/src/test/ui/issue-4335.stderr index 90b94a597a5d..80f5b445bb64 100644 --- a/src/test/ui/issue-4335.stderr +++ b/src/test/ui/issue-4335.stderr @@ -18,5 +18,5 @@ LL | id(Box::new(|| *v)) error: aborting due to 2 previous errors -You've got a few errors: E0373, E0507 -If you want more information on an error, try using "rustc --explain E0373" +Some errors occurred: E0373, E0507. +For more information about an error, try `rustc --explain E0373`. diff --git a/src/test/ui/issue-44023.stderr b/src/test/ui/issue-44023.stderr index a3dde7321c26..3baf7ec0277b 100644 --- a/src/test/ui/issue-44023.stderr +++ b/src/test/ui/issue-44023.stderr @@ -11,4 +11,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-45157.stderr b/src/test/ui/issue-45157.stderr index 07102f68633c..e528a84ebd1a 100644 --- a/src/test/ui/issue-45157.stderr +++ b/src/test/ui/issue-45157.stderr @@ -12,4 +12,4 @@ LL | println!("{} {}", mref, nref) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0502" +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/issue-45697-1.stderr b/src/test/ui/issue-45697-1.stderr index 2a6d219267d2..aa899c5aee9e 100644 --- a/src/test/ui/issue-45697-1.stderr +++ b/src/test/ui/issue-45697-1.stderr @@ -16,5 +16,5 @@ LL | *y.pointer += 1; error: aborting due to 2 previous errors -You've got a few errors: E0503, E0506 -If you want more information on an error, try using "rustc --explain E0503" +Some errors occurred: E0503, E0506. +For more information about an error, try `rustc --explain E0503`. diff --git a/src/test/ui/issue-45697.stderr b/src/test/ui/issue-45697.stderr index 30baded7dad9..babfc33b9458 100644 --- a/src/test/ui/issue-45697.stderr +++ b/src/test/ui/issue-45697.stderr @@ -16,5 +16,5 @@ LL | *y.pointer += 1; error: aborting due to 2 previous errors -You've got a few errors: E0503, E0506 -If you want more information on an error, try using "rustc --explain E0503" +Some errors occurred: E0503, E0506. +For more information about an error, try `rustc --explain E0503`. diff --git a/src/test/ui/issue-45730.stderr b/src/test/ui/issue-45730.stderr index b10c69f26c5c..aa5773e3dbff 100644 --- a/src/test/ui/issue-45730.stderr +++ b/src/test/ui/issue-45730.stderr @@ -30,4 +30,4 @@ LL | let x = 0 as *const i32 as *const _ as *mut _; //~ ERROR cannot cast error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0641" +For more information about this error, try `rustc --explain E0641`. diff --git a/src/test/ui/issue-46112.stderr b/src/test/ui/issue-46112.stderr index 7c6796841650..796187b93aa9 100644 --- a/src/test/ui/issue-46112.stderr +++ b/src/test/ui/issue-46112.stderr @@ -12,4 +12,4 @@ LL | fn main() { test(Ok(())); } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-46332.stderr b/src/test/ui/issue-46332.stderr index c3b17884676b..06553767cc97 100644 --- a/src/test/ui/issue-46332.stderr +++ b/src/test/ui/issue-46332.stderr @@ -6,4 +6,4 @@ LL | TyUInt {}; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0422" +For more information about this error, try `rustc --explain E0422`. diff --git a/src/test/ui/issue-46471-1.stderr b/src/test/ui/issue-46471-1.stderr index b46bcbd69112..bfd5bfa9f727 100644 --- a/src/test/ui/issue-46471-1.stderr +++ b/src/test/ui/issue-46471-1.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issue-46471.stderr b/src/test/ui/issue-46471.stderr index ce2b2c310259..ac974afa13a1 100644 --- a/src/test/ui/issue-46471.stderr +++ b/src/test/ui/issue-46471.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issue-46472.stderr b/src/test/ui/issue-46472.stderr index a0d41c961a44..9b55b78b43d5 100644 --- a/src/test/ui/issue-46472.stderr +++ b/src/test/ui/issue-46472.stderr @@ -30,4 +30,4 @@ LL | fn bar<'a>() -> &'a mut u32 { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issue-46983.stderr b/src/test/ui/issue-46983.stderr index 67c8fa8261f7..31aeebd5a721 100644 --- a/src/test/ui/issue-46983.stderr +++ b/src/test/ui/issue-46983.stderr @@ -8,4 +8,4 @@ LL | &*x error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/issue-47377.stderr b/src/test/ui/issue-47377.stderr index 2de117489c39..66c4a1277a0f 100644 --- a/src/test/ui/issue-47377.stderr +++ b/src/test/ui/issue-47377.stderr @@ -10,4 +10,4 @@ LL | let _a = b.to_owned() + ", World!"; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0369" +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issue-47380.stderr b/src/test/ui/issue-47380.stderr index 968dc614ad68..585a2ec64d06 100644 --- a/src/test/ui/issue-47380.stderr +++ b/src/test/ui/issue-47380.stderr @@ -10,4 +10,4 @@ LL | println!("🦀🦀🦀🦀🦀"); let _a = b.to_owned() + ", World!"; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0369" +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/issue-47511.stderr b/src/test/ui/issue-47511.stderr index 2b8ba8794fb7..6ee71fc6c73d 100644 --- a/src/test/ui/issue-47511.stderr +++ b/src/test/ui/issue-47511.stderr @@ -14,4 +14,4 @@ LL | fn g<'a>(_: X<'a>) -> X<'a> { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0581" +For more information about this error, try `rustc --explain E0581`. diff --git a/src/test/ui/issue-47623.stderr b/src/test/ui/issue-47623.stderr index fd15ce784208..8cbed1c293e1 100644 --- a/src/test/ui/issue-47623.stderr +++ b/src/test/ui/issue-47623.stderr @@ -6,4 +6,4 @@ LL | use self; //~ERROR `self` imports are only allowed within a { } list error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0429" +For more information about this error, try `rustc --explain E0429`. diff --git a/src/test/ui/issue-47706-trait.stderr b/src/test/ui/issue-47706-trait.stderr index a6a270b057a4..542ba5017806 100644 --- a/src/test/ui/issue-47706-trait.stderr +++ b/src/test/ui/issue-47706-trait.stderr @@ -10,5 +10,5 @@ LL | None::<()>.map(Self::f); error: aborting due to 2 previous errors -You've got a few errors: E0593, E0601 -If you want more information on an error, try using "rustc --explain E0593" +Some errors occurred: E0593, E0601. +For more information about an error, try `rustc --explain E0593`. diff --git a/src/test/ui/issue-47706.stderr b/src/test/ui/issue-47706.stderr index ef48d4d7aaef..0a5c8beccd13 100644 --- a/src/test/ui/issue-47706.stderr +++ b/src/test/ui/issue-47706.stderr @@ -28,4 +28,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0593" +For more information about this error, try `rustc --explain E0593`. diff --git a/src/test/ui/issue-48276.stderr b/src/test/ui/issue-48276.stderr index 9273ece2c908..db4894aa6916 100644 --- a/src/test/ui/issue-48276.stderr +++ b/src/test/ui/issue-48276.stderr @@ -25,4 +25,4 @@ LL | fn from(&self) -> &'static str { error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0185" +For more information about this error, try `rustc --explain E0185`. diff --git a/src/test/ui/issue-4935.stderr b/src/test/ui/issue-4935.stderr index fb5a2261c1f6..25efd54443ae 100644 --- a/src/test/ui/issue-4935.stderr +++ b/src/test/ui/issue-4935.stderr @@ -9,4 +9,4 @@ LL | fn main() { foo(5, 6) } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0061" +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/issue-5239-1.stderr b/src/test/ui/issue-5239-1.stderr index 6a6405726232..2f9204e72d3f 100644 --- a/src/test/ui/issue-5239-1.stderr +++ b/src/test/ui/issue-5239-1.stderr @@ -8,4 +8,4 @@ LL | let x = |ref x: isize| { x += 1; }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0368" +For more information about this error, try `rustc --explain E0368`. diff --git a/src/test/ui/issue-6458-3.stderr b/src/test/ui/issue-6458-3.stderr index 8eb864a878a1..c09b2643dfa2 100644 --- a/src/test/ui/issue-6458-3.stderr +++ b/src/test/ui/issue-6458-3.stderr @@ -6,4 +6,4 @@ LL | mem::transmute(0); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issue-6458-4.stderr b/src/test/ui/issue-6458-4.stderr index 2615085a930d..13b0ace64652 100644 --- a/src/test/ui/issue-6458-4.stderr +++ b/src/test/ui/issue-6458-4.stderr @@ -13,4 +13,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/issue-6458.stderr b/src/test/ui/issue-6458.stderr index 058a6ea5c7d7..701795c748dc 100644 --- a/src/test/ui/issue-6458.stderr +++ b/src/test/ui/issue-6458.stderr @@ -6,4 +6,4 @@ LL | foo(TypeWithState(marker::PhantomData)); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/issue-7813.stderr b/src/test/ui/issue-7813.stderr index b4291684db4b..34837e90e4f7 100644 --- a/src/test/ui/issue-7813.stderr +++ b/src/test/ui/issue-7813.stderr @@ -8,4 +8,4 @@ LL | let v = &[]; //~ ERROR type annotations needed error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetime-elision-return-type-requires-explicit-lifetime.stderr index b8145a893aac..30cff86ed1d4 100644 --- a/src/test/ui/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -52,4 +52,4 @@ LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize { error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0106" +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr b/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr index 4cf0ad0888b2..87cb17489135 100644 --- a/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr +++ b/src/test/ui/lifetime-errors/42701_one_named_and_one_anonymous.stderr @@ -9,4 +9,4 @@ LL | &*x //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr index 5b65dffdb38b..29163361e23f 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr @@ -9,4 +9,4 @@ LL | other //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr index b11b96595dfa..e18156179a20 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr @@ -8,4 +8,4 @@ LL | if x > y { x } else { y } //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr index a334f97b3cc4..f208fb57f5b7 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr @@ -8,4 +8,4 @@ LL | if x > y { x } else { y } //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr index d61292330b89..7604b9a9017e 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr @@ -8,4 +8,4 @@ LL | if x > y { x } else { y } //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr index 9efdb33f7e58..83c6ff19867d 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr @@ -9,4 +9,4 @@ LL | if true { &self.field } else { x } //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr index f27d869a4d4a..0eb8afbb26b6 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr @@ -11,4 +11,4 @@ LL | if x > y { x } else { y } //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr index d098df514e1a..9893eee77e8c 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else.stderr @@ -8,4 +8,4 @@ LL | if x > y { x } else { y } //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index c72d25fe2a9f..b6dfdff60be2 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -11,4 +11,4 @@ LL | x //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index 4d9e26c06326..6c32adc11ce0 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -11,4 +11,4 @@ LL | if true { x } else { self } //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr index 90f210148522..4710ebfa9679 100644 --- a/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -8,4 +8,4 @@ LL | fn foo(x: &i32, y: &i32) -> &i32 { //~ ERROR missing lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0106" +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr index 5d3316276916..5c9b7666de65 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-2.stderr @@ -8,4 +8,4 @@ LL | y.push(x); //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr index d840467835ba..4cfb76f85f2a 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr @@ -9,4 +9,4 @@ LL | x.push(y); //~ ERROR explicit lifetime required error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr index a5433ec08340..ede76bca2ba0 100644 --- a/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr +++ b/src/test/ui/lifetime-errors/ex2a-push-one-existing-name.stderr @@ -8,4 +8,4 @@ LL | x.push(y); //~ ERROR explicit lifetime error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr index dd220a7e661d..9884c0f35116 100644 --- a/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr +++ b/src/test/ui/lifetime-errors/ex2b-push-no-existing-names.stderr @@ -8,4 +8,4 @@ LL | x.push(y); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr index bba52f408b0c..114024c2fb02 100644 --- a/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr +++ b/src/test/ui/lifetime-errors/ex2c-push-inference-variable.stderr @@ -9,4 +9,4 @@ LL | x.push(z); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr index 673aee256b4f..32fc8b42f42e 100644 --- a/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr +++ b/src/test/ui/lifetime-errors/ex2d-push-inference-variable-2.stderr @@ -8,4 +8,4 @@ LL | let a: &mut Vec> = x; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr index cbe48abbb993..f62848ffa8c1 100644 --- a/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr +++ b/src/test/ui/lifetime-errors/ex2e-push-inference-variable-3.stderr @@ -8,4 +8,4 @@ LL | let a: &mut Vec> = x; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr index eb7985a565ff..f3716c307035 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-2.stderr @@ -8,4 +8,4 @@ LL | v = x; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr index e9c156149d41..5a584296d3ba 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-3.stderr @@ -16,4 +16,4 @@ LL | z.push((x,y)); //~ ERROR lifetime mismatch error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr index 19cd661505ad..158f40f2969a 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr @@ -8,4 +8,4 @@ LL | x.b = y.b; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr index 52a319fad610..546789eedcb9 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr @@ -10,4 +10,4 @@ LL | x.a = x.b; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr index 121afa47bc1b..ccc5e02ab704 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr @@ -10,4 +10,4 @@ LL | x.a = x.b; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr index 7348b366e801..f69bcb642978 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr @@ -9,4 +9,4 @@ LL | x.push(y); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr index 5478abfdbc00..f9530c436a0a 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr @@ -8,4 +8,4 @@ LL | x.push(y); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr index 1cde0d83feb1..243103e2d180 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr @@ -8,4 +8,4 @@ LL | x.push(y); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr index ca6c4337b9b8..c4dd28234317 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr @@ -8,4 +8,4 @@ LL | x.push(y); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr index 8bcc7d4a92bf..52293e453061 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr @@ -10,4 +10,4 @@ LL | y = x.b; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr index 80639d9359e2..b5d10e573c4e 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr @@ -8,4 +8,4 @@ LL | y.b = x; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr index c0ceefdea171..089132995206 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr @@ -8,4 +8,4 @@ LL | y.b = x; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr index 28af2905e4ae..133611ae4894 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr @@ -8,4 +8,4 @@ LL | x.b = y; //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index ff2492b94360..01ea885b63ea 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -10,4 +10,4 @@ LL | x //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index b6bd1c5c9221..aa5ab5402959 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -10,4 +10,4 @@ LL | if true { x } else { self } //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr index 5a5abf3f98b8..8a9ee9a05b81 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr @@ -8,4 +8,4 @@ LL | y.push(z); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr index b09877ede38a..65c9ea4e757f 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr @@ -8,4 +8,4 @@ LL | x.push(y); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr index 9e18c2e11bf7..43ca5cd603f1 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr @@ -8,4 +8,4 @@ LL | y.push(z); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr index d73af970e56e..57187a47239c 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions.stderr @@ -8,4 +8,4 @@ LL | x.push(y); //~ ERROR lifetime mismatch error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr b/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr index 8a69514932af..437431189665 100644 --- a/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr +++ b/src/test/ui/lifetime-errors/liveness-assign-imm-local-notes.stderr @@ -62,4 +62,4 @@ LL | x = 2; //~ ERROR (Ast) [E0384] error: aborting due to 8 previous errors -If you want more information on this error, try using "rustc --explain E0384" +For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr index aaa01a86d60a..c78b09a86a49 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -13,4 +13,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr index b58cbfd7b2ea..ea79990bbb1f 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr @@ -111,5 +111,5 @@ LL | | } error: aborting due to 7 previous errors -You've got a few errors: E0309, E0310 -If you want more information on an error, try using "rustc --explain E0309" +Some errors occurred: E0309, E0310. +For more information about an error, try `rustc --explain E0309`. diff --git a/src/test/ui/lint-forbid-attr.stderr b/src/test/ui/lint-forbid-attr.stderr index 73a40a46c110..aa0c0c1f5c2b 100644 --- a/src/test/ui/lint-forbid-attr.stderr +++ b/src/test/ui/lint-forbid-attr.stderr @@ -9,4 +9,4 @@ LL | #[allow(deprecated)] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0453" +For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/outer-forbid.stderr b/src/test/ui/lint/outer-forbid.stderr index 62bec0fe7b33..e49dcd4a2d19 100644 --- a/src/test/ui/lint/outer-forbid.stderr +++ b/src/test/ui/lint/outer-forbid.stderr @@ -27,4 +27,4 @@ LL | #[allow(bad_style)] //~ ERROR overruled error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0453" +For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr index 00624f7e5ca4..b90c5aa3a4ba 100644 --- a/src/test/ui/lint/use_suggestion_json.stderr +++ b/src/test/ui/lint/use_suggestion_json.stderr @@ -384,7 +384,6 @@ LL | use std::collections::hash_map::Iter; | and 8 other candidates -If you want more information on this error, try using /"rustc --explain E0412/" " } { @@ -397,3 +396,12 @@ If you want more information on this error, try using /"rustc --explain E0412/" " } +{ + "message": "For more information about this error, try `rustc --explain E0412`.", + "code": null, + "level": "", + "spans": [], + "children": [], + "rendered": "For more information about this error, try `rustc --explain E0412`. +" +} diff --git a/src/test/ui/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness-return-last-stmt-semi.stderr index faf098296e8b..1fa001879a0a 100644 --- a/src/test/ui/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness-return-last-stmt-semi.stderr @@ -49,4 +49,4 @@ LL | | } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/loop-break-value-no-repeat.stderr b/src/test/ui/loop-break-value-no-repeat.stderr index 0f04847df4cd..4421f557e420 100644 --- a/src/test/ui/loop-break-value-no-repeat.stderr +++ b/src/test/ui/loop-break-value-no-repeat.stderr @@ -10,4 +10,4 @@ LL | break //~ ERROR `break` with value from a `for` loop error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0571" +For more information about this error, try `rustc --explain E0571`. diff --git a/src/test/ui/lub-glb/old-lub-glb-hr.stderr b/src/test/ui/lub-glb/old-lub-glb-hr.stderr index 0fa6fdae4812..9b40062bd57b 100644 --- a/src/test/ui/lub-glb/old-lub-glb-hr.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-hr.stderr @@ -16,4 +16,4 @@ LL | | }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr index 49fb063a9c68..6a69e7cc7172 100644 --- a/src/test/ui/lub-glb/old-lub-glb-object.stderr +++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr @@ -16,4 +16,4 @@ LL | | }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr index 58fc3c3a65b0..eab6cd23748c 100644 --- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr +++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr @@ -80,5 +80,5 @@ LL | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous n error: aborting due to 8 previous errors -You've got a few errors: E0599, E0609, E0610, E0689 -If you want more information on an error, try using "rustc --explain E0599" +Some errors occurred: E0599, E0609, E0610, E0689. +For more information about an error, try `rustc --explain E0599`. diff --git a/src/test/ui/macros/macro-backtrace-nested.stderr b/src/test/ui/macros/macro-backtrace-nested.stderr index a0ed467b5af5..a4fe702c0d93 100644 --- a/src/test/ui/macros/macro-backtrace-nested.stderr +++ b/src/test/ui/macros/macro-backtrace-nested.stderr @@ -18,4 +18,4 @@ LL | call_nested_expr_sum!(); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr index d573523a5a0d..06d22714dd8b 100644 --- a/src/test/ui/macros/macro_path_as_generic_bound.stderr +++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr @@ -6,4 +6,3 @@ LL | foo!(m::m2::A); //~ ERROR failed to resolve error: cannot continue compilation due to previous error -If you want more information on this error, try using "rustc --explain E0433" diff --git a/src/test/ui/macros/span-covering-argument-1.stderr b/src/test/ui/macros/span-covering-argument-1.stderr index 3343c210d24d..c67095d9ee75 100644 --- a/src/test/ui/macros/span-covering-argument-1.stderr +++ b/src/test/ui/macros/span-covering-argument-1.stderr @@ -11,4 +11,4 @@ LL | bad!(foo whatever); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/main-wrong-location.stderr b/src/test/ui/main-wrong-location.stderr index 0f775dba536e..aad68de9ec79 100644 --- a/src/test/ui/main-wrong-location.stderr +++ b/src/test/ui/main-wrong-location.stderr @@ -9,4 +9,4 @@ LL | fn main() { } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/method-call-err-msg.stderr b/src/test/ui/method-call-err-msg.stderr index 05d5bde18cf5..3e5bbdfa8f84 100644 --- a/src/test/ui/method-call-err-msg.stderr +++ b/src/test/ui/method-call-err-msg.stderr @@ -43,5 +43,5 @@ LL | .take() //~ ERROR no method named `take` found for type `Foo` in th error: aborting due to 4 previous errors -You've got a few errors: E0061, E0599 -If you want more information on an error, try using "rustc --explain E0061" +Some errors occurred: E0061, E0599. +For more information about an error, try `rustc --explain E0061`. diff --git a/src/test/ui/method-missing-call.stderr b/src/test/ui/method-missing-call.stderr index a5715d4a7ad9..82d04cb06dd4 100644 --- a/src/test/ui/method-missing-call.stderr +++ b/src/test/ui/method-missing-call.stderr @@ -16,4 +16,4 @@ LL | .filter_map; //~ ERROR attempted to take value of method `fil error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0615" +For more information about this error, try `rustc --explain E0615`. diff --git a/src/test/ui/mismatched_types/E0053.stderr b/src/test/ui/mismatched_types/E0053.stderr index 8256c9328d90..1b16694bf2c4 100644 --- a/src/test/ui/mismatched_types/E0053.stderr +++ b/src/test/ui/mismatched_types/E0053.stderr @@ -24,4 +24,4 @@ LL | fn bar(&mut self) { } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0053" +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/mismatched_types/E0409.stderr b/src/test/ui/mismatched_types/E0409.stderr index 93cea816824e..a1bfcafe0539 100644 --- a/src/test/ui/mismatched_types/E0409.stderr +++ b/src/test/ui/mismatched_types/E0409.stderr @@ -17,5 +17,5 @@ LL | (0, ref y) | (y, 0) => {} //~ ERROR E0409 error: aborting due to 2 previous errors -You've got a few errors: E0308, E0409 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0409. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr index 4560771f21e8..647e0a215aa5 100644 --- a/src/test/ui/mismatched_types/E0631.stderr +++ b/src/test/ui/mismatched_types/E0631.stderr @@ -58,4 +58,4 @@ LL | fn bar>(_: F) {} error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0631" +For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr index 423b460e31dd..1b2ea514f3e9 100644 --- a/src/test/ui/mismatched_types/abridged.stderr +++ b/src/test/ui/mismatched_types/abridged.stderr @@ -68,4 +68,4 @@ LL | x //~ ERROR mismatched types error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 75950c0f6d33..9d23b256fd33 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -48,4 +48,4 @@ LL | 6 == Ok(1); //~ ERROR is not satisfied error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr index a4e5a897e492..7931e7ff07f4 100644 --- a/src/test/ui/mismatched_types/cast-rfc0401.stderr +++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr @@ -248,5 +248,5 @@ LL | vec![0.0].iter().map(|s| s as f32).collect::>(); //~ ERROR is error: aborting due to 34 previous errors -You've got a few errors: E0054, E0277, E0604, E0605, E0606, E0607, E0609 -If you want more information on an error, try using "rustc --explain E0054" +Some errors occurred: E0054, E0277, E0604, E0605, E0606, E0607, E0609. +For more information about an error, try `rustc --explain E0054`. diff --git a/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr b/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr index 46cb027c9072..262c4aa1a7c7 100644 --- a/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count-expected-type-issue-47244.stderr @@ -12,4 +12,4 @@ LL | m.iter().map( |(_, b)| { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0593" +For more information about this error, try `rustc --explain E0593`. diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 0370c2596cc4..6451c0d06fa2 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -118,4 +118,4 @@ LL | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); error: aborting due to 12 previous errors -If you want more information on this error, try using "rustc --explain E0593" +For more information about this error, try `rustc --explain E0593`. diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index b37779dd0938..62e646c8d394 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -51,5 +51,5 @@ LL | fn baz(_: F) {} error: aborting due to 5 previous errors -You've got a few errors: E0271, E0631 -If you want more information on an error, try using "rustc --explain E0271" +Some errors occurred: E0271, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 3950242e27bd..cb03d0ea4cca 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -28,5 +28,5 @@ LL | fn baz(_: T) {} error: aborting due to 2 previous errors -You've got a few errors: E0271, E0631 -If you want more information on an error, try using "rustc --explain E0271" +Some errors occurred: E0271, E0631. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/mismatched_types/const-fn-in-trait.stderr b/src/test/ui/mismatched_types/const-fn-in-trait.stderr index 453f1d9e6143..ba248e076d4b 100644 --- a/src/test/ui/mismatched_types/const-fn-in-trait.stderr +++ b/src/test/ui/mismatched_types/const-fn-in-trait.stderr @@ -12,4 +12,4 @@ LL | const fn f() -> u32 { 22 } //~ ERROR cannot be declared const error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0379" +For more information about this error, try `rustc --explain E0379`. diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr index d62026f75204..221ee79bd67e 100644 --- a/src/test/ui/mismatched_types/fn-variance-1.stderr +++ b/src/test/ui/mismatched_types/fn-variance-1.stderr @@ -30,4 +30,4 @@ LL | fn apply(t: T, f: F) where F: FnOnce(T) { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0631" +For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/mismatched_types/for-loop-has-unit-body.stderr b/src/test/ui/mismatched_types/for-loop-has-unit-body.stderr index e28e3f12bf74..1fed52883973 100644 --- a/src/test/ui/mismatched_types/for-loop-has-unit-body.stderr +++ b/src/test/ui/mismatched_types/for-loop-has-unit-body.stderr @@ -9,4 +9,4 @@ LL | x //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/issue-19109.stderr b/src/test/ui/mismatched_types/issue-19109.stderr index c52048919b31..c838c617ae45 100644 --- a/src/test/ui/mismatched_types/issue-19109.stderr +++ b/src/test/ui/mismatched_types/issue-19109.stderr @@ -11,4 +11,4 @@ LL | t as *mut Trait error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index f07cb2f73143..ff047a28adcf 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -20,5 +20,5 @@ LL | cast!(2); error: aborting due to 2 previous errors -You've got a few errors: E0308, E0605 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0605. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr index df573df67d4c..062bda4468a3 100644 --- a/src/test/ui/mismatched_types/issue-35030.stderr +++ b/src/test/ui/mismatched_types/issue-35030.stderr @@ -9,4 +9,4 @@ LL | Some(true) //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index bd1a930baa93..86a92a70287e 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -18,5 +18,5 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count(); error: aborting due to 2 previous errors -You've got a few errors: E0599, E0631 -If you want more information on an error, try using "rustc --explain E0599" +Some errors occurred: E0599, E0631. +For more information about an error, try `rustc --explain E0599`. diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr index bba216b1e8cc..1bf1521e39e0 100644 --- a/src/test/ui/mismatched_types/issue-38371.stderr +++ b/src/test/ui/mismatched_types/issue-38371.stderr @@ -35,5 +35,5 @@ LL | fn ugh(&[bar]: &u32) { //~ ERROR expected an array or slice error: aborting due to 4 previous errors -You've got a few errors: E0308, E0529 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0529. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/main.stderr b/src/test/ui/mismatched_types/main.stderr index 7793a38b38eb..ce6f2ee6e052 100644 --- a/src/test/ui/mismatched_types/main.stderr +++ b/src/test/ui/mismatched_types/main.stderr @@ -11,4 +11,4 @@ LL | | ); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr index d84b8474ded6..471c15f6d72d 100644 --- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr +++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr @@ -9,4 +9,4 @@ LL | a.unwrap(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr index 830eec48d118..d841a340431a 100644 --- a/src/test/ui/mismatched_types/overloaded-calls-bad.stderr +++ b/src/test/ui/mismatched_types/overloaded-calls-bad.stderr @@ -21,5 +21,5 @@ LL | let ans = s("burma", "shave"); error: aborting due to 3 previous errors -You've got a few errors: E0057, E0308 -If you want more information on an error, try using "rustc --explain E0057" +Some errors occurred: E0057, E0308. +For more information about an error, try `rustc --explain E0057`. diff --git a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr index e922b203adf3..bbe9053430a1 100644 --- a/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr +++ b/src/test/ui/mismatched_types/trait-bounds-cant-coerce.stderr @@ -9,4 +9,4 @@ LL | a(x); //~ ERROR mismatched types [E0308] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr index 0460ec3194a7..28b16641e4dd 100644 --- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr +++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr @@ -24,4 +24,4 @@ LL | fn bar(&mut self, bar: &Bar) { } //~ ERROR incompatible type error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0053" +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index cac85e7fbac1..762f0744d80c 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -15,4 +15,4 @@ LL | fn call_itisize>(y: isize, mut f: F) -> isize { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0631" +For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/missing-items/issue-40221.stderr b/src/test/ui/missing-items/issue-40221.stderr index cb30805ce2f1..81c9f40f6cfb 100644 --- a/src/test/ui/missing-items/issue-40221.stderr +++ b/src/test/ui/missing-items/issue-40221.stderr @@ -6,4 +6,4 @@ LL | match proto { //~ ERROR non-exhaustive patterns error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0004" +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/missing-items/m2.stderr b/src/test/ui/missing-items/m2.stderr index aebe25ab4926..1e4b47b44fab 100644 --- a/src/test/ui/missing-items/m2.stderr +++ b/src/test/ui/missing-items/m2.stderr @@ -12,5 +12,5 @@ LL | impl m1::X for X { //~ ERROR not all trait items implemented error: aborting due to 2 previous errors -You've got a few errors: E0046, E0601 -If you want more information on an error, try using "rustc --explain E0046" +Some errors occurred: E0046, E0601. +For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/missing-items/missing-type-parameter.stderr b/src/test/ui/missing-items/missing-type-parameter.stderr index c2798af66f21..a27e8aac28f2 100644 --- a/src/test/ui/missing-items/missing-type-parameter.stderr +++ b/src/test/ui/missing-items/missing-type-parameter.stderr @@ -6,4 +6,4 @@ LL | foo(); //~ ERROR type annotations needed error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr index 1df422730ecf..f494af0ff3ec 100644 --- a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr +++ b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr @@ -8,4 +8,4 @@ LL | mod missing; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0583" +For more information about this error, try `rustc --explain E0583`. diff --git a/src/test/ui/moves-based-on-type-block-bad.stderr b/src/test/ui/moves-based-on-type-block-bad.stderr index fd83309274d8..f1b882924109 100644 --- a/src/test/ui/moves-based-on-type-block-bad.stderr +++ b/src/test/ui/moves-based-on-type-block-bad.stderr @@ -9,4 +9,4 @@ LL | box E::Bar(x) => println!("{}", x.to_string()), error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0507" +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/moves-based-on-type-match-bindings.stderr b/src/test/ui/moves-based-on-type-match-bindings.stderr index 1c33004d8f69..62e16df583f8 100644 --- a/src/test/ui/moves-based-on-type-match-bindings.stderr +++ b/src/test/ui/moves-based-on-type-match-bindings.stderr @@ -11,4 +11,4 @@ LL | touch(&x); //~ ERROR use of partially moved value: `x` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/moves-based-on-type-tuple.stderr b/src/test/ui/moves-based-on-type-tuple.stderr index a614b33c63e9..b0a3b6bf1fd6 100644 --- a/src/test/ui/moves-based-on-type-tuple.stderr +++ b/src/test/ui/moves-based-on-type-tuple.stderr @@ -20,4 +20,4 @@ LL | box (x, x) error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0382" +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/nested_impl_trait.stderr b/src/test/ui/nested_impl_trait.stderr index b3e61e74bbb7..10d767db8d32 100644 --- a/src/test/ui/nested_impl_trait.stderr +++ b/src/test/ui/nested_impl_trait.stderr @@ -48,5 +48,5 @@ LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into { error: aborting due to 6 previous errors -You've got a few errors: E0562, E0666 -If you want more information on an error, try using "rustc --explain E0562" +Some errors occurred: E0562, E0666. +For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/nll/borrowed-local-error.stderr b/src/test/ui/nll/borrowed-local-error.stderr index 24964f651f79..901b1ca271a5 100644 --- a/src/test/ui/nll/borrowed-local-error.stderr +++ b/src/test/ui/nll/borrowed-local-error.stderr @@ -14,4 +14,4 @@ LL | | }); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/borrowed-match-issue-45045.stderr b/src/test/ui/nll/borrowed-match-issue-45045.stderr index a80bc686e34a..7904e6015799 100644 --- a/src/test/ui/nll/borrowed-match-issue-45045.stderr +++ b/src/test/ui/nll/borrowed-match-issue-45045.stderr @@ -27,4 +27,4 @@ LL | *g = Xyz::B; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0503" +For more information about this error, try `rustc --explain E0503`. diff --git a/src/test/ui/nll/borrowed-referent-issue-38899.stderr b/src/test/ui/nll/borrowed-referent-issue-38899.stderr index 675f85ecb4dd..5c5a66e7e21d 100644 --- a/src/test/ui/nll/borrowed-referent-issue-38899.stderr +++ b/src/test/ui/nll/borrowed-referent-issue-38899.stderr @@ -12,4 +12,4 @@ LL | drop(x); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0502" +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/borrowed-temporary-error.stderr b/src/test/ui/nll/borrowed-temporary-error.stderr index 575d9b5a62d7..37746a173eb7 100644 --- a/src/test/ui/nll/borrowed-temporary-error.stderr +++ b/src/test/ui/nll/borrowed-temporary-error.stderr @@ -11,4 +11,4 @@ LL | println!("{:?}", x); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/borrowed-universal-error-2.stderr b/src/test/ui/nll/borrowed-universal-error-2.stderr index 2e4d7cc8f818..467b02d207dd 100644 --- a/src/test/ui/nll/borrowed-universal-error-2.stderr +++ b/src/test/ui/nll/borrowed-universal-error-2.stderr @@ -15,4 +15,4 @@ LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/borrowed-universal-error.stderr b/src/test/ui/nll/borrowed-universal-error.stderr index 3e9a3ceb1dba..94d9bb36fa42 100644 --- a/src/test/ui/nll/borrowed-universal-error.stderr +++ b/src/test/ui/nll/borrowed-universal-error.stderr @@ -15,4 +15,4 @@ LL | fn foo<'a>(x: &'a (u32,)) -> &'a u32 { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/capture-ref-in-struct.stderr b/src/test/ui/nll/capture-ref-in-struct.stderr index 0fb718075849..81946de612af 100644 --- a/src/test/ui/nll/capture-ref-in-struct.stderr +++ b/src/test/ui/nll/capture-ref-in-struct.stderr @@ -12,4 +12,4 @@ LL | deref(p); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr index 18ffdc583497..a9a52aba8421 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr @@ -37,4 +37,4 @@ LL | deref(p); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr index 7b2b2f748726..a7fb9d90a218 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -64,4 +64,4 @@ LL | deref(p); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr index 0a45603a42cd..fd6b7a2e68d3 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -41,4 +41,4 @@ LL | deref(p); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index 798f222c136e..947b95b1c532 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -49,4 +49,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 86653138a185..d39cdc34471a 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -83,4 +83,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index 6eb0926b1c83..475fdd947817 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -49,4 +49,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr index dfe4e5f844e1..5bdfc7e935fe 100644 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr @@ -60,4 +60,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr index a162d754defa..1e93ae1ee07c 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr-anon-does-not-outlive-static.stderr @@ -14,4 +14,4 @@ LL | &*x error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr index f8bf188e789e..3af6d7d21f75 100644 --- a/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr +++ b/src/test/ui/nll/closure-requirements/region-lbr1-does-not-outlive-ebr2.stderr @@ -16,4 +16,4 @@ LL | &*x error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0623" +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/nll/drop-no-may-dangle.stderr b/src/test/ui/nll/drop-no-may-dangle.stderr index bbb9c0051bc9..6454413901be 100644 --- a/src/test/ui/nll/drop-no-may-dangle.stderr +++ b/src/test/ui/nll/drop-no-may-dangle.stderr @@ -23,4 +23,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0506" +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/get_default.stderr b/src/test/ui/nll/get_default.stderr index 37c9a10cf927..064fd38b8725 100644 --- a/src/test/ui/nll/get_default.stderr +++ b/src/test/ui/nll/get_default.stderr @@ -48,4 +48,4 @@ LL | return v; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0502" +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/guarantor-issue-46974.stderr b/src/test/ui/nll/guarantor-issue-46974.stderr index 82c5e8dafdce..3cb20cc975f4 100644 --- a/src/test/ui/nll/guarantor-issue-46974.stderr +++ b/src/test/ui/nll/guarantor-issue-46974.stderr @@ -20,5 +20,5 @@ LL | &s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621] error: aborting due to 2 previous errors -You've got a few errors: E0506, E0621 -If you want more information on an error, try using "rustc --explain E0506" +Some errors occurred: E0506, E0621. +For more information about an error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/issue-31567.stderr b/src/test/ui/nll/issue-31567.stderr index e0ff653e2b4d..579dc7eba8c8 100644 --- a/src/test/ui/nll/issue-31567.stderr +++ b/src/test/ui/nll/issue-31567.stderr @@ -15,4 +15,4 @@ LL | fn get_dangling<'a>(v: VecWrapper<'a>) -> &'a u32 { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/issue-47470.stderr b/src/test/ui/nll/issue-47470.stderr index 1356461a6e41..f84a68d85b95 100644 --- a/src/test/ui/nll/issue-47470.stderr +++ b/src/test/ui/nll/issue-47470.stderr @@ -14,4 +14,4 @@ LL | impl<'a> Bar for Foo<'a> { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr index d34b8184e6d8..327454ee60e5 100644 --- a/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr +++ b/src/test/ui/nll/maybe-initialized-drop-implicit-fragment-drop.stderr @@ -12,4 +12,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0506" +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/maybe-initialized-drop-with-fragment.stderr b/src/test/ui/nll/maybe-initialized-drop-with-fragment.stderr index ed81aa6006a2..54be12f28954 100644 --- a/src/test/ui/nll/maybe-initialized-drop-with-fragment.stderr +++ b/src/test/ui/nll/maybe-initialized-drop-with-fragment.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0506" +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr b/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr index 96eb2afd5b16..ee926e427931 100644 --- a/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr +++ b/src/test/ui/nll/maybe-initialized-drop-with-uninitialized-fragments.stderr @@ -12,4 +12,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0506" +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/maybe-initialized-drop.stderr b/src/test/ui/nll/maybe-initialized-drop.stderr index 1e4851d10da5..cc842c29ccb1 100644 --- a/src/test/ui/nll/maybe-initialized-drop.stderr +++ b/src/test/ui/nll/maybe-initialized-drop.stderr @@ -10,4 +10,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0506" +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/return-ref-mut-issue-46557.stderr b/src/test/ui/nll/return-ref-mut-issue-46557.stderr index 2184beac99b6..f40e38c63f5a 100644 --- a/src/test/ui/nll/return-ref-mut-issue-46557.stderr +++ b/src/test/ui/nll/return-ref-mut-issue-46557.stderr @@ -14,4 +14,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/trait-associated-constant.stderr b/src/test/ui/nll/trait-associated-constant.stderr index 990b5faf3471..2c3fd091f9a0 100644 --- a/src/test/ui/nll/trait-associated-constant.stderr +++ b/src/test/ui/nll/trait-associated-constant.stderr @@ -38,4 +38,4 @@ LL | impl<'a: 'b, 'b> Anything<'a, 'b> for FailStruct2 { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr index 3b75b8d7027e..bfa58bfc8074 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -14,4 +14,4 @@ LL | x error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0621" +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr index 33abfb5c3a1f..f29d2233e707 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr @@ -28,4 +28,4 @@ LL | x error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr index 2ad715e0c5b1..fa53967ed3ac 100644 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr +++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr @@ -14,4 +14,4 @@ LL | twice(value, |value_ref, item| invoke2(value_ref, item)); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0310" +For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr index a580502f1757..bcdf984f65a8 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -159,4 +159,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr index 05385c16bdc4..95851e7edc70 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr @@ -28,4 +28,4 @@ LL | Box::new(x.next()) error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index f557b448cec3..aa45cf187010 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -198,4 +198,4 @@ LL | | } error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 4fc0dffa6757..c7cbdaec3395 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -330,4 +330,4 @@ LL | | } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index ab3c40064596..997cc57cfa28 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -85,4 +85,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr index 76ccb13e53e0..ba08bc1ff7b4 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr @@ -60,4 +60,4 @@ LL | x error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 83d2b959c801..fcdb0b0a4a9f 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -193,4 +193,4 @@ LL | | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr index bdbde6c4ac01..1510ca61e5c7 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body-nll-feature.stderr @@ -8,4 +8,4 @@ LL | outlives(cell, t) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr index 21ca9e38103b..34ed709a2730 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr @@ -14,4 +14,4 @@ LL | outlives(cell, t) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr index 9fe074a299d0..98ccfc52029f 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr @@ -28,4 +28,4 @@ LL | x error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0309" +For more information about this error, try `rustc --explain E0309`. diff --git a/src/test/ui/no-patterns-in-args.stderr b/src/test/ui/no-patterns-in-args.stderr index e0e5ed07ef28..8ac1cced28fb 100644 --- a/src/test/ui/no-patterns-in-args.stderr +++ b/src/test/ui/no-patterns-in-args.stderr @@ -30,5 +30,5 @@ LL | type A2 = fn(&arg: u8); //~ ERROR patterns aren't allowed in function point error: aborting due to 5 previous errors -You've got a few errors: E0130, E0561 -If you want more information on an error, try using "rustc --explain E0130" +Some errors occurred: E0130, E0561. +For more information about an error, try `rustc --explain E0130`. diff --git a/src/test/ui/non-constant-expr-for-arr-len.stderr b/src/test/ui/non-constant-expr-for-arr-len.stderr index 6e9bafa5a4cc..9504c84b10ed 100644 --- a/src/test/ui/non-constant-expr-for-arr-len.stderr +++ b/src/test/ui/non-constant-expr-for-arr-len.stderr @@ -6,4 +6,4 @@ LL | let _x = [0; n]; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0435" +For more information about this error, try `rustc --explain E0435`. diff --git a/src/test/ui/non-exhaustive-pattern-witness.stderr b/src/test/ui/non-exhaustive-pattern-witness.stderr index 74bf0e256e3b..7179b4b135a1 100644 --- a/src/test/ui/non-exhaustive-pattern-witness.stderr +++ b/src/test/ui/non-exhaustive-pattern-witness.stderr @@ -42,4 +42,4 @@ LL | match ((), false) { error: aborting due to 7 previous errors -If you want more information on this error, try using "rustc --explain E0004" +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr index d4ca6f53feb2..c45ab734fd57 100644 --- a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr +++ b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr @@ -36,4 +36,4 @@ LL | pub mod innest; error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/not-enough-arguments.stderr b/src/test/ui/not-enough-arguments.stderr index a39070cef1f5..6a869cc5d552 100644 --- a/src/test/ui/not-enough-arguments.stderr +++ b/src/test/ui/not-enough-arguments.stderr @@ -9,4 +9,4 @@ LL | foo(1, 2, 3); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0061" +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/numeric-fields.stderr b/src/test/ui/numeric-fields.stderr index bed94e8f09a9..607980ba3bf5 100644 --- a/src/test/ui/numeric-fields.stderr +++ b/src/test/ui/numeric-fields.stderr @@ -14,5 +14,5 @@ LL | S{0: a, 0x1: b, ..} => {} error: aborting due to 2 previous errors -You've got a few errors: E0026, E0560 -If you want more information on an error, try using "rustc --explain E0026" +Some errors occurred: E0026, E0560. +For more information about an error, try `rustc --explain E0026`. diff --git a/src/test/ui/object-safety-associated-consts.stderr b/src/test/ui/object-safety-associated-consts.stderr index 71a2a4992677..39ec5a64e933 100644 --- a/src/test/ui/object-safety-associated-consts.stderr +++ b/src/test/ui/object-safety-associated-consts.stderr @@ -8,4 +8,4 @@ LL | fn make_bar(t: &T) -> &Bar { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety-generics.stderr b/src/test/ui/object-safety-generics.stderr index e10a2c6b1249..e5dfa6666303 100644 --- a/src/test/ui/object-safety-generics.stderr +++ b/src/test/ui/object-safety-generics.stderr @@ -16,4 +16,4 @@ LL | fn make_bar_explicit(t: &T) -> &Bar { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety-mentions-Self.stderr b/src/test/ui/object-safety-mentions-Self.stderr index a1690d60ff28..b181be95a540 100644 --- a/src/test/ui/object-safety-mentions-Self.stderr +++ b/src/test/ui/object-safety-mentions-Self.stderr @@ -16,4 +16,4 @@ LL | fn make_baz(t: &T) -> &Baz { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety-sized.stderr b/src/test/ui/object-safety-sized.stderr index 994dd943c76e..a6dd16666c68 100644 --- a/src/test/ui/object-safety-sized.stderr +++ b/src/test/ui/object-safety-sized.stderr @@ -8,4 +8,4 @@ LL | fn make_bar(t: &T) -> &Bar { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety-supertrait-mentions-Self.stderr index d2ca35ced9d9..f562bc6c54f9 100644 --- a/src/test/ui/object-safety-supertrait-mentions-Self.stderr +++ b/src/test/ui/object-safety-supertrait-mentions-Self.stderr @@ -8,4 +8,4 @@ LL | fn make_baz(t: &T) -> &Baz { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/on-unimplemented/bad-annotation.stderr b/src/test/ui/on-unimplemented/bad-annotation.stderr index ce4dcfb906d3..c37383757384 100644 --- a/src/test/ui/on-unimplemented/bad-annotation.stderr +++ b/src/test/ui/on-unimplemented/bad-annotation.stderr @@ -74,5 +74,5 @@ LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message error: aborting due to 10 previous errors -You've got a few errors: E0230, E0231, E0232 -If you want more information on an error, try using "rustc --explain E0230" +Some errors occurred: E0230, E0231, E0232. +For more information about an error, try `rustc --explain E0230`. diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index ca0723875884..23635a3c415d 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -63,4 +63,4 @@ LL | Index::index(&[] as &[i32], Bar(2u32)); error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr index dfb7b576c5a3..5d8f80e57b07 100644 --- a/src/test/ui/on-unimplemented/no-debug.stderr +++ b/src/test/ui/on-unimplemented/no-debug.stderr @@ -36,4 +36,4 @@ LL | println!("{} {}", Foo, Bar); error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index 6f9868d4cdaf..2b286ad0be7f 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -21,4 +21,4 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr index 8708f1461863..8bd910403b47 100644 --- a/src/test/ui/on-unimplemented/on-trait.stderr +++ b/src/test/ui/on-unimplemented/on-trait.stderr @@ -26,4 +26,4 @@ LL | fn foobar>() -> T { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/slice-index.stderr b/src/test/ui/on-unimplemented/slice-index.stderr index 5e507b3aa9c5..6a4756eb1c98 100644 --- a/src/test/ui/on-unimplemented/slice-index.stderr +++ b/src/test/ui/on-unimplemented/slice-index.stderr @@ -18,4 +18,4 @@ LL | x[..1i32]; //~ ERROR E0277 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/partialeq_help.stderr b/src/test/ui/partialeq_help.stderr index ff03c7efa509..c813b64d40b5 100644 --- a/src/test/ui/partialeq_help.stderr +++ b/src/test/ui/partialeq_help.stderr @@ -9,4 +9,4 @@ LL | a == b; //~ ERROR E0277 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/pat-slice-old-style.stderr b/src/test/ui/pat-slice-old-style.stderr index 0fbd9b8e2095..6fa5b18a14e8 100644 --- a/src/test/ui/pat-slice-old-style.stderr +++ b/src/test/ui/pat-slice-old-style.stderr @@ -8,4 +8,4 @@ LL | [a, b..] => {}, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/qualified-path-params-2.stderr b/src/test/ui/qualified-path-params-2.stderr index 471e6f4fa5db..8b618cbf7ba9 100644 --- a/src/test/ui/qualified-path-params-2.stderr +++ b/src/test/ui/qualified-path-params-2.stderr @@ -14,5 +14,5 @@ LL | type A = ::A::f; error: aborting due to 2 previous errors -You've got a few errors: E0109, E0223 -If you want more information on an error, try using "rustc --explain E0109" +Some errors occurred: E0109, E0223. +For more information about an error, try `rustc --explain E0109`. diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index beb0f5562929..b09721e59570 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -32,4 +32,4 @@ LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0600" +For more information about this error, try `rustc --explain E0600`. diff --git a/src/test/ui/recursive-requirements.stderr b/src/test/ui/recursive-requirements.stderr index 2f5945d9fe45..d9e08102ab6a 100644 --- a/src/test/ui/recursive-requirements.stderr +++ b/src/test/ui/recursive-requirements.stderr @@ -12,4 +12,4 @@ LL | let _: AssertSync = unimplemented!(); //~ ERROR E0275 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0275" +For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/region-borrow-params-issue-29793-small.stderr b/src/test/ui/region-borrow-params-issue-29793-small.stderr index a342f51e2570..cfe38fe20040 100644 --- a/src/test/ui/region-borrow-params-issue-29793-small.stderr +++ b/src/test/ui/region-borrow-params-issue-29793-small.stderr @@ -244,5 +244,5 @@ LL | let f = move |t: bool| if t { x } else { y }; // (separate erro error: aborting due to 20 previous errors -You've got a few errors: E0373, E0597 -If you want more information on an error, try using "rustc --explain E0373" +Some errors occurred: E0373, E0597. +For more information about an error, try `rustc --explain E0373`. diff --git a/src/test/ui/regions-fn-subtyping-return-static.stderr b/src/test/ui/regions-fn-subtyping-return-static.stderr index 6a7cd6f0236f..bd10dc8a808d 100644 --- a/src/test/ui/regions-fn-subtyping-return-static.stderr +++ b/src/test/ui/regions-fn-subtyping-return-static.stderr @@ -9,4 +9,4 @@ LL | want_F(bar); //~ ERROR E0308 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions-nested-fns-2.stderr b/src/test/ui/regions-nested-fns-2.stderr index 16bec5ee218a..c0aa6f9d5420 100644 --- a/src/test/ui/regions-nested-fns-2.stderr +++ b/src/test/ui/regions-nested-fns-2.stderr @@ -13,4 +13,4 @@ LL | move |z| { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0373" +For more information about this error, try `rustc --explain E0373`. diff --git a/src/test/ui/resolve-conflict-item-vs-import.stderr b/src/test/ui/resolve-conflict-item-vs-import.stderr index 73e3e9611375..5ef4bdf4aadd 100644 --- a/src/test/ui/resolve-conflict-item-vs-import.stderr +++ b/src/test/ui/resolve-conflict-item-vs-import.stderr @@ -15,4 +15,4 @@ LL | use std::mem::transmute as other_transmute; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0255" +For more information about this error, try `rustc --explain E0255`. diff --git a/src/test/ui/resolve-inconsistent-names.stderr b/src/test/ui/resolve-inconsistent-names.stderr index c136b79de003..17caac210d45 100644 --- a/src/test/ui/resolve-inconsistent-names.stderr +++ b/src/test/ui/resolve-inconsistent-names.stderr @@ -16,4 +16,4 @@ LL | a | b => {} //~ ERROR variable `a` is not bound in all patterns error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0408" +For more information about this error, try `rustc --explain E0408`. diff --git a/src/test/ui/resolve/enums-are-namespaced-xc.stderr b/src/test/ui/resolve/enums-are-namespaced-xc.stderr index df65f5dddedd..4b1750a54dc9 100644 --- a/src/test/ui/resolve/enums-are-namespaced-xc.stderr +++ b/src/test/ui/resolve/enums-are-namespaced-xc.stderr @@ -30,5 +30,5 @@ LL | use namespaced_enums::Foo::C; error: aborting due to 3 previous errors -You've got a few errors: E0422, E0425 -If you want more information on an error, try using "rustc --explain E0422" +Some errors occurred: E0422, E0425. +For more information about an error, try `rustc --explain E0422`. diff --git a/src/test/ui/resolve/issue-14254.stderr b/src/test/ui/resolve/issue-14254.stderr index 226fe36dba3e..325e88508452 100644 --- a/src/test/ui/resolve/issue-14254.stderr +++ b/src/test/ui/resolve/issue-14254.stderr @@ -146,5 +146,5 @@ error[E0601]: main function not found error: aborting due to 25 previous errors -You've got a few errors: E0425, E0601 -If you want more information on an error, try using "rustc --explain E0425" +Some errors occurred: E0425, E0601. +For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/resolve/issue-16058.stderr b/src/test/ui/resolve/issue-16058.stderr index 36c62408de78..0ea6da3b27d0 100644 --- a/src/test/ui/resolve/issue-16058.stderr +++ b/src/test/ui/resolve/issue-16058.stderr @@ -14,4 +14,4 @@ LL | use std::thread::Result; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0574" +For more information about this error, try `rustc --explain E0574`. diff --git a/src/test/ui/resolve/issue-17518.stderr b/src/test/ui/resolve/issue-17518.stderr index c5d8f457ec74..177b38aae7bb 100644 --- a/src/test/ui/resolve/issue-17518.stderr +++ b/src/test/ui/resolve/issue-17518.stderr @@ -10,4 +10,4 @@ LL | use SomeEnum::E; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0422" +For more information about this error, try `rustc --explain E0422`. diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr index 4ac907b23ec3..8de552ea0898 100644 --- a/src/test/ui/resolve/issue-18252.stderr +++ b/src/test/ui/resolve/issue-18252.stderr @@ -6,4 +6,4 @@ LL | let f = Foo::Variant(42); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0423" +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr index 508457558665..0dbd4c85a376 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -12,4 +12,4 @@ LL | let homura = issue_19452_aux::Homura::Madoka; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0423" +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index 8056a47b464c..a9d2aeee2d15 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -47,5 +47,3 @@ LL | use std::ops::Div; error: cannot continue compilation due to previous error -You've got a few errors: E0405, E0412 -If you want more information on an error, try using "rustc --explain E0405" diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index 398c85920fd2..50781d437927 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -12,5 +12,3 @@ error[E0601]: main function not found error: cannot continue compilation due to previous error -You've got a few errors: E0405, E0601 -If you want more information on an error, try using "rustc --explain E0405" diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr index 75601e932dfa..7725f74cb49f 100644 --- a/src/test/ui/resolve/issue-21221-3.stderr +++ b/src/test/ui/resolve/issue-21221-3.stderr @@ -10,4 +10,3 @@ LL | use issue_21221_3::outer::OuterTrait; error: cannot continue compilation due to previous error -If you want more information on this error, try using "rustc --explain E0405" diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr index 10dcf0aa3b9e..b0a4d5ba4d89 100644 --- a/src/test/ui/resolve/issue-21221-4.stderr +++ b/src/test/ui/resolve/issue-21221-4.stderr @@ -10,4 +10,3 @@ LL | use issue_21221_4::T; error: cannot continue compilation due to previous error -If you want more information on this error, try using "rustc --explain E0405" diff --git a/src/test/ui/resolve/issue-23305.stderr b/src/test/ui/resolve/issue-23305.stderr index a9d43aeb7426..63b7ab78b13e 100644 --- a/src/test/ui/resolve/issue-23305.stderr +++ b/src/test/ui/resolve/issue-23305.stderr @@ -13,4 +13,4 @@ LL | impl ToNbt {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0391" +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr index 6cf5fdeeb0db..3e6c38bce51c 100644 --- a/src/test/ui/resolve/issue-2356.stderr +++ b/src/test/ui/resolve/issue-2356.stderr @@ -108,5 +108,5 @@ LL | self += 1; error: aborting due to 17 previous errors -You've got a few errors: E0424, E0425 -If you want more information on an error, try using "rustc --explain E0424" +Some errors occurred: E0424, E0425. +For more information about an error, try `rustc --explain E0424`. diff --git a/src/test/ui/resolve/issue-24968.stderr b/src/test/ui/resolve/issue-24968.stderr index 8aa84f2ed877..9a1d5ea170e6 100644 --- a/src/test/ui/resolve/issue-24968.stderr +++ b/src/test/ui/resolve/issue-24968.stderr @@ -6,4 +6,4 @@ LL | fn foo(_: Self) { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0411" +For more information about this error, try `rustc --explain E0411`. diff --git a/src/test/ui/resolve/issue-33876.stderr b/src/test/ui/resolve/issue-33876.stderr index 2742d4af7121..631a9f6f7242 100644 --- a/src/test/ui/resolve/issue-33876.stderr +++ b/src/test/ui/resolve/issue-33876.stderr @@ -6,4 +6,4 @@ LL | let any: &Any = &Bar; //~ ERROR expected value, found trait `Bar` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0423" +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr index 7d01cd739e0e..567fd31b09ca 100644 --- a/src/test/ui/resolve/issue-3907-2.stderr +++ b/src/test/ui/resolve/issue-3907-2.stderr @@ -8,4 +8,4 @@ LL | fn bar(_x: Foo) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0038" +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 80ee2e028ebb..2b8b2b20685f 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -10,4 +10,3 @@ LL | use issue_3907::Foo; error: cannot continue compilation due to previous error -If you want more information on this error, try using "rustc --explain E0404" diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr index 4d1e3ae9b107..089fb9fa6609 100644 --- a/src/test/ui/resolve/issue-39226.stderr +++ b/src/test/ui/resolve/issue-39226.stderr @@ -9,4 +9,4 @@ LL | handle: Handle error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0423" +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/issue-5035-2.stderr b/src/test/ui/resolve/issue-5035-2.stderr index fedb8b607fcd..92309274e844 100644 --- a/src/test/ui/resolve/issue-5035-2.stderr +++ b/src/test/ui/resolve/issue-5035-2.stderr @@ -9,4 +9,4 @@ LL | fn foo(_x: K) {} //~ ERROR: `I + 'static: std::marker::Sized` is not satisf error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr index 9b3d69d90c0f..6597f05889af 100644 --- a/src/test/ui/resolve/issue-5035.stderr +++ b/src/test/ui/resolve/issue-5035.stderr @@ -15,5 +15,3 @@ LL | impl K for isize {} //~ ERROR expected trait, found type alias `K` error: cannot continue compilation due to previous error -You've got a few errors: E0404, E0432 -If you want more information on an error, try using "rustc --explain E0404" diff --git a/src/test/ui/resolve/issue-6702.stderr b/src/test/ui/resolve/issue-6702.stderr index 708ff2e5001a..6f2312afe4f7 100644 --- a/src/test/ui/resolve/issue-6702.stderr +++ b/src/test/ui/resolve/issue-6702.stderr @@ -6,4 +6,4 @@ LL | let _m = Monster(); //~ ERROR expected function, found struct `Monster` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0423" +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index 1a00395f2de8..bb3caf342bfc 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -48,5 +48,5 @@ LL | let b: m::first = m::second; // Misspelled item in module. error: aborting due to 8 previous errors -You've got a few errors: E0412, E0425 -If you want more information on an error, try using "rustc --explain E0412" +Some errors occurred: E0412, E0425. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/resolve/name-clash-nullary.stderr b/src/test/ui/resolve/name-clash-nullary.stderr index aefdc9b9fe1c..862ad270502f 100644 --- a/src/test/ui/resolve/name-clash-nullary.stderr +++ b/src/test/ui/resolve/name-clash-nullary.stderr @@ -9,4 +9,4 @@ LL | let None: isize = 42; //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 7af2f5931dc8..d8ab21ddb5f3 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -223,5 +223,5 @@ LL | let _: E = E::Unit; error: aborting due to 23 previous errors -You've got a few errors: E0308, E0412, E0423, E0603, E0618 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0412, E0423, E0603, E0618. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index ddd8f238e872..6ea5241fff00 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -75,5 +75,5 @@ LL | xcrate::m::n::Z; error: aborting due to 10 previous errors -You've got a few errors: E0423, E0603 -If you want more information on an error, try using "rustc --explain E0423" +Some errors occurred: E0423, E0603. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/resolve-assoc-suggestions.stderr b/src/test/ui/resolve/resolve-assoc-suggestions.stderr index e03a9052e4b6..916fa9793dc1 100644 --- a/src/test/ui/resolve/resolve-assoc-suggestions.stderr +++ b/src/test/ui/resolve/resolve-assoc-suggestions.stderr @@ -54,5 +54,5 @@ LL | method; error: aborting due to 9 previous errors -You've got a few errors: E0412, E0425, E0531 -If you want more information on an error, try using "rustc --explain E0412" +Some errors occurred: E0412, E0425, E0531. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/resolve/resolve-hint-macro.stderr b/src/test/ui/resolve/resolve-hint-macro.stderr index 82279b7b2df9..9de6fd85de25 100644 --- a/src/test/ui/resolve/resolve-hint-macro.stderr +++ b/src/test/ui/resolve/resolve-hint-macro.stderr @@ -6,4 +6,4 @@ LL | assert(true); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0423" +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/resolve-speculative-adjustment.stderr b/src/test/ui/resolve/resolve-speculative-adjustment.stderr index 0e3eb95f9c4b..217bfb425664 100644 --- a/src/test/ui/resolve/resolve-speculative-adjustment.stderr +++ b/src/test/ui/resolve/resolve-speculative-adjustment.stderr @@ -24,4 +24,4 @@ LL | method(); error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index c6058c7af030..263319f2ffa9 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -76,5 +76,5 @@ error[E0601]: main function not found error: aborting due to 10 previous errors -You've got a few errors: E0423, E0601 -If you want more information on an error, try using "rustc --explain E0423" +Some errors occurred: E0423, E0601. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/token-error-correct-2.stderr b/src/test/ui/resolve/token-error-correct-2.stderr index 41d77bf16b97..7abc1ba47810 100644 --- a/src/test/ui/resolve/token-error-correct-2.stderr +++ b/src/test/ui/resolve/token-error-correct-2.stderr @@ -18,4 +18,4 @@ LL | if foo { error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index 98989f99dd4f..284acd20ba5e 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -44,5 +44,5 @@ LL | fs::create_dir_all(path.as_ref()).map(|()| true) //~ ERROR: mis error: aborting due to 5 previous errors -You've got a few errors: E0308, E0425 -If you want more information on an error, try using "rustc --explain E0308" +Some errors occurred: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/resolve/tuple-struct-alias.stderr b/src/test/ui/resolve/tuple-struct-alias.stderr index 50d997e01daf..cdac6277bcfa 100644 --- a/src/test/ui/resolve/tuple-struct-alias.stderr +++ b/src/test/ui/resolve/tuple-struct-alias.stderr @@ -32,5 +32,5 @@ LL | A(..) => {} //~ ERROR expected tuple struct/variant error: aborting due to 4 previous errors -You've got a few errors: E0423, E0532 -If you want more information on an error, try using "rustc --explain E0423" +Some errors occurred: E0423, E0532. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index c225563b7549..6e7bd28d16fc 100644 --- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -12,5 +12,3 @@ LL | fn g isize>(x: F) {} error: cannot continue compilation due to previous error -You've got a few errors: E0404, E0405 -If you want more information on an error, try using "rustc --explain E0404" diff --git a/src/test/ui/resolve/unresolved_static_type_field.stderr b/src/test/ui/resolve/unresolved_static_type_field.stderr index 7012419d94cd..262a4983b81a 100644 --- a/src/test/ui/resolve/unresolved_static_type_field.stderr +++ b/src/test/ui/resolve/unresolved_static_type_field.stderr @@ -9,4 +9,4 @@ LL | f(cx); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/resolve/use_suggestion_placement.stderr b/src/test/ui/resolve/use_suggestion_placement.stderr index da2ea67ad08f..caae70900dc0 100644 --- a/src/test/ui/resolve/use_suggestion_placement.stderr +++ b/src/test/ui/resolve/use_suggestion_placement.stderr @@ -32,5 +32,5 @@ LL | use std::collections::hash_map::HashMap; error: aborting due to 3 previous errors -You've got a few errors: E0412, E0425 -If you want more information on an error, try using "rustc --explain E0412" +Some errors occurred: E0412, E0425. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.stderr b/src/test/ui/rfc-2005-default-binding-mode/const.stderr index b91e64b42bf6..302b3a8dbc32 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/const.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/const.stderr @@ -9,4 +9,4 @@ LL | FOO => {}, //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr index 59c857110a9a..18cd0774667c 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr @@ -24,4 +24,4 @@ LL | *x += 1; //~ ERROR cannot assign to immutable error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0594" +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr index 72e5c1fce1e6..392efecb9cd1 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr @@ -24,4 +24,4 @@ LL | *n += 1; //~ ERROR cannot assign to immutable error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0594" +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.stderr b/src/test/ui/rfc-2005-default-binding-mode/for.stderr index cdf6a1667aa4..4094c185063e 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/for.stderr @@ -8,4 +8,4 @@ LL | for (n, mut m) in &tups { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0009" +For more information about this error, try `rustc --explain E0009`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr index e304ae14065a..154fa79fa3f3 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr @@ -6,4 +6,4 @@ LL | Some((x, 3)) | &Some((ref x, 5)) => x, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0409" +For more information about this error, try `rustc --explain E0409`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr index 1d8f544dbadc..dde1f2d352c7 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr @@ -18,4 +18,4 @@ LL | b"abc" => true, //~ ERROR mismatched types error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr index b92f9662613b..e3a613f92611 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr @@ -6,4 +6,4 @@ LL | u32::XXX => { } //~ ERROR no associated item named error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr index f10d0f83f0c2..c0127e5990e9 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr @@ -6,4 +6,4 @@ LL | match sl { //~ ERROR non-exhaustive patterns error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0004" +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr index 1d713be96d7d..ea58c62fc847 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr @@ -8,4 +8,4 @@ LL | if let Some(y) = &Some(22) { //~ ERROR non-reference pattern error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr index 67e50346ace0..054530e24bd1 100644 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr @@ -6,4 +6,4 @@ LL | type Quux<'a> = ::Bar<'a, 'static>; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0110" +For more information about this error, try `rustc --explain E0110`. diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr index bc342119e592..64e82c0d1097 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr @@ -30,5 +30,5 @@ LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; error: aborting due to 5 previous errors -You've got a few errors: E0110, E0261 -If you want more information on an error, try using "rustc --explain E0110" +Some errors occurred: E0110, E0261. +For more information about an error, try `rustc --explain E0110`. diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr index 0c126236d0eb..d33eebb42d60 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr @@ -18,4 +18,4 @@ LL | fn iter<'a>(&'a self) -> Self::Iter<'a>; error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0110" +For more information about this error, try `rustc --explain E0110`. diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr index 6df4ceed66df..3e772eee4f49 100644 --- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr @@ -24,4 +24,4 @@ LL | fn new(value: T) -> Self::Pointer { error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0109" +For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr index df03c15aaa74..9ab80151a7ed 100644 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr @@ -18,4 +18,4 @@ LL | fn next<'a>(&'a self) -> Option>; error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0110" +For more information about this error, try `rustc --explain E0110`. diff --git a/src/test/ui/self-impl.stderr b/src/test/ui/self-impl.stderr index e17c2b6e7926..a5a5135faad7 100644 --- a/src/test/ui/self-impl.stderr +++ b/src/test/ui/self-impl.stderr @@ -16,4 +16,4 @@ LL | let _: Self::Baz = true; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0223" +For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/shadowed-lifetime.stderr b/src/test/ui/shadowed-lifetime.stderr index efb9faa0963b..8d7c00bb61e1 100644 --- a/src/test/ui/shadowed-lifetime.stderr +++ b/src/test/ui/shadowed-lifetime.stderr @@ -16,4 +16,4 @@ LL | let x: for<'b> fn(&'b isize) = panic!(); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0496" +For more information about this error, try `rustc --explain E0496`. diff --git a/src/test/ui/shadowed-type-parameter.stderr b/src/test/ui/shadowed-type-parameter.stderr index d13c75b25c36..c40343e31b44 100644 --- a/src/test/ui/shadowed-type-parameter.stderr +++ b/src/test/ui/shadowed-type-parameter.stderr @@ -26,4 +26,4 @@ LL | fn shadow_in_method(&self) {} error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0194" +For more information about this error, try `rustc --explain E0194`. diff --git a/src/test/ui/span/E0046.stderr b/src/test/ui/span/E0046.stderr index 047a9115caf2..035e2e08720c 100644 --- a/src/test/ui/span/E0046.stderr +++ b/src/test/ui/span/E0046.stderr @@ -9,4 +9,4 @@ LL | impl Foo for Bar {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0046" +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/span/E0057.stderr b/src/test/ui/span/E0057.stderr index 0d6cd77de070..fb3e710b8cf9 100644 --- a/src/test/ui/span/E0057.stderr +++ b/src/test/ui/span/E0057.stderr @@ -12,4 +12,4 @@ LL | let c = f(2, 3); //~ ERROR E0057 error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0057" +For more information about this error, try `rustc --explain E0057`. diff --git a/src/test/ui/span/E0072.stderr b/src/test/ui/span/E0072.stderr index 1c03cfe0e9e0..f8bf41fefa8f 100644 --- a/src/test/ui/span/E0072.stderr +++ b/src/test/ui/span/E0072.stderr @@ -11,4 +11,4 @@ LL | tail: Option, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/span/E0204.stderr b/src/test/ui/span/E0204.stderr index aa21c6762e7b..8be1af61d80b 100644 --- a/src/test/ui/span/E0204.stderr +++ b/src/test/ui/span/E0204.stderr @@ -36,4 +36,4 @@ LL | Bar(&'a mut bool), error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0204" +For more information about this error, try `rustc --explain E0204`. diff --git a/src/test/ui/span/E0493.stderr b/src/test/ui/span/E0493.stderr index 74a85c0164e1..85d83de9d80e 100644 --- a/src/test/ui/span/E0493.stderr +++ b/src/test/ui/span/E0493.stderr @@ -6,4 +6,4 @@ LL | const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0493" +For more information about this error, try `rustc --explain E0493`. diff --git a/src/test/ui/span/E0535.stderr b/src/test/ui/span/E0535.stderr index 309696eebc48..2191aebbeb21 100644 --- a/src/test/ui/span/E0535.stderr +++ b/src/test/ui/span/E0535.stderr @@ -6,4 +6,4 @@ LL | #[inline(unknown)] //~ ERROR E0535 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0535" +For more information about this error, try `rustc --explain E0535`. diff --git a/src/test/ui/span/E0536.stderr b/src/test/ui/span/E0536.stderr index ff8f45438747..2b998356c20b 100644 --- a/src/test/ui/span/E0536.stderr +++ b/src/test/ui/span/E0536.stderr @@ -6,4 +6,4 @@ LL | #[cfg(not())] //~ ERROR E0536 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0536" +For more information about this error, try `rustc --explain E0536`. diff --git a/src/test/ui/span/E0537.stderr b/src/test/ui/span/E0537.stderr index 88e74b1cce58..7257c73acb52 100644 --- a/src/test/ui/span/E0537.stderr +++ b/src/test/ui/span/E0537.stderr @@ -6,4 +6,4 @@ LL | #[cfg(unknown())] //~ ERROR E0537 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0537" +For more information about this error, try `rustc --explain E0537`. diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr index 901a1af94bcd..01c0603256c1 100644 --- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr +++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr @@ -84,5 +84,5 @@ LL | *x.y_mut() = 3; //~ ERROR cannot borrow error: aborting due to 10 previous errors -You've got a few errors: E0499, E0596 -If you want more information on an error, try using "rustc --explain E0499" +Some errors occurred: E0499, E0596. +For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr index 948d6d175dec..3a28ef36d059 100644 --- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr +++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr @@ -32,4 +32,4 @@ LL | **x = 3; //~ ERROR cannot borrow error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr index a06b7097ee37..318b77dedcba 100644 --- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -46,5 +46,5 @@ LL | foo(f); error: aborting due to 5 previous errors -You've got a few errors: E0499, E0504, E0507, E0596 -If you want more information on an error, try using "rustc --explain E0499" +Some errors occurred: E0499, E0504, E0507, E0596. +For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr index 8111f80690aa..a18d3c55394d 100644 --- a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr +++ b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr @@ -9,4 +9,4 @@ LL | x.h(); //~ ERROR cannot borrow error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/span/borrowck-fn-in-const-b.stderr b/src/test/ui/span/borrowck-fn-in-const-b.stderr index 1d4af884b232..4b6c62e6ec83 100644 --- a/src/test/ui/span/borrowck-fn-in-const-b.stderr +++ b/src/test/ui/span/borrowck-fn-in-const-b.stderr @@ -8,4 +8,4 @@ LL | x.push(format!("this is broken")); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr index 6de2eecb61b6..dfcd082c0c2c 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr @@ -50,4 +50,4 @@ LL | } error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/borrowck-object-mutability.stderr b/src/test/ui/span/borrowck-object-mutability.stderr index 2f1a6c631412..5bc07949a951 100644 --- a/src/test/ui/span/borrowck-object-mutability.stderr +++ b/src/test/ui/span/borrowck-object-mutability.stderr @@ -18,4 +18,4 @@ LL | x.borrowed_mut(); //~ ERROR cannot borrow error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/span/borrowck-ref-into-rvalue.stderr b/src/test/ui/span/borrowck-ref-into-rvalue.stderr index cf423c278e12..5de3fc4ab0ac 100644 --- a/src/test/ui/span/borrowck-ref-into-rvalue.stderr +++ b/src/test/ui/span/borrowck-ref-into-rvalue.stderr @@ -14,4 +14,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr index 251f33b63fee..5153d8097882 100644 --- a/src/test/ui/span/coerce-suggestions.stderr +++ b/src/test/ui/span/coerce-suggestions.stderr @@ -61,4 +61,4 @@ LL | s = format!("foo"); error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/span/destructor-restrictions.stderr b/src/test/ui/span/destructor-restrictions.stderr index 15ddfb352405..0ca77a91f2d7 100644 --- a/src/test/ui/span/destructor-restrictions.stderr +++ b/src/test/ui/span/destructor-restrictions.stderr @@ -10,4 +10,4 @@ LL | }; //~^ ERROR `*a` does not live long enough error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/dropck-object-cycle.stderr b/src/test/ui/span/dropck-object-cycle.stderr index 2a426ca3a294..7b3855917c9d 100644 --- a/src/test/ui/span/dropck-object-cycle.stderr +++ b/src/test/ui/span/dropck-object-cycle.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/dropck_arr_cycle_checked.stderr b/src/test/ui/span/dropck_arr_cycle_checked.stderr index 5e6512c06bf4..44803b281541 100644 --- a/src/test/ui/span/dropck_arr_cycle_checked.stderr +++ b/src/test/ui/span/dropck_arr_cycle_checked.stderr @@ -66,4 +66,4 @@ LL | } error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/dropck_direct_cycle_with_drop.stderr b/src/test/ui/span/dropck_direct_cycle_with_drop.stderr index cf507df4e819..d20421c327fc 100644 --- a/src/test/ui/span/dropck_direct_cycle_with_drop.stderr +++ b/src/test/ui/span/dropck_direct_cycle_with_drop.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/dropck_misc_variants.stderr b/src/test/ui/span/dropck_misc_variants.stderr index 42469018e94d..af56448d4061 100644 --- a/src/test/ui/span/dropck_misc_variants.stderr +++ b/src/test/ui/span/dropck_misc_variants.stderr @@ -21,4 +21,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/dropck_vec_cycle_checked.stderr b/src/test/ui/span/dropck_vec_cycle_checked.stderr index f4ab3293543c..63b0ab52d395 100644 --- a/src/test/ui/span/dropck_vec_cycle_checked.stderr +++ b/src/test/ui/span/dropck_vec_cycle_checked.stderr @@ -66,4 +66,4 @@ LL | } error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/gated-features-attr-spans.stderr b/src/test/ui/span/gated-features-attr-spans.stderr index 87ad9312fa41..179daf83c3c0 100644 --- a/src/test/ui/span/gated-features-attr-spans.stderr +++ b/src/test/ui/span/gated-features-attr-spans.stderr @@ -24,4 +24,4 @@ LL | #[must_use] //~ WARN is experimental error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr index ec5cfebedf9d..4f1ac3b94594 100644 --- a/src/test/ui/span/impl-wrong-item-for-trait.stderr +++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr @@ -68,5 +68,5 @@ LL | impl Debug for FooTypeForMethod { error: aborting due to 8 previous errors -You've got a few errors: E0046, E0323, E0324, E0325, E0437 -If you want more information on an error, try using "rustc --explain E0046" +Some errors occurred: E0046, E0323, E0324, E0325, E0437. +For more information about an error, try `rustc --explain E0046`. diff --git a/src/test/ui/span/issue-11925.stderr b/src/test/ui/span/issue-11925.stderr index 1185dc6a0cc8..bd66a5bc3929 100644 --- a/src/test/ui/span/issue-11925.stderr +++ b/src/test/ui/span/issue-11925.stderr @@ -12,4 +12,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-15480.stderr b/src/test/ui/span/issue-15480.stderr index c3298a4a0b5c..1d239c712fe9 100644 --- a/src/test/ui/span/issue-15480.stderr +++ b/src/test/ui/span/issue-15480.stderr @@ -13,4 +13,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr index ec5c7e637f4a..6932134f4cdc 100644 --- a/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr +++ b/src/test/ui/span/issue-23338-locals-die-before-temps-of-body.stderr @@ -20,4 +20,4 @@ LL | }; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr index d80e3352ee4a..83a7671b8f93 100644 --- a/src/test/ui/span/issue-23729.stderr +++ b/src/test/ui/span/issue-23729.stderr @@ -8,4 +8,4 @@ LL | impl Iterator for Recurrence { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0046" +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr index a94debd575c5..c8b55290aa09 100644 --- a/src/test/ui/span/issue-23827.stderr +++ b/src/test/ui/span/issue-23827.stderr @@ -8,4 +8,4 @@ LL | impl FnOnce<(C,)> for Prototype { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0046" +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/span/issue-24356.stderr b/src/test/ui/span/issue-24356.stderr index 17a25821fd41..7c599138ef3c 100644 --- a/src/test/ui/span/issue-24356.stderr +++ b/src/test/ui/span/issue-24356.stderr @@ -8,4 +8,4 @@ LL | impl Deref for Thing { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0046" +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr index 284c07edf034..13a79035003c 100644 --- a/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr +++ b/src/test/ui/span/issue-24805-dropck-child-has-items-via-parent.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr b/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr index e0e10ff672a4..a2e25492c194 100644 --- a/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr +++ b/src/test/ui/span/issue-24805-dropck-trait-has-items.stderr @@ -30,4 +30,4 @@ LL | } error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-24895-copy-clone-dropck.stderr b/src/test/ui/span/issue-24895-copy-clone-dropck.stderr index 31ad51400a26..1f6c96d4a0c5 100644 --- a/src/test/ui/span/issue-24895-copy-clone-dropck.stderr +++ b/src/test/ui/span/issue-24895-copy-clone-dropck.stderr @@ -10,4 +10,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-25199.stderr b/src/test/ui/span/issue-25199.stderr index fe2df9ce7113..bee83b532baa 100644 --- a/src/test/ui/span/issue-25199.stderr +++ b/src/test/ui/span/issue-25199.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-26656.stderr b/src/test/ui/span/issue-26656.stderr index e15af193bec5..98f0c90ed781 100644 --- a/src/test/ui/span/issue-26656.stderr +++ b/src/test/ui/span/issue-26656.stderr @@ -10,4 +10,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr index b171fde0f0f7..d0611bd580fe 100644 --- a/src/test/ui/span/issue-27522.stderr +++ b/src/test/ui/span/issue-27522.stderr @@ -9,4 +9,4 @@ LL | fn handler(self: &SomeType); //~ ERROR invalid `self` type error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0307" +For more information about this error, try `rustc --explain E0307`. diff --git a/src/test/ui/span/issue-29106.stderr b/src/test/ui/span/issue-29106.stderr index 3d7bd2232e43..23e53c9852d5 100644 --- a/src/test/ui/span/issue-29106.stderr +++ b/src/test/ui/span/issue-29106.stderr @@ -20,4 +20,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr index 026d2ba41c7b..15d56abca508 100644 --- a/src/test/ui/span/issue-29595.stderr +++ b/src/test/ui/span/issue-29595.stderr @@ -12,4 +12,4 @@ LL | const C: Self; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/span/issue-33884.stderr b/src/test/ui/span/issue-33884.stderr index fc79b79877a4..c47d28b45625 100644 --- a/src/test/ui/span/issue-33884.stderr +++ b/src/test/ui/span/issue-33884.stderr @@ -10,4 +10,4 @@ LL | stream.write_fmt(format!("message received")) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr index bf2de0f11250..bfa81a398a4a 100644 --- a/src/test/ui/span/issue-34264.stderr +++ b/src/test/ui/span/issue-34264.stderr @@ -45,5 +45,5 @@ LL | bar(1, 2, 3); //~ ERROR this function takes error: aborting due to 6 previous errors -You've got a few errors: E0061, E0308 -If you want more information on an error, try using "rustc --explain E0061" +Some errors occurred: E0061, E0308. +For more information about an error, try `rustc --explain E0061`. diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 596f2d76da6b..d3267d0cc157 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -12,5 +12,3 @@ error[E0601]: main function not found error: cannot continue compilation due to previous error -You've got a few errors: E0404, E0601 -If you want more information on an error, try using "rustc --explain E0404" diff --git a/src/test/ui/span/issue-36530.stderr b/src/test/ui/span/issue-36530.stderr index 69dd330838df..cbec4f6b0a63 100644 --- a/src/test/ui/span/issue-36530.stderr +++ b/src/test/ui/span/issue-36530.stderr @@ -16,4 +16,4 @@ LL | #![foo] //~ ERROR is currently unknown to the compiler error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/span/issue-36537.stderr b/src/test/ui/span/issue-36537.stderr index 058e83ba4fdf..73a0cf63c949 100644 --- a/src/test/ui/span/issue-36537.stderr +++ b/src/test/ui/span/issue-36537.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-37767.stderr b/src/test/ui/span/issue-37767.stderr index ad72a0649710..5477146a5518 100644 --- a/src/test/ui/span/issue-37767.stderr +++ b/src/test/ui/span/issue-37767.stderr @@ -57,4 +57,4 @@ LL | fn foo(self) {} error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0034" +For more information about this error, try `rustc --explain E0034`. diff --git a/src/test/ui/span/issue-39018.stderr b/src/test/ui/span/issue-39018.stderr index d300357fa0b6..ee6334e8164c 100644 --- a/src/test/ui/span/issue-39018.stderr +++ b/src/test/ui/span/issue-39018.stderr @@ -32,4 +32,4 @@ LL | let x = "Hello " + &"World!".to_owned(); error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0369" +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/span/issue-39698.stderr b/src/test/ui/span/issue-39698.stderr index 4222d40a12bc..e8dab8dc4650 100644 --- a/src/test/ui/span/issue-39698.stderr +++ b/src/test/ui/span/issue-39698.stderr @@ -40,4 +40,4 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0408" +For more information about this error, try `rustc --explain E0408`. diff --git a/src/test/ui/span/issue-40157.stderr b/src/test/ui/span/issue-40157.stderr index cc029ae84b6b..8c6d3339e983 100644 --- a/src/test/ui/span/issue-40157.stderr +++ b/src/test/ui/span/issue-40157.stderr @@ -12,4 +12,4 @@ LL | {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr index 508608bd202a..23315e3b76a4 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr @@ -15,4 +15,4 @@ LL | | .sum::<_>() error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 37e8200a308c..dc2cd4c2ddc3 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -67,4 +67,4 @@ LL | fn is_str() -> bool { error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/span/issue28498-reject-ex1.stderr b/src/test/ui/span/issue28498-reject-ex1.stderr index adbbd6766154..fb6eeb4de5dd 100644 --- a/src/test/ui/span/issue28498-reject-ex1.stderr +++ b/src/test/ui/span/issue28498-reject-ex1.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue28498-reject-lifetime-param.stderr b/src/test/ui/span/issue28498-reject-lifetime-param.stderr index a701ff6eb3ea..841ea5b25c84 100644 --- a/src/test/ui/span/issue28498-reject-lifetime-param.stderr +++ b/src/test/ui/span/issue28498-reject-lifetime-param.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr index 934863fa4da1..2a5e34290ec9 100644 --- a/src/test/ui/span/issue28498-reject-passed-to-fn.stderr +++ b/src/test/ui/span/issue28498-reject-passed-to-fn.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/issue28498-reject-trait-bound.stderr b/src/test/ui/span/issue28498-reject-trait-bound.stderr index 4630022e9c49..6e46f67a1d51 100644 --- a/src/test/ui/span/issue28498-reject-trait-bound.stderr +++ b/src/test/ui/span/issue28498-reject-trait-bound.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr index a7417b006ad4..be514fdd81ce 100644 --- a/src/test/ui/span/missing-unit-argument.stderr +++ b/src/test/ui/span/missing-unit-argument.stderr @@ -67,4 +67,4 @@ LL | S.generic::<()>(()); //~ ERROR this function takes error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0061" +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/span/move-closure.stderr b/src/test/ui/span/move-closure.stderr index 497224b7b534..1c629ee9841c 100644 --- a/src/test/ui/span/move-closure.stderr +++ b/src/test/ui/span/move-closure.stderr @@ -9,4 +9,4 @@ LL | let x: () = move || (); //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/span/multiline-span-E0072.stderr b/src/test/ui/span/multiline-span-E0072.stderr index 42ec3764fffa..d087a3aaabff 100644 --- a/src/test/ui/span/multiline-span-E0072.stderr +++ b/src/test/ui/span/multiline-span-E0072.stderr @@ -14,4 +14,4 @@ LL | | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr index e3bb8349f8a1..463d5baae64e 100644 --- a/src/test/ui/span/multiline-span-simple.stderr +++ b/src/test/ui/span/multiline-span-simple.stderr @@ -8,4 +8,4 @@ LL | foo(1 as u32 + //~ ERROR cannot add `()` to `u32` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/span/mut-arg-hint.stderr b/src/test/ui/span/mut-arg-hint.stderr index 73a63aabe674..730592b31002 100644 --- a/src/test/ui/span/mut-arg-hint.stderr +++ b/src/test/ui/span/mut-arg-hint.stderr @@ -24,4 +24,4 @@ LL | a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed conte error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0596" +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr index 15694106fe8d..7898b066acd4 100644 --- a/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr +++ b/src/test/ui/span/mut-ptr-cant-outlive-ref.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/non-existing-module-import.stderr b/src/test/ui/span/non-existing-module-import.stderr index ed9ae1f21b4d..5518b42ac652 100644 --- a/src/test/ui/span/non-existing-module-import.stderr +++ b/src/test/ui/span/non-existing-module-import.stderr @@ -6,4 +6,4 @@ LL | use std::bar::{foo1, foo2}; //~ ERROR unresolved import error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0432" +For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/span/pub-struct-field.stderr b/src/test/ui/span/pub-struct-field.stderr index 40819e2e8baa..4d2a48aef00a 100644 --- a/src/test/ui/span/pub-struct-field.stderr +++ b/src/test/ui/span/pub-struct-field.stderr @@ -17,4 +17,4 @@ LL | pub(crate) bar: u8, //~ ERROR is already declared error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0124" +For more information about this error, try `rustc --explain E0124`. diff --git a/src/test/ui/span/range-2.stderr b/src/test/ui/span/range-2.stderr index 6378e55f8038..e2ee86ae1f59 100644 --- a/src/test/ui/span/range-2.stderr +++ b/src/test/ui/span/range-2.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/recursive-type-field.stderr b/src/test/ui/span/recursive-type-field.stderr index 7ac63d3ca6ec..74ccb74ac2b5 100644 --- a/src/test/ui/span/recursive-type-field.stderr +++ b/src/test/ui/span/recursive-type-field.stderr @@ -29,4 +29,4 @@ LL | x: Bar<'a>, error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr index c9e8a6d8f56b..db47a9010e09 100644 --- a/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr +++ b/src/test/ui/span/regionck-unboxed-closure-lifetimes.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr index 785a47182530..2b63d5bd6c75 100644 --- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr +++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/regions-close-over-type-parameter-2.stderr b/src/test/ui/span/regions-close-over-type-parameter-2.stderr index 9e8c4000d064..79c6a0be1790 100644 --- a/src/test/ui/span/regions-close-over-type-parameter-2.stderr +++ b/src/test/ui/span/regions-close-over-type-parameter-2.stderr @@ -11,4 +11,4 @@ LL | }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/regions-escape-loop-via-variable.stderr b/src/test/ui/span/regions-escape-loop-via-variable.stderr index 1bc8e996d013..0ff0d76a5e46 100644 --- a/src/test/ui/span/regions-escape-loop-via-variable.stderr +++ b/src/test/ui/span/regions-escape-loop-via-variable.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/regions-escape-loop-via-vec.stderr b/src/test/ui/span/regions-escape-loop-via-vec.stderr index 2cb8df235b4b..1d4911bd5af7 100644 --- a/src/test/ui/span/regions-escape-loop-via-vec.stderr +++ b/src/test/ui/span/regions-escape-loop-via-vec.stderr @@ -37,5 +37,5 @@ LL | x += 1; //~ ERROR cannot assign error: aborting due to 4 previous errors -You've got a few errors: E0503, E0506, E0597 -If you want more information on an error, try using "rustc --explain E0503" +Some errors occurred: E0503, E0506, E0597. +For more information about an error, try `rustc --explain E0503`. diff --git a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr index 42240509a9ea..87dc0682199b 100644 --- a/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr +++ b/src/test/ui/span/regions-infer-borrow-scope-within-loop.stderr @@ -12,4 +12,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr index 462c01d849b6..0447b578d44c 100644 --- a/src/test/ui/span/send-is-not-static-ensures-scoping.stderr +++ b/src/test/ui/span/send-is-not-static-ensures-scoping.stderr @@ -26,4 +26,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/send-is-not-static-std-sync-2.stderr b/src/test/ui/span/send-is-not-static-std-sync-2.stderr index ed6363a2e330..53f4d685d0c2 100644 --- a/src/test/ui/span/send-is-not-static-std-sync-2.stderr +++ b/src/test/ui/span/send-is-not-static-std-sync-2.stderr @@ -34,4 +34,4 @@ LL | } error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/send-is-not-static-std-sync.stderr b/src/test/ui/span/send-is-not-static-std-sync.stderr index ffaccf010a9d..066715cd5b5f 100644 --- a/src/test/ui/span/send-is-not-static-std-sync.stderr +++ b/src/test/ui/span/send-is-not-static-std-sync.stderr @@ -57,5 +57,5 @@ LL | drop(y); //~ ERROR cannot move out error: aborting due to 6 previous errors -You've got a few errors: E0505, E0597 -If you want more information on an error, try using "rustc --explain E0505" +Some errors occurred: E0505, E0597. +For more information about an error, try `rustc --explain E0505`. diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr index 3cc791a05800..503d1f72c354 100644 --- a/src/test/ui/span/slice-borrow.stderr +++ b/src/test/ui/span/slice-borrow.stderr @@ -13,4 +13,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/suggestion-non-ascii.stderr b/src/test/ui/span/suggestion-non-ascii.stderr index 331d18fad54e..f74d4a5caefc 100644 --- a/src/test/ui/span/suggestion-non-ascii.stderr +++ b/src/test/ui/span/suggestion-non-ascii.stderr @@ -6,4 +6,4 @@ LL | println!("☃{}", tup[0]); //~ ERROR cannot index into a value of type error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0608" +For more information about this error, try `rustc --explain E0608`. diff --git a/src/test/ui/span/type-binding.stderr b/src/test/ui/span/type-binding.stderr index 407897bfcfe6..d8bfdff142b5 100644 --- a/src/test/ui/span/type-binding.stderr +++ b/src/test/ui/span/type-binding.stderr @@ -6,4 +6,4 @@ LL | fn homura>(_: T) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0220" +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/span/typo-suggestion.stderr b/src/test/ui/span/typo-suggestion.stderr index 010565970130..0ac3a94e7128 100644 --- a/src/test/ui/span/typo-suggestion.stderr +++ b/src/test/ui/span/typo-suggestion.stderr @@ -12,4 +12,4 @@ LL | println!("Hello {}", fob); //~ ERROR cannot find value error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0425" +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr b/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr index f9a942906038..b461f74c7599 100644 --- a/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr +++ b/src/test/ui/span/vec-must-not-hide-type-from-dropck.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/vec_refs_data_with_early_death.stderr b/src/test/ui/span/vec_refs_data_with_early_death.stderr index cdf0cd6de5cb..0dd7288ce64a 100644 --- a/src/test/ui/span/vec_refs_data_with_early_death.stderr +++ b/src/test/ui/span/vec_refs_data_with_early_death.stderr @@ -22,4 +22,4 @@ LL | } error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/span/wf-method-late-bound-regions.stderr b/src/test/ui/span/wf-method-late-bound-regions.stderr index 30b1086bbd72..f455707366a5 100644 --- a/src/test/ui/span/wf-method-late-bound-regions.stderr +++ b/src/test/ui/span/wf-method-late-bound-regions.stderr @@ -11,4 +11,4 @@ LL | } error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0597" +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/specialization-feature-gate-default.stderr b/src/test/ui/specialization-feature-gate-default.stderr index 0ce10ec8184d..30548bb24504 100644 --- a/src/test/ui/specialization-feature-gate-default.stderr +++ b/src/test/ui/specialization-feature-gate-default.stderr @@ -8,4 +8,4 @@ LL | default fn foo(&self) {} //~ ERROR specialization is unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/specialization-feature-gate-overlap.stderr b/src/test/ui/specialization-feature-gate-overlap.stderr index 00b495dbacd0..bb2d071c93df 100644 --- a/src/test/ui/specialization-feature-gate-overlap.stderr +++ b/src/test/ui/specialization-feature-gate-overlap.stderr @@ -9,4 +9,4 @@ LL | impl Foo for u8 { //~ ERROR E0119 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0119" +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr index abd82cd78ae1..4fe4e569df95 100644 --- a/src/test/ui/static-lifetime.stderr +++ b/src/test/ui/static-lifetime.stderr @@ -13,4 +13,4 @@ LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lif error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0478" +For more information about this error, try `rustc --explain E0478`. diff --git a/src/test/ui/str-concat-on-double-ref.stderr b/src/test/ui/str-concat-on-double-ref.stderr index 8216455ece4b..d42c859598fd 100644 --- a/src/test/ui/str-concat-on-double-ref.stderr +++ b/src/test/ui/str-concat-on-double-ref.stderr @@ -8,4 +8,4 @@ LL | let c = a + b; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0369" +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/str-lit-type-mismatch.stderr b/src/test/ui/str-lit-type-mismatch.stderr index 52be4e80393e..de18851636df 100644 --- a/src/test/ui/str-lit-type-mismatch.stderr +++ b/src/test/ui/str-lit-type-mismatch.stderr @@ -36,4 +36,4 @@ LL | let z: &str = b"foo"; //~ ERROR mismatched types error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/struct-fields-decl-dupe.stderr b/src/test/ui/struct-fields-decl-dupe.stderr index 272ce6b1607d..b5068b4abda5 100644 --- a/src/test/ui/struct-fields-decl-dupe.stderr +++ b/src/test/ui/struct-fields-decl-dupe.stderr @@ -8,4 +8,4 @@ LL | foo: isize, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0124" +For more information about this error, try `rustc --explain E0124`. diff --git a/src/test/ui/struct-fields-hints-no-dupe.stderr b/src/test/ui/struct-fields-hints-no-dupe.stderr index 7c276098febd..d04d193c6655 100644 --- a/src/test/ui/struct-fields-hints-no-dupe.stderr +++ b/src/test/ui/struct-fields-hints-no-dupe.stderr @@ -6,4 +6,4 @@ LL | bar : 42, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0560" +For more information about this error, try `rustc --explain E0560`. diff --git a/src/test/ui/struct-fields-hints.stderr b/src/test/ui/struct-fields-hints.stderr index 6e4d30086601..6d0ec8bdf92c 100644 --- a/src/test/ui/struct-fields-hints.stderr +++ b/src/test/ui/struct-fields-hints.stderr @@ -6,4 +6,4 @@ LL | bar : 42, error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0560" +For more information about this error, try `rustc --explain E0560`. diff --git a/src/test/ui/struct-fields-too-many.stderr b/src/test/ui/struct-fields-too-many.stderr index 8132cf687a31..01b3fe16fbb6 100644 --- a/src/test/ui/struct-fields-too-many.stderr +++ b/src/test/ui/struct-fields-too-many.stderr @@ -8,4 +8,4 @@ LL | bar: 0 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0560" +For more information about this error, try `rustc --explain E0560`. diff --git a/src/test/ui/struct-path-self-type-mismatch.stderr b/src/test/ui/struct-path-self-type-mismatch.stderr index a038a7234021..cfba3be61306 100644 --- a/src/test/ui/struct-path-self-type-mismatch.stderr +++ b/src/test/ui/struct-path-self-type-mismatch.stderr @@ -30,4 +30,4 @@ LL | | } error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggest-private-fields.stderr b/src/test/ui/suggest-private-fields.stderr index fb3d8a675699..51a96df951ae 100644 --- a/src/test/ui/suggest-private-fields.stderr +++ b/src/test/ui/suggest-private-fields.stderr @@ -26,4 +26,4 @@ LL | bb: 20, error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0560" +For more information about this error, try `rustc --explain E0560`. diff --git a/src/test/ui/suggestions/closure-immutable-outer-variable.stderr b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr index a6fda3d7987f..3353e2c72917 100644 --- a/src/test/ui/suggestions/closure-immutable-outer-variable.stderr +++ b/src/test/ui/suggestions/closure-immutable-outer-variable.stderr @@ -8,4 +8,4 @@ LL | foo(Box::new(move || y = false) as Box<_>); //~ ERROR cannot assign to error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0594" +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr index 69b2ab0eadd5..b1e3105a5f92 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr @@ -11,4 +11,4 @@ LL | o.closure(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr index 29138441a912..bd5efcd9fee7 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr @@ -121,4 +121,4 @@ LL | (*self.container).f3(1); //~ ERROR no method named `f3` found error: aborting due to 11 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr index e405300b136d..95b764b43ede 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr @@ -11,4 +11,4 @@ LL | demo.example(1); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr index a58ea05221cd..b7f13320eec6 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr @@ -24,4 +24,4 @@ LL | s.c_fn_ptr(); //~ ERROR no method named `c_fn_ptr` found error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr index 3e934ca391a2..145df8b156bf 100644 --- a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr +++ b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr @@ -9,4 +9,4 @@ LL | let dog_age = dog.dog_age(); //~ ERROR no method error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/conversion-methods.stderr b/src/test/ui/suggestions/conversion-methods.stderr index b8d1c89ec375..970ccad23169 100644 --- a/src/test/ui/suggestions/conversion-methods.stderr +++ b/src/test/ui/suggestions/conversion-methods.stderr @@ -48,4 +48,4 @@ LL | let _prove_piercing_earnest: Vec = &[1, 2, 3]; //~ ERROR mismatc error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr index 9a9f64b94a76..4e2a321ffac0 100644 --- a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr +++ b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr @@ -8,4 +8,4 @@ LL | .filter(|&(ref a, _)| foo(a)) error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/suggestions/dont-suggest-private-trait-method.stderr b/src/test/ui/suggestions/dont-suggest-private-trait-method.stderr index 2dfedac8be24..81ecc546a6de 100644 --- a/src/test/ui/suggestions/dont-suggest-private-trait-method.stderr +++ b/src/test/ui/suggestions/dont-suggest-private-trait-method.stderr @@ -9,4 +9,4 @@ LL | T::new(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/extern-crate-rename.stderr b/src/test/ui/suggestions/extern-crate-rename.stderr index aefbbc79ba92..2c2723fe4c5c 100644 --- a/src/test/ui/suggestions/extern-crate-rename.stderr +++ b/src/test/ui/suggestions/extern-crate-rename.stderr @@ -13,4 +13,4 @@ LL | extern crate m2 as m1; //~ ERROR is defined multiple times error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0259" +For more information about this error, try `rustc --explain E0259`. diff --git a/src/test/ui/suggestions/fn-closure-mutable-capture.stderr b/src/test/ui/suggestions/fn-closure-mutable-capture.stderr index e46900ba49dc..a58d663dc0ab 100644 --- a/src/test/ui/suggestions/fn-closure-mutable-capture.stderr +++ b/src/test/ui/suggestions/fn-closure-mutable-capture.stderr @@ -13,4 +13,4 @@ LL | bar(move || x = 1); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0594" +For more information about this error, try `rustc --explain E0594`. diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr index f3130d0587c4..b249df3b4ef6 100644 --- a/src/test/ui/suggestions/for-c-in-str.stderr +++ b/src/test/ui/suggestions/for-c-in-str.stderr @@ -9,4 +9,4 @@ LL | for c in "asdf" { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr index c9babb6a6d91..7cf7a1d15a27 100644 --- a/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr +++ b/src/test/ui/suggestions/issue-32354-suggest-import-rename.stderr @@ -14,4 +14,4 @@ LL | use extension2::ConstructorExtension as OtherConstructorExtension; //~ ERRO error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0252" +For more information about this error, try `rustc --explain E0252`. diff --git a/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr b/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr index 387b9cfcf32c..80bbdd11289a 100644 --- a/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr +++ b/src/test/ui/suggestions/issue-43420-no-over-suggest.stderr @@ -9,4 +9,4 @@ LL | foo(&a); //~ ERROR mismatched types error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr index 22c82be100c9..8e2b2d845e9b 100644 --- a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr +++ b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr @@ -12,4 +12,4 @@ LL | extern crate std as other_std; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0259" +For more information about this error, try `rustc --explain E0259`. diff --git a/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr index 4d75ee0284c3..e89e9dce94dc 100644 --- a/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr +++ b/src/test/ui/suggestions/issue-46756-consider-borrowing-cast-or-binexpr.stderr @@ -24,4 +24,4 @@ LL | light_flows_our_war_of_mocking_words(with_tears + 4); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr index ddd38ca5c3c4..92ad22806156 100644 --- a/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr +++ b/src/test/ui/suggestions/method-on-ambiguous-numeric-type.stderr @@ -20,4 +20,4 @@ LL | let y: f32 = 2.0; error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0689" +For more information about this error, try `rustc --explain E0689`. diff --git a/src/test/ui/suggestions/numeric-cast-2.stderr b/src/test/ui/suggestions/numeric-cast-2.stderr index 84f01309bd0a..3d4855837172 100644 --- a/src/test/ui/suggestions/numeric-cast-2.stderr +++ b/src/test/ui/suggestions/numeric-cast-2.stderr @@ -18,4 +18,4 @@ LL | let z: i32 = x + x; error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/numeric-cast.stderr b/src/test/ui/suggestions/numeric-cast.stderr index a19ca7de4b06..4aac65ff4cbd 100644 --- a/src/test/ui/suggestions/numeric-cast.stderr +++ b/src/test/ui/suggestions/numeric-cast.stderr @@ -904,4 +904,4 @@ LL | foo::((-x_i8).into()); error: aborting due to 134 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/return-type.stderr b/src/test/ui/suggestions/return-type.stderr index b09615a2fa69..7d7653eee28f 100644 --- a/src/test/ui/suggestions/return-type.stderr +++ b/src/test/ui/suggestions/return-type.stderr @@ -17,4 +17,4 @@ LL | fn bar() -> S { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/str-array-assignment.stderr b/src/test/ui/suggestions/str-array-assignment.stderr index 352954597b19..76db882742a0 100644 --- a/src/test/ui/suggestions/str-array-assignment.stderr +++ b/src/test/ui/suggestions/str-array-assignment.stderr @@ -44,5 +44,5 @@ LL | let w: &str = s[..2]; error: aborting due to 4 previous errors -You've got a few errors: E0277, E0308 -If you want more information on an error, try using "rustc --explain E0277" +Some errors occurred: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/suggest-labels.stderr b/src/test/ui/suggestions/suggest-labels.stderr index 1943e8c65611..671ff1a56db6 100644 --- a/src/test/ui/suggestions/suggest-labels.stderr +++ b/src/test/ui/suggestions/suggest-labels.stderr @@ -18,4 +18,4 @@ LL | break 'longlable; //~ ERROR use of undeclared label error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0426" +For more information about this error, try `rustc --explain E0426`. diff --git a/src/test/ui/suggestions/suggest-methods.stderr b/src/test/ui/suggestions/suggest-methods.stderr index fbbd6247d566..cb352361f33e 100644 --- a/src/test/ui/suggestions/suggest-methods.stderr +++ b/src/test/ui/suggestions/suggest-methods.stderr @@ -33,4 +33,4 @@ LL | let _ = 63u32.count_o(); //~ ERROR no method named error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0599" +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/try-on-option.stderr b/src/test/ui/suggestions/try-on-option.stderr index da7f07a8b162..aee52808f1e2 100644 --- a/src/test/ui/suggestions/try-on-option.stderr +++ b/src/test/ui/suggestions/try-on-option.stderr @@ -17,4 +17,4 @@ LL | x?; //~ the `?` operator error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr index 2fa97d770af8..7536bbcd2db3 100644 --- a/src/test/ui/suggestions/try-operator-on-main.stderr +++ b/src/test/ui/suggestions/try-operator-on-main.stderr @@ -39,4 +39,4 @@ LL | ()?; //~ ERROR the `?` operator can only error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr b/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr index 80d1569bf1cd..3722d2a0e3ff 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-initializer.stderr @@ -15,4 +15,4 @@ LL | let x: Vec::with_capacity(10, 20); //~ ERROR expected type, found `10` error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0061" +For more information about this error, try `rustc --explain E0061`. diff --git a/src/test/ui/suggestions/type-ascription-with-fn-call.stderr b/src/test/ui/suggestions/type-ascription-with-fn-call.stderr index 4d36449d26ae..78df97139b6a 100644 --- a/src/test/ui/suggestions/type-ascription-with-fn-call.stderr +++ b/src/test/ui/suggestions/type-ascription-with-fn-call.stderr @@ -11,4 +11,4 @@ LL | f(); //~ ERROR expected type, found function error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0573" +For more information about this error, try `rustc --explain E0573`. diff --git a/src/test/ui/svh-change-lit.stderr b/src/test/ui/svh-change-lit.stderr index 588e293b255b..bf018cdf8297 100644 --- a/src/test/ui/svh-change-lit.stderr +++ b/src/test/ui/svh-change-lit.stderr @@ -11,4 +11,4 @@ LL | extern crate b; //~ ERROR: found possibly newer version of crate `a` which error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh-change-significant-cfg.stderr b/src/test/ui/svh-change-significant-cfg.stderr index a57a5e7a5dd2..e8926cda9e9f 100644 --- a/src/test/ui/svh-change-significant-cfg.stderr +++ b/src/test/ui/svh-change-significant-cfg.stderr @@ -11,4 +11,4 @@ LL | extern crate b; //~ ERROR: found possibly newer version of crate `a` which error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh-change-trait-bound.stderr b/src/test/ui/svh-change-trait-bound.stderr index f0e433ea894f..d9824876a95a 100644 --- a/src/test/ui/svh-change-trait-bound.stderr +++ b/src/test/ui/svh-change-trait-bound.stderr @@ -11,4 +11,4 @@ LL | extern crate b; //~ ERROR: found possibly newer version of crate `a` which error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh-change-type-arg.stderr b/src/test/ui/svh-change-type-arg.stderr index bc08c8cf5797..1f942cc19891 100644 --- a/src/test/ui/svh-change-type-arg.stderr +++ b/src/test/ui/svh-change-type-arg.stderr @@ -11,4 +11,4 @@ LL | extern crate b; //~ ERROR: found possibly newer version of crate `a` which error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh-change-type-ret.stderr b/src/test/ui/svh-change-type-ret.stderr index 187ebda21ef7..0d59f31ccb66 100644 --- a/src/test/ui/svh-change-type-ret.stderr +++ b/src/test/ui/svh-change-type-ret.stderr @@ -11,4 +11,4 @@ LL | extern crate b; //~ ERROR: found possibly newer version of crate `a` which error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh-change-type-static.stderr b/src/test/ui/svh-change-type-static.stderr index c0ca2e94cea7..cbfb74f59ed6 100644 --- a/src/test/ui/svh-change-type-static.stderr +++ b/src/test/ui/svh-change-type-static.stderr @@ -11,4 +11,4 @@ LL | extern crate b; //~ ERROR: found possibly newer version of crate `a` which error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh-use-trait.stderr b/src/test/ui/svh-use-trait.stderr index fd57ecf6c3fe..612f52ba9592 100644 --- a/src/test/ui/svh-use-trait.stderr +++ b/src/test/ui/svh-use-trait.stderr @@ -11,4 +11,4 @@ LL | extern crate utb; //~ ERROR: found possibly newer version of crate `uta` wh error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0460" +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/switched-expectations.stderr b/src/test/ui/switched-expectations.stderr index 0020d14f5cb9..9db318735bdc 100644 --- a/src/test/ui/switched-expectations.stderr +++ b/src/test/ui/switched-expectations.stderr @@ -9,4 +9,4 @@ LL | let ref string: String = var; //~ ERROR mismatched types [E0308] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr index 26816ca0ca22..4b672f31d385 100644 --- a/src/test/ui/token/issue-10636-2.stderr +++ b/src/test/ui/token/issue-10636-2.stderr @@ -26,4 +26,4 @@ error[E0601]: main function not found error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/token/issue-15980.stderr b/src/test/ui/token/issue-15980.stderr index 4078797474e5..d52368bf96a7 100644 --- a/src/test/ui/token/issue-15980.stderr +++ b/src/test/ui/token/issue-15980.stderr @@ -24,4 +24,4 @@ LL | let x: io::IoResult<()> = Ok(()); error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0412" +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/token/issue-41155.stderr b/src/test/ui/token/issue-41155.stderr index ece803b75dc5..00155cc28734 100644 --- a/src/test/ui/token/issue-41155.stderr +++ b/src/test/ui/token/issue-41155.stderr @@ -16,5 +16,5 @@ error[E0601]: main function not found error: aborting due to 3 previous errors -You've got a few errors: E0412, E0601 -If you want more information on an error, try using "rustc --explain E0412" +Some errors occurred: E0412, E0601. +For more information about an error, try `rustc --explain E0412`. diff --git a/src/test/ui/trait-alias.stderr b/src/test/ui/trait-alias.stderr index 731ea8b8c4c4..5d290e5c7fba 100644 --- a/src/test/ui/trait-alias.stderr +++ b/src/test/ui/trait-alias.stderr @@ -36,4 +36,4 @@ LL | trait CD = Clone + Default; //~ERROR E0645 error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0645" +For more information about this error, try `rustc --explain E0645`. diff --git a/src/test/ui/trait-duplicate-methods.stderr b/src/test/ui/trait-duplicate-methods.stderr index 2aec3f3377dd..1dfddd937ca2 100644 --- a/src/test/ui/trait-duplicate-methods.stderr +++ b/src/test/ui/trait-duplicate-methods.stderr @@ -10,4 +10,4 @@ LL | fn orange(&self); //~ ERROR the name `orange` is defined multiple times error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0428" +For more information about this error, try `rustc --explain E0428`. diff --git a/src/test/ui/trait-method-private.stderr b/src/test/ui/trait-method-private.stderr index f89da4d4bf20..3a625ae25a46 100644 --- a/src/test/ui/trait-method-private.stderr +++ b/src/test/ui/trait-method-private.stderr @@ -12,4 +12,4 @@ LL | use inner::Bar; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0624" +For more information about this error, try `rustc --explain E0624`. diff --git a/src/test/ui/trait-safety-fn-body.stderr b/src/test/ui/trait-safety-fn-body.stderr index 894d0c8c3f7f..432df4382227 100644 --- a/src/test/ui/trait-safety-fn-body.stderr +++ b/src/test/ui/trait-safety-fn-body.stderr @@ -6,4 +6,4 @@ LL | *self += 1; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0133" +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/trait-suggest-where-clause.stderr b/src/test/ui/trait-suggest-where-clause.stderr index 71fa93d5e0c8..abd9f5a8b73f 100644 --- a/src/test/ui/trait-suggest-where-clause.stderr +++ b/src/test/ui/trait-suggest-where-clause.stderr @@ -65,4 +65,4 @@ LL | mem::size_of::<[&U]>(); error: aborting due to 7 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits-multidispatch-convert-ambig-dest.stderr b/src/test/ui/traits-multidispatch-convert-ambig-dest.stderr index 65f2de8bad53..46c86cd767a0 100644 --- a/src/test/ui/traits-multidispatch-convert-ambig-dest.stderr +++ b/src/test/ui/traits-multidispatch-convert-ambig-dest.stderr @@ -6,4 +6,4 @@ LL | test(22, std::default::Default::default()); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/transmute/main.stderr b/src/test/ui/transmute/main.stderr index d412788af5d8..7f6ee749c4fd 100644 --- a/src/test/ui/transmute/main.stderr +++ b/src/test/ui/transmute/main.stderr @@ -36,4 +36,4 @@ LL | let x: Foo = transmute(10); //~ ERROR transmute called with types of di error: aborting due to 4 previous errors -If you want more information on this error, try using "rustc --explain E0512" +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr b/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr index 00723060307a..1591b06f3ac5 100644 --- a/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr +++ b/src/test/ui/transmute/transmute-from-fn-item-types-error.stderr @@ -88,5 +88,5 @@ LL | mem::transmute::<_, Option>(Some(baz)); error: aborting due to 9 previous errors -You've got a few errors: E0512, E0591 -If you want more information on an error, try using "rustc --explain E0512" +Some errors occurred: E0512, E0591. +For more information about an error, try `rustc --explain E0512`. diff --git a/src/test/ui/transmute/transmute-type-parameters.stderr b/src/test/ui/transmute/transmute-type-parameters.stderr index fd9c132383ce..ab0bd8fe2d81 100644 --- a/src/test/ui/transmute/transmute-type-parameters.stderr +++ b/src/test/ui/transmute/transmute-type-parameters.stderr @@ -54,4 +54,4 @@ LL | let _: i32 = transmute(x); error: aborting due to 6 previous errors -If you want more information on this error, try using "rustc --explain E0512" +For more information about this error, try `rustc --explain E0512`. diff --git a/src/test/ui/type-annotation-needed.stderr b/src/test/ui/type-annotation-needed.stderr index 67c0698a6c29..d48891596df2 100644 --- a/src/test/ui/type-annotation-needed.stderr +++ b/src/test/ui/type-annotation-needed.stderr @@ -12,4 +12,4 @@ LL | fn foo>(x: i32) {} error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0283" +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type-check-defaults.stderr b/src/test/ui/type-check-defaults.stderr index f39b7dcb31f0..a2d6e53df050 100644 --- a/src/test/ui/type-check-defaults.stderr +++ b/src/test/ui/type-check-defaults.stderr @@ -72,4 +72,4 @@ LL | trait ProjectionPred> where T::Item : Add {} error: aborting due to 7 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-check/assignment-in-if.stderr b/src/test/ui/type-check/assignment-in-if.stderr index 32b4315bb83a..7f3ce0d2a5fe 100644 --- a/src/test/ui/type-check/assignment-in-if.stderr +++ b/src/test/ui/type-check/assignment-in-if.stderr @@ -57,4 +57,4 @@ LL | if (if true { x = 4 } else { x = 5 }) { error: aborting due to 5 previous errors -If you want more information on this error, try using "rustc --explain E0308" +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type-check/cannot_infer_local_or_array.stderr index 27679e165370..90191ae67451 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type-check/cannot_infer_local_or_array.stderr @@ -8,4 +8,4 @@ LL | let x = []; //~ ERROR type annotations needed error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type-check/cannot_infer_local_or_vec.stderr index 5c024437b774..e58a5b67c196 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type-check/cannot_infer_local_or_vec.stderr @@ -10,4 +10,4 @@ LL | let x = vec![]; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 3a1b2879593c..d7887216bc91 100644 --- a/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -10,4 +10,4 @@ LL | let (x, ) = (vec![], ); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-check/issue-22897.stderr b/src/test/ui/type-check/issue-22897.stderr index 1e6830601b65..e2374809dd6b 100644 --- a/src/test/ui/type-check/issue-22897.stderr +++ b/src/test/ui/type-check/issue-22897.stderr @@ -6,4 +6,4 @@ LL | []; //~ ERROR type annotations needed error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr index 1eb1f8effbb3..fbb7427ae3e8 100644 --- a/src/test/ui/type-check/issue-40294.stderr +++ b/src/test/ui/type-check/issue-40294.stderr @@ -18,4 +18,4 @@ LL | trait Foo: Sized { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0283" +For more information about this error, try `rustc --explain E0283`. diff --git a/src/test/ui/type-check/issue-41314.stderr b/src/test/ui/type-check/issue-41314.stderr index 95b046bf184a..bcb0f9a99a77 100644 --- a/src/test/ui/type-check/issue-41314.stderr +++ b/src/test/ui/type-check/issue-41314.stderr @@ -14,5 +14,5 @@ LL | X::Y { number } => {} //~ ERROR does not have a field named `number error: aborting due to 2 previous errors -You've got a few errors: E0026, E0027 -If you want more information on an error, try using "rustc --explain E0026" +Some errors occurred: E0026, E0027. +For more information about an error, try `rustc --explain E0026`. diff --git a/src/test/ui/type-check/missing_trait_impl.stderr b/src/test/ui/type-check/missing_trait_impl.stderr index ef02708fe53f..777f16b12ce6 100644 --- a/src/test/ui/type-check/missing_trait_impl.stderr +++ b/src/test/ui/type-check/missing_trait_impl.stderr @@ -8,4 +8,4 @@ LL | let z = x + y; //~ ERROR binary operation `+` cannot be applied to type error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0369" +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/type-check/unknown_type_for_closure.stderr b/src/test/ui/type-check/unknown_type_for_closure.stderr index ce9c0dc4e409..25283f5e76b1 100644 --- a/src/test/ui/type-check/unknown_type_for_closure.stderr +++ b/src/test/ui/type-check/unknown_type_for_closure.stderr @@ -6,4 +6,4 @@ LL | let x = |_| { }; //~ ERROR type annotations needed error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-recursive.stderr b/src/test/ui/type-recursive.stderr index ea90feee3246..c0c2cbc857a8 100644 --- a/src/test/ui/type-recursive.stderr +++ b/src/test/ui/type-recursive.stderr @@ -11,4 +11,4 @@ LL | foolish: t1 error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0072" +For more information about this error, try `rustc --explain E0072`. diff --git a/src/test/ui/typeck-builtin-bound-type-parameters.stderr b/src/test/ui/typeck-builtin-bound-type-parameters.stderr index cf4011f5dbe3..221f05b91509 100644 --- a/src/test/ui/typeck-builtin-bound-type-parameters.stderr +++ b/src/test/ui/typeck-builtin-bound-type-parameters.stderr @@ -36,5 +36,5 @@ LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} error: aborting due to 6 previous errors -You've got a few errors: E0107, E0244 -If you want more information on an error, try using "rustc --explain E0107" +Some errors occurred: E0107, E0244. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/typeck_type_placeholder_item.stderr b/src/test/ui/typeck_type_placeholder_item.stderr index b00fbafcd691..3f814085955f 100644 --- a/src/test/ui/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck_type_placeholder_item.stderr @@ -204,4 +204,4 @@ LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } error: aborting due to 34 previous errors -If you want more information on this error, try using "rustc --explain E0121" +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/typeck_type_placeholder_lifetime_1.stderr b/src/test/ui/typeck_type_placeholder_lifetime_1.stderr index 19b308f33340..fe9566b31815 100644 --- a/src/test/ui/typeck_type_placeholder_lifetime_1.stderr +++ b/src/test/ui/typeck_type_placeholder_lifetime_1.stderr @@ -6,4 +6,4 @@ LL | let c: Foo<_, _> = Foo { r: &5 }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0244" +For more information about this error, try `rustc --explain E0244`. diff --git a/src/test/ui/typeck_type_placeholder_lifetime_2.stderr b/src/test/ui/typeck_type_placeholder_lifetime_2.stderr index 12712e1e88cf..64ec42454666 100644 --- a/src/test/ui/typeck_type_placeholder_lifetime_2.stderr +++ b/src/test/ui/typeck_type_placeholder_lifetime_2.stderr @@ -6,4 +6,4 @@ LL | let c: Foo<_, usize> = Foo { r: &5 }; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0244" +For more information about this error, try `rustc --explain E0244`. diff --git a/src/test/ui/ui-testing-optout.stderr b/src/test/ui/ui-testing-optout.stderr index 1c13da57b0d0..aab3399a6fcc 100644 --- a/src/test/ui/ui-testing-optout.stderr +++ b/src/test/ui/ui-testing-optout.stderr @@ -18,4 +18,4 @@ error[E0412]: cannot find type `F` in this scope error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0412" +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/unboxed-closure-no-cyclic-sig.stderr b/src/test/ui/unboxed-closure-no-cyclic-sig.stderr index 633ae13ca104..0c0c339286ec 100644 --- a/src/test/ui/unboxed-closure-no-cyclic-sig.stderr +++ b/src/test/ui/unboxed-closure-no-cyclic-sig.stderr @@ -10,4 +10,4 @@ LL | g(|_| { }); //~ ERROR closure/generator type that references itself error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0644" +For more information about this error, try `rustc --explain E0644`. diff --git a/src/test/ui/unboxed-closure-sugar-wrong-trait.stderr b/src/test/ui/unboxed-closure-sugar-wrong-trait.stderr index 8ef0828fba58..82ba4e66393d 100644 --- a/src/test/ui/unboxed-closure-sugar-wrong-trait.stderr +++ b/src/test/ui/unboxed-closure-sugar-wrong-trait.stderr @@ -12,5 +12,5 @@ LL | fn f isize>(x: F) {} error: aborting due to 2 previous errors -You've got a few errors: E0220, E0244 -If you want more information on an error, try using "rustc --explain E0220" +Some errors occurred: E0220, E0244. +For more information about an error, try `rustc --explain E0220`. diff --git a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr index 3b78481504ce..0062ea77c0b5 100644 --- a/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr +++ b/src/test/ui/unboxed-closures-infer-fn-once-move-from-projection.stderr @@ -11,4 +11,4 @@ LL | foo(c); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0525" +For more information about this error, try `rustc --explain E0525`. diff --git a/src/test/ui/unconstrained-none.stderr b/src/test/ui/unconstrained-none.stderr index 6fdbc8414b61..34d524abed9e 100644 --- a/src/test/ui/unconstrained-none.stderr +++ b/src/test/ui/unconstrained-none.stderr @@ -6,4 +6,4 @@ LL | None; //~ ERROR type annotations needed [E0282] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/unconstrained-ref.stderr b/src/test/ui/unconstrained-ref.stderr index 7aeec39ae14a..1fddf4531199 100644 --- a/src/test/ui/unconstrained-ref.stderr +++ b/src/test/ui/unconstrained-ref.stderr @@ -6,4 +6,4 @@ LL | S { o: &None }; //~ ERROR type annotations needed [E0282] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/union/union-derive-eq.stderr b/src/test/ui/union/union-derive-eq.stderr index 88b33c3e96e1..02fa0ca6f831 100644 --- a/src/test/ui/union/union-derive-eq.stderr +++ b/src/test/ui/union/union-derive-eq.stderr @@ -8,4 +8,4 @@ LL | a: PartialEqNotEq, //~ ERROR the trait bound `PartialEqNotEq: std::cmp: error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/union/union-fields-2.stderr b/src/test/ui/union/union-fields-2.stderr index d902ad1629cd..3ea4d3426dad 100644 --- a/src/test/ui/union/union-fields-2.stderr +++ b/src/test/ui/union/union-fields-2.stderr @@ -80,5 +80,5 @@ LL | let U { a, .. } = u; //~ ERROR `..` cannot be used in union patterns error: aborting due to 13 previous errors -You've got a few errors: E0026, E0436, E0560 -If you want more information on an error, try using "rustc --explain E0026" +Some errors occurred: E0026, E0436, E0560. +For more information about an error, try `rustc --explain E0026`. diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr index 4f2d00aaa3e2..fb81a7b695d4 100644 --- a/src/test/ui/union/union-sized-field.stderr +++ b/src/test/ui/union/union-sized-field.stderr @@ -30,4 +30,4 @@ LL | Value(T), //~ ERROR the trait bound `T: std::marker::Sized` is not sati error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/union/union-suggest-field.stderr b/src/test/ui/union/union-suggest-field.stderr index f2ff38bd0c7c..631aacb0289f 100644 --- a/src/test/ui/union/union-suggest-field.stderr +++ b/src/test/ui/union/union-suggest-field.stderr @@ -20,5 +20,5 @@ LL | let y = u.calculate; //~ ERROR attempted to take value of method `calcu error: aborting due to 3 previous errors -You've got a few errors: E0560, E0609, E0615 -If you want more information on an error, try using "rustc --explain E0560" +Some errors occurred: E0560, E0609, E0615. +For more information about an error, try `rustc --explain E0560`. diff --git a/src/test/ui/unknown-language-item.stderr b/src/test/ui/unknown-language-item.stderr index b97971c29dc7..95ce5db33ae5 100644 --- a/src/test/ui/unknown-language-item.stderr +++ b/src/test/ui/unknown-language-item.stderr @@ -6,4 +6,4 @@ LL | #[lang = "foo"] error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0522" +For more information about this error, try `rustc --explain E0522`. diff --git a/src/test/ui/unsafe-const-fn.stderr b/src/test/ui/unsafe-const-fn.stderr index 43b8e36baf23..270b90ec3fcb 100644 --- a/src/test/ui/unsafe-const-fn.stderr +++ b/src/test/ui/unsafe-const-fn.stderr @@ -6,4 +6,4 @@ LL | const VAL: u32 = dummy(0xFFFF); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0133" +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsized-enum2.stderr b/src/test/ui/unsized-enum2.stderr index f2bfa6b82141..c05c1cfe4129 100644 --- a/src/test/ui/unsized-enum2.stderr +++ b/src/test/ui/unsized-enum2.stderr @@ -188,4 +188,4 @@ LL | VL{u: isize, x: Path4}, //~ ERROR `PathHelper4 + 'static: std::marker:: error: aborting due to 20 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/use-mod.stderr b/src/test/ui/use-mod.stderr index 0a63f370d97d..dcdba6fce9ad 100644 --- a/src/test/ui/use-mod.stderr +++ b/src/test/ui/use-mod.stderr @@ -30,5 +30,5 @@ LL | self as other_bar error: aborting due to 3 previous errors -You've got a few errors: E0252, E0430, E0431 -If you want more information on an error, try using "rustc --explain E0252" +Some errors occurred: E0252, E0430, E0431. +For more information about an error, try `rustc --explain E0252`. diff --git a/src/test/ui/use-nested-groups-error.stderr b/src/test/ui/use-nested-groups-error.stderr index 64bbc7b588ed..5e0fd503bc27 100644 --- a/src/test/ui/use-nested-groups-error.stderr +++ b/src/test/ui/use-nested-groups-error.stderr @@ -6,4 +6,4 @@ LL | use a::{b1::{C1, C2}, B2}; error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0432" +For more information about this error, try `rustc --explain E0432`. diff --git a/src/test/ui/variadic-ffi-3.stderr b/src/test/ui/variadic-ffi-3.stderr index b9a84a0cd37d..c7355405b2ac 100644 --- a/src/test/ui/variadic-ffi-3.stderr +++ b/src/test/ui/variadic-ffi-3.stderr @@ -72,5 +72,5 @@ LL | foo(1, 2, 1u16); //~ ERROR can't pass `u16` to variadic function error: aborting due to 10 previous errors -You've got a few errors: E0060, E0308, E0617 -If you want more information on an error, try using "rustc --explain E0060" +Some errors occurred: E0060, E0308, E0617. +For more information about an error, try `rustc --explain E0060`. diff --git a/src/test/ui/variance-unused-type-param.stderr b/src/test/ui/variance-unused-type-param.stderr index d606c5ef6ed0..b3ae91a6fa58 100644 --- a/src/test/ui/variance-unused-type-param.stderr +++ b/src/test/ui/variance-unused-type-param.stderr @@ -24,4 +24,4 @@ LL | enum ListCell { error: aborting due to 3 previous errors -If you want more information on this error, try using "rustc --explain E0392" +For more information about this error, try `rustc --explain E0392`. diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index c3849bb82ba4..90acc2f86d74 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -8,4 +8,4 @@ LL | let _foo = Vec::new(); error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0282" +For more information about this error, try `rustc --explain E0282`. From 9b15ddb29e5acb15b074913d1e70b5b26bd89ee6 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sun, 21 Jan 2018 13:33:21 +0800 Subject: [PATCH 175/830] remove defaulting to unit Types will no longer default to `()`, instead always defaulting to `!`. This disables the associated warning and removes the flag from TyTuple --- src/librustc/ich/impls_ty.rs | 3 +- src/librustc/infer/resolve.rs | 6 -- src/librustc/lint/builtin.rs | 8 --- src/librustc/middle/mem_categorization.rs | 2 +- src/librustc/mir/tcx.rs | 7 +-- src/librustc/traits/error_reporting.rs | 10 ++-- src/librustc/traits/fulfill.rs | 6 +- src/librustc/traits/select.rs | 55 ++----------------- src/librustc/traits/util.rs | 2 +- src/librustc/ty/context.rs | 21 ++----- src/librustc/ty/error.rs | 2 +- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/flags.rs | 5 +- src/librustc/ty/inhabitedness/mod.rs | 2 +- src/librustc/ty/item_path.rs | 6 +- src/librustc/ty/layout.rs | 4 +- src/librustc/ty/mod.rs | 2 +- src/librustc/ty/relate.rs | 5 +- src/librustc/ty/structural_impls.rs | 4 +- src/librustc/ty/sty.rs | 17 +----- src/librustc/ty/util.rs | 13 ++--- src/librustc/ty/walk.rs | 2 +- src/librustc/ty/wf.rs | 2 +- src/librustc/util/ppaux.rs | 4 +- src/librustc_driver/test.rs | 10 ++-- src/librustc_lint/lib.rs | 5 -- src/librustc_lint/unused.rs | 2 +- .../borrow_check/error_reporting.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 2 +- .../borrow_check/nll/universal_regions.rs | 2 +- src/librustc_mir/build/expr/as_rvalue.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 4 +- src/librustc_mir/hair/pattern/mod.rs | 4 +- src/librustc_mir/interpret/terminator/mod.rs | 2 +- src/librustc_mir/monomorphize/item.rs | 2 +- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/inline.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 2 +- src/librustc_trans/abi.rs | 2 +- src/librustc_trans/debuginfo/metadata.rs | 8 +-- src/librustc_trans/debuginfo/mod.rs | 4 +- src/librustc_trans/debuginfo/type_names.rs | 2 +- src/librustc_trans/mir/block.rs | 2 +- src/librustc_trans/mir/mod.rs | 2 +- src/librustc_trans/mir/rvalue.rs | 2 +- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/_match.rs | 4 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/closure.rs | 4 +- src/librustc_typeck/check/intrinsic.rs | 8 +-- src/librustc_typeck/check/mod.rs | 19 +++---- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/mod.rs | 8 +-- .../compile-fail/defaulted-unit-warning.rs | 38 ------------- ...ed-types-ICE-when-projecting-out-of-err.rs | 2 +- ...ypes-ICE-when-projecting-out-of-err.stderr | 4 +- 57 files changed, 107 insertions(+), 243 deletions(-) delete mode 100644 src/test/compile-fail/defaulted-unit-warning.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 4eb4f0edafe4..bb3051b546e6 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -886,9 +886,8 @@ for ty::TypeVariants<'gcx> TyGeneratorWitness(types) => { types.hash_stable(hcx, hasher) } - TyTuple(inner_tys, from_diverging_type_var) => { + TyTuple(inner_tys) => { inner_tys.hash_stable(hcx, hasher); - from_diverging_type_var.hash_stable(hcx, hasher); } TyProjection(ref projection_ty) => { projection_ty.hash_stable(hcx, hasher); diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 5e70c0ce368f..77b722c5695f 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -173,12 +173,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx> ty::TyInfer(_) => { bug!("Unexpected type in full type resolver: {:?}", t); } - ty::TyTuple(tys, true) => { - // Un-default defaulted tuples - we are going to a - // different infcx, and the default will just cause - // pollution. - self.tcx().intern_tup(tys, false) - } _ => { t.super_fold_with(self) } diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 8e1f76c50180..1795866e103b 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -151,13 +151,6 @@ declare_lint! { "lints that have been renamed or removed" } -declare_lint! { - pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT, - Deny, - "attempt to resolve a trait on an expression whose type cannot be inferred but which \ - currently defaults to ()" -} - declare_lint! { pub SAFE_EXTERN_STATICS, Deny, @@ -304,7 +297,6 @@ impl LintPass for HardwiredLints { INVALID_TYPE_PARAM_DEFAULT, CONST_ERR, RENAMED_AND_REMOVED_LINTS, - RESOLVE_TRAIT_ON_DEFAULTED_UNIT, SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, PATTERNS_IN_FNS_WITHOUT_BODY, diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 30d63b8443e3..6bf0c5d1ba3e 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1298,7 +1298,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { PatKind::Tuple(ref subpats, ddpos) => { // (p1, ..., pN) let expected_len = match self.pat_ty(&pat)?.sty { - ty::TyTuple(ref tys, _) => tys.len(), + ty::TyTuple(ref tys) => tys.len(), ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty), }; for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) { diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index d779ccd17360..20902d911101 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -155,7 +155,7 @@ impl<'tcx> Rvalue<'tcx> { let lhs_ty = lhs.ty(local_decls, tcx); let rhs_ty = rhs.ty(local_decls, tcx); let ty = op.ty(tcx, lhs_ty, rhs_ty); - tcx.intern_tup(&[ty, tcx.types.bool], false) + tcx.intern_tup(&[ty, tcx.types.bool]) } Rvalue::UnaryOp(UnOp::Not, ref operand) | Rvalue::UnaryOp(UnOp::Neg, ref operand) => { @@ -178,10 +178,7 @@ impl<'tcx> Rvalue<'tcx> { tcx.mk_array(ty, ops.len() as u64) } AggregateKind::Tuple => { - tcx.mk_tup( - ops.iter().map(|op| op.ty(local_decls, tcx)), - false - ) + tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))) } AggregateKind::Adt(def, _, substs, _) => { tcx.type_of(def.did).subst(tcx, substs) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b8455b97fa41..5d994a0e444c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -729,14 +729,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }).map(|sp| self.tcx.sess.codemap().def_span(sp)); // the sp could be an fn def let found = match found_trait_ref.skip_binder().substs.type_at(1).sty { - ty::TyTuple(ref tys, _) => tys.iter() + ty::TyTuple(ref tys) => tys.iter() .map(|_| ArgKind::empty()).collect::>(), _ => vec![ArgKind::empty()], }; let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty { - ty::TyTuple(ref tys, _) => tys.iter() + ty::TyTuple(ref tys) => tys.iter() .map(|t| match t.sty { - ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple( + ty::TypeVariants::TyTuple(ref tys) => ArgKind::Tuple( Some(span), tys.iter() .map(|ty| ("_".to_owned(), format!("{}", ty.sty))) @@ -986,7 +986,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, trait_ref: &ty::TraitRef<'tcx>) -> String { let inputs = trait_ref.substs.type_at(1); - let sig = if let ty::TyTuple(inputs, _) = inputs.sty { + let sig = if let ty::TyTuple(inputs) = inputs.sty { tcx.mk_fn_sig( inputs.iter().map(|&x| x), tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })), @@ -1422,7 +1422,7 @@ impl ArgKind { /// argument. This has no name (`_`) and no source spans.. pub fn from_expected_ty(t: Ty<'_>) -> ArgKind { match t.sty { - ty::TyTuple(ref tys, _) => ArgKind::Tuple( + ty::TyTuple(ref tys) => ArgKind::Tuple( None, tys.iter() .map(|ty| ("_".to_owned(), format!("{}", ty.sty))) diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index bb2c7977f265..150a2ead9e96 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -330,11 +330,7 @@ fn process_predicate<'a, 'gcx, 'tcx>( if data.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. - if - // make defaulted unit go through the slow path for better warnings, - // please remove this when the warnings are removed. - !trait_obligation.predicate.skip_binder().self_ty().is_defaulted_unit() && - selcx.evaluate_obligation_conservatively(&obligation) { + if selcx.evaluate_obligation_conservatively(&obligation) { debug!("selecting trait `{:?}` at depth {} evaluated to holds", data, obligation.recursion_depth); return Ok(Some(vec![])) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index f2f54dcedfd6..4db81cf1dec1 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -53,7 +53,6 @@ use std::mem; use std::rc::Rc; use syntax::abi::Abi; use hir; -use lint; use util::nodemap::{FxHashMap, FxHashSet}; @@ -526,54 +525,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { debug!("select({:?})", obligation); assert!(!obligation.predicate.has_escaping_regions()); - let tcx = self.tcx(); - let stack = self.push_stack(TraitObligationStackList::empty(), obligation); let ret = match self.candidate_from_obligation(&stack)? { None => None, Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?) }; - // Test whether this is a `()` which was produced by defaulting a - // diverging type variable with `!` disabled. If so, we may need - // to raise a warning. - if obligation.predicate.skip_binder().self_ty().is_defaulted_unit() { - let mut raise_warning = true; - // Don't raise a warning if the trait is implemented for ! and only - // permits a trivial implementation for !. This stops us warning - // about (for example) `(): Clone` becoming `!: Clone` because such - // a switch can't cause code to stop compiling or execute - // differently. - let mut never_obligation = obligation.clone(); - let def_id = never_obligation.predicate.skip_binder().trait_ref.def_id; - never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| { - // Swap out () with ! so we can check if the trait is impld for ! - { - let trait_ref = &mut trait_pred.trait_ref; - let unit_substs = trait_ref.substs; - let mut never_substs = Vec::with_capacity(unit_substs.len()); - never_substs.push(tcx.types.never.into()); - never_substs.extend(&unit_substs[1..]); - trait_ref.substs = tcx.intern_substs(&never_substs); - } - trait_pred - }); - if let Ok(Some(..)) = self.select(&never_obligation) { - if !tcx.trait_relevant_for_never(def_id) { - // The trait is also implemented for ! and the resulting - // implementation cannot actually be invoked in any way. - raise_warning = false; - } - } - - if raise_warning { - tcx.lint_node(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT, - obligation.cause.body_id, - obligation.cause.span, - &format!("code relies on type inference rules which are likely \ - to change")); - } - } Ok(ret) } @@ -1929,7 +1886,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } // (.., T) -> (.., U). - (&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => { + (&ty::TyTuple(tys_a), &ty::TyTuple(tys_b)) => { tys_a.len() == tys_b.len() } @@ -2068,7 +2025,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) => Never, - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { Where(ty::Binder(tys.last().into_iter().cloned().collect())) } @@ -2122,7 +2079,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { Where(ty::Binder(vec![element_ty])) } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { // (*) binder moved here Where(ty::Binder(tys.to_vec())) } @@ -2215,7 +2172,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { vec![element_ty] } - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet tys.to_vec() } @@ -3004,7 +2961,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } // (.., T) -> (.., U). - (&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => { + (&ty::TyTuple(tys_a), &ty::TyTuple(tys_b)) => { assert_eq!(tys_a.len(), tys_b.len()); // The last field of the tuple has to exist. @@ -3017,7 +2974,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // Check that the source tuple with the target's // last element is equal to the target. - let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last)), false); + let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last))); let InferOk { obligations, .. } = self.infcx.at(&obligation.cause, obligation.param_env) .eq(target, new_tuple) diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index c562f2cd48dd..8f7a24057472 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -503,7 +503,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::Yes => - self.intern_tup(sig.skip_binder().inputs(), false), + self.intern_tup(sig.skip_binder().inputs()), }; let trait_ref = ty::TraitRef { def_id: fn_trait_def_id, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 9a687028b582..fd3465f59ebf 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2014,7 +2014,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> { let converted_sig = sig.map_bound(|s| { let params_iter = match s.inputs()[0].sty { - ty::TyTuple(params, _) => { + ty::TyTuple(params) => { params.into_iter().cloned() } _ => bug!(), @@ -2134,25 +2134,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.mk_ty(TySlice(ty)) } - pub fn intern_tup(self, ts: &[Ty<'tcx>], defaulted: bool) -> Ty<'tcx> { - self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted)) + pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> { + self.mk_ty(TyTuple(self.intern_type_list(ts))) } - pub fn mk_tup], Ty<'tcx>>>(self, iter: I, - defaulted: bool) -> I::Output { - iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted))) + pub fn mk_tup], Ty<'tcx>>>(self, iter: I) -> I::Output { + iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts)))) } pub fn mk_nil(self) -> Ty<'tcx> { - self.intern_tup(&[], false) - } - - pub fn mk_diverging_default(self) -> Ty<'tcx> { - if self.features().never_type { - self.types.never - } else { - self.intern_tup(&[], true) - } + self.intern_tup(&[]) } pub fn mk_bool(self) -> Ty<'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 8a0253ed2f11..eb3924186472 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -177,7 +177,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> { match self.sty { ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyNever => self.to_string(), - ty::TyTuple(ref tys, _) if tys.is_empty() => self.to_string(), + ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(), ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)), ty::TyForeign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)), diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 93d8a4d979de..6533a7440ac3 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -97,7 +97,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len())) } ty::TyNever => Some(NeverSimplifiedType), - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { Some(TupleSimplifiedType(tys.len())) } ty::TyFnPtr(ref f) => { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index cae64fd4c95c..086fc66c70f9 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -179,10 +179,7 @@ impl FlagComputation { self.add_ty(m.ty); } - &ty::TyTuple(ref ts, is_default) => { - if is_default { - self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX); - } + &ty::TyTuple(ref ts) => { self.add_tys(&ts[..]); } diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs index 3e653cf126a8..325f8575fd0a 100644 --- a/src/librustc/ty/inhabitedness/mod.rs +++ b/src/librustc/ty/inhabitedness/mod.rs @@ -256,7 +256,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { }, TyNever => DefIdForest::full(tcx), - TyTuple(ref tys, _) => { + TyTuple(ref tys) => { DefIdForest::union(tcx, tys.iter().map(|ty| { ty.uninhabited_from(visited, tcx) })) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index fefd11eecf4f..1f23b0a27e33 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -355,9 +355,9 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option { ty::TyRawPtr(mt) | ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty), - ty::TyTuple(ref tys, _) => tys.iter() - .filter_map(|ty| characteristic_def_id_of_type(ty)) - .next(), + ty::TyTuple(ref tys) => tys.iter() + .filter_map(|ty| characteristic_def_id_of_type(ty)) + .next(), ty::TyFnDef(def_id, _) | ty::TyClosure(def_id, _) | diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 04353d2ece19..3a3f10cb87db 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1318,7 +1318,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { StructKind::AlwaysSized)? } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { let kind = if tys.len() == 0 { StructKind::AlwaysSized } else { @@ -2243,7 +2243,7 @@ impl<'a, 'tcx> TyLayout<'tcx> { substs.field_tys(def_id, tcx).nth(i).unwrap() } - ty::TyTuple(tys, _) => tys[i], + ty::TyTuple(tys) => tys[i], // SIMD vector types. ty::TyAdt(def, ..) if def.repr.simd() => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index fc1d26b0e091..09b11a36352e 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2046,7 +2046,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { vec![ty] } - TyTuple(ref tys, _) => { + TyTuple(ref tys) => { match tys.last() { None => vec![], Some(ty) => self.sized_constraint_for_ty(tcx, ty) diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 72e7d16b64dc..36eb3e3f94cf 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -529,11 +529,10 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, Ok(tcx.mk_slice(t)) } - (&ty::TyTuple(as_, a_defaulted), &ty::TyTuple(bs, b_defaulted)) => + (&ty::TyTuple(as_), &ty::TyTuple(bs)) => { if as_.len() == bs.len() { - let defaulted = a_defaulted || b_defaulted; - Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)), defaulted)?) + Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?) } else if !(as_.is_empty() || bs.is_empty()) { Err(TypeError::TupleSize( expected_found(relation, &as_.len(), &bs.len()))) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 0627bcdfb0ec..c9a69d5405c9 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -869,7 +869,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)), ty::TyDynamic(ref trait_ty, ref region) => ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)), - ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted), + ty::TyTuple(ts) => ty::TyTuple(ts.fold_with(folder)), ty::TyFnDef(def_id, substs) => { ty::TyFnDef(def_id, substs.fold_with(folder)) } @@ -908,7 +908,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { ty::TyAdt(_, substs) => substs.visit_with(visitor), ty::TyDynamic(ref trait_ty, ref reg) => trait_ty.visit_with(visitor) || reg.visit_with(visitor), - ty::TyTuple(ts, _) => ts.visit_with(visitor), + ty::TyTuple(ts) => ts.visit_with(visitor), ty::TyFnDef(_, substs) => substs.visit_with(visitor), ty::TyFnPtr(ref f) => f.visit_with(visitor), ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor), diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 109422564c84..ae053d7f4f58 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -148,11 +148,7 @@ pub enum TypeVariants<'tcx> { TyNever, /// A tuple type. For example, `(i32, bool)`. - /// The bool indicates whether this is a unit tuple and was created by - /// defaulting a diverging type variable with feature(never_type) disabled. - /// It's only purpose is for raising future-compatibility warnings for when - /// diverging type variables start defaulting to ! instead of (). - TyTuple(&'tcx Slice>, bool), + TyTuple(&'tcx Slice>), /// The projection of an associated type. For example, /// `>::N`. @@ -1274,7 +1270,7 @@ impl RegionKind { impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_nil(&self) -> bool { match self.sty { - TyTuple(ref tys, _) => tys.is_empty(), + TyTuple(ref tys) => tys.is_empty(), _ => false, } } @@ -1286,15 +1282,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } - /// Test whether this is a `()` which was produced by defaulting a - /// diverging type variable with feature(never_type) disabled. - pub fn is_defaulted_unit(&self) -> bool { - match self.sty { - TyTuple(_, true) => true, - _ => false, - } - } - pub fn is_primitive(&self) -> bool { match self.sty { TyBool | TyChar | TyInt(_) | TyUint(_) | TyFloat(_) => true, diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 753f89d8cd29..91d460a96f78 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -269,7 +269,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Don't use `non_enum_variant`, this may be a univariant enum. adt.variants[0].fields.get(i).map(|f| f.ty(self, substs)) } - (&TyTuple(ref v, _), None) => v.get(i).cloned(), + (&TyTuple(ref v), None) => v.get(i).cloned(), _ => None, } } @@ -307,7 +307,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { if let Some((&last_ty, _)) = tys.split_last() { ty = last_ty; } else { @@ -344,7 +344,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { break; } }, - (&TyTuple(a_tys, _), &TyTuple(b_tys, _)) + (&TyTuple(a_tys), &TyTuple(b_tys)) if a_tys.len() == b_tys.len() => { if let Some(a_last) = a_tys.last() { a = a_last; @@ -709,9 +709,8 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W> TyGeneratorWitness(tys) => { self.hash(tys.skip_binder().len()); } - TyTuple(tys, defaulted) => { + TyTuple(tys) => { self.hash(tys.len()); - self.hash(defaulted); } TyParam(p) => { self.hash(p.idx); @@ -838,7 +837,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> { -> Representability { match ty.sty { - TyTuple(ref ts, _) => { + TyTuple(ref ts) => { // Find non representable fold_repr(ts.iter().map(|ty| { is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty) @@ -1106,7 +1105,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // state transformation pass ty::TyGenerator(..) => true, - ty::TyTuple(ref tys, _) => tys.iter().cloned().any(needs_drop), + ty::TyTuple(ref tys) => tys.iter().cloned().any(needs_drop), // unions don't have destructors regardless of the child types ty::TyAdt(def, _) if def.is_union() => false, diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 722fdfe773a9..46c048e839b4 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -125,7 +125,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { ty::TyGeneratorWitness(ts) => { stack.extend(ts.skip_binder().iter().cloned().rev()); } - ty::TyTuple(ts, _) => { + ty::TyTuple(ts) => { stack.extend(ts.iter().cloned().rev()); } ty::TyFnDef(_, substs) => { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 49ae79ae9c92..f05d56c9d837 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -275,7 +275,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { self.compute_const(len); } - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { if let Some((_last, rest)) = tys.split_last() { for elem in rest { self.require_sized(elem, traits::TupleElem); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index efa53c775ae2..2c3ee1ec285a 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -340,7 +340,7 @@ impl PrintContext { if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { let projection_ty = projections[0].ty; - if let TyTuple(ref args, _) = substs.type_at(1).sty { + if let TyTuple(ref args) = substs.type_at(1).sty { return self.fn_sig(f, args, false, projection_ty); } } @@ -1013,7 +1013,7 @@ define_print! { tm.print(f, cx) } TyNever => write!(f, "!"), - TyTuple(ref tys, _) => { + TyTuple(ref tys) => { write!(f, "(")?; let mut tys = tys.iter(); if let Some(&ty) = tys.next() { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 06610609ebdb..f7cd1c99a79d 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -287,7 +287,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { } pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> { - self.infcx.tcx.intern_tup(&[ty1, ty2], false) + self.infcx.tcx.intern_tup(&[ty1, ty2]) } pub fn t_param(&self, index: u32) -> Ty<'tcx> { @@ -593,8 +593,8 @@ fn walk_ty() { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; let usize_ty = tcx.types.usize; - let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); - let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); + let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]); + let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]); let walked: Vec<_> = tup2_ty.walk().collect(); assert_eq!(walked, [tup2_ty, tup1_ty, int_ty, usize_ty, int_ty, usize_ty, tup1_ty, int_ty, @@ -608,8 +608,8 @@ fn walk_ty_skip_subtree() { let tcx = env.infcx.tcx; let int_ty = tcx.types.isize; let usize_ty = tcx.types.usize; - let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); - let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); + let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]); + let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]); // types we expect to see (in order), plus a boolean saying // whether to skip the subtree. diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 779aa3a9037c..235d733b253a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -234,11 +234,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #39207 ", epoch: None, }, - FutureIncompatibleInfo { - id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT), - reference: "issue #39216 ", - epoch: None, - }, FutureIncompatibleInfo { id: LintId::of(MISSING_FRAGMENT_SPECIFIER), reference: "issue #40107 ", diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 6ab3172c4fef..d777f6f19b0f 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { let t = cx.tables.expr_ty(&expr); let ty_warned = match t.sty { - ty::TyTuple(ref tys, _) if tys.is_empty() => return, + ty::TyTuple(ref tys) if tys.is_empty() => return, ty::TyNever => return, ty::TyAdt(def, _) => { if def.variants.is_empty() { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 84ba13674505..56371d809b26 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -789,7 +789,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } else { format!("{}", def.non_enum_variant().fields[field.index()].name) }, - ty::TyTuple(_, _) => format!("{}", field.index()), + ty::TyTuple(_) => format!("{}", field.index()), ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => { self.describe_field_from_ty(&tnm.ty, field) } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 06e6be5cd56a..022831b5a925 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -542,7 +542,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { }), }; } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { return match tys.get(field.index()) { Some(&ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 668172749fec..afd338581392 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -635,7 +635,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap(); assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs"); let inputs = match tuplized_inputs[0].sty { - ty::TyTuple(inputs, _) => inputs, + ty::TyTuple(inputs) => inputs, _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]), }; diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 1a9064aab1b2..b7f402f61a9c 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -298,7 +298,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source_info = self.source_info(span); let bool_ty = self.hir.bool_ty(); if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() { - let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty], false); + let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]); let result_value = self.temp(result_tup, span); self.cfg.push_assign(block, source_info, diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index da25969bf117..62d1b43d6257 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -227,7 +227,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e)); let tupled_args = Expr { - ty: cx.tcx.mk_tup(arg_tys, false), + ty: cx.tcx.mk_tup(arg_tys), temp_lifetime, span: expr.span, kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() }, diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index a3295aac8015..58aa9b06c642 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -877,7 +877,7 @@ fn pat_constructors<'tcx>(_cx: &mut MatchCheckCtxt, fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 { debug!("constructor_arity({:#?}, {:?})", ctor, ty); match ty.sty { - ty::TyTuple(ref fs, _) => fs.len() as u64, + ty::TyTuple(ref fs) => fs.len() as u64, ty::TySlice(..) | ty::TyArray(..) => match *ctor { Slice(length) => length, ConstantValue(_) => 0, @@ -901,7 +901,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>, { debug!("constructor_sub_pattern_tys({:#?}, {:?})", ctor, ty); match ty.sty { - ty::TyTuple(ref fs, _) => fs.into_iter().map(|t| *t).collect(), + ty::TyTuple(ref fs) => fs.into_iter().map(|t| *t).collect(), ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor { Slice(length) => (0..length).map(|_| ty).collect(), ConstantValue(_) => vec![], diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 1774c95af0f0..eb87d5b044b4 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -449,7 +449,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatKind::Tuple(ref subpatterns, ddpos) => { let ty = self.tables.node_id_to_type(pat.hir_id); match ty.sty { - ty::TyTuple(ref tys, _) => { + ty::TyTuple(ref tys) => { let subpatterns = subpatterns.iter() .enumerate_and_adjust(tys.len(), ddpos) @@ -879,7 +879,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { subpatterns: adt_subpatterns(struct_var.fields.len(), None), } } - ty::TyTuple(fields, _) => { + ty::TyTuple(fields) => { PatternKind::Leaf { subpatterns: adt_subpatterns(fields.len(), None), } diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index be34b8705eb1..851fac532e36 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -234,7 +234,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { // Second argument must be a tuple matching the argument list of sig let snd_ty = real_sig.inputs_and_output[1]; match snd_ty.sty { - ty::TyTuple(tys, _) if sig.inputs().len() == tys.len() => + ty::TyTuple(tys) if sig.inputs().len() == tys.len() => if sig.inputs().iter().zip(tys).all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) { return Ok(true) }, diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 10e2a84038de..c2f4359c0082 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -281,7 +281,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { self.push_def_path(adt_def.did, output); self.push_type_params(substs, iter::empty(), output); }, - ty::TyTuple(component_types, _) => { + ty::TyTuple(component_types) => { output.push('('); for &component_type in component_types { self.push_type_name(component_type, output); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 62af09cc4910..6a0f42c6dbb6 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -312,7 +312,7 @@ fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, substs.upvar_tys(def_id, tcx) ) } - ty::TyTuple(tys, _) => builder.tuple_like_shim(dest, src, tys.iter().cloned()), + ty::TyTuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().cloned()), _ => { bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty) } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 6380d2a5c15f..2dd805ccf9b5 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -599,7 +599,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { assert!(args.next().is_none()); let tuple = Place::Local(tuple); - let tuple_tys = if let ty::TyTuple(s, _) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty { + let tuple_tys = if let ty::TyTuple(s) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty { s } else { bug!("Closure arguments are not passed as a tuple"); diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 3f5208dd2d4b..e95126c8a1a0 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -788,7 +788,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect(); self.open_drop_for_tuple(&tys) } - ty::TyTuple(tys, _) => { + ty::TyTuple(tys) => { self.open_drop_for_tuple(tys) } ty::TyAdt(def, _) if def.is_box() => { diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index c1dc8c6684a1..4a98fff6af76 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -722,7 +722,7 @@ impl<'a, 'tcx> FnType<'tcx> { assert!(!sig.variadic && extra_args.is_empty()); match sig.inputs().last().unwrap().sty { - ty::TyTuple(ref tupled_arguments, _) => { + ty::TyTuple(ref tupled_arguments) => { inputs = &sig.inputs()[0..sig.inputs().len() - 1]; tupled_arguments } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 20cc57522b5d..f3d95cf794ba 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -362,7 +362,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // return type signature_metadata.push(match signature.output().sty { - ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(), + ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), _ => type_metadata(cx, signature.output(), span) }); @@ -533,7 +533,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ty::TyFloat(_) => { MetadataCreationResult::new(basic_type_metadata(cx, t), false) } - ty::TyTuple(ref elements, _) if elements.is_empty() => { + ty::TyTuple(ref elements) if elements.is_empty() => { MetadataCreationResult::new(basic_type_metadata(cx, t), false) } ty::TyArray(typ, _) | @@ -621,7 +621,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, usage_site_span).finalize(cx) } }, - ty::TyTuple(ref elements, _) => { + ty::TyTuple(ref elements) => { prepare_tuple_metadata(cx, t, &elements[..], @@ -731,7 +731,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let (name, encoding) = match t.sty { ty::TyNever => ("!", DW_ATE_unsigned), - ty::TyTuple(ref elements, _) if elements.is_empty() => + ty::TyTuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned), ty::TyBool => ("bool", DW_ATE_boolean), ty::TyChar => ("char", DW_ATE_unsigned_char), diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index c13b91eb3b6b..7664c88679e0 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -312,7 +312,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, // Return type -- llvm::DIBuilder wants this at index 0 signature.push(match sig.output().sty { - ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(), + ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(), _ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP) }); @@ -351,7 +351,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } if sig.abi == Abi::RustCall && !sig.inputs().is_empty() { - if let ty::TyTuple(args, _) = sig.inputs()[sig.inputs().len() - 1].sty { + if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty { for &argument_type in args { signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)); } diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 211de95c96ed..96ed4e884711 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -53,7 +53,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, push_item_name(cx, def.did, qualified, output); push_type_params(cx, substs, output); }, - ty::TyTuple(component_types, _) => { + ty::TyTuple(component_types) => { output.push('('); for &component_type in component_types { push_debuginfo_type_name(cx, component_type, true, output); diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 96c5bb3b91d2..93bc89f0914f 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -710,7 +710,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { let layout = cx.layout_of(cx.tcx.intern_tup(&[ cx.tcx.mk_mut_ptr(cx.tcx.types.u8), cx.tcx.types.i32 - ], false)); + ])); let slot = PlaceRef::alloca(bx, layout, "personalityslot"); self.personality_slot = Some(slot); slot diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 0533b04a0c1d..11dabbeae743 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -448,7 +448,7 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, let arg_ty = fx.monomorphize(&arg_decl.ty); let tupled_arg_tys = match arg_ty.sty { - ty::TyTuple(ref tys, _) => tys, + ty::TyTuple(ref tys) => tys, _ => bug!("spread argument isn't a tuple?!") }; diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index fa0514952d21..93702bfbbf3b 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -399,7 +399,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { lhs.immediate(), rhs.immediate(), lhs.layout.ty); let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty); - let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool], false); + let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool]); let operand = OperandRef { val: result, layout: bx.cx.layout_of(operand_ty) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 0df1225cf262..827ca79334cb 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1050,7 +1050,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.types.never }, hir::TyTup(ref fields) => { - tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)), false) + tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t))) } hir::TyBareFn(ref bf) => { require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index eb02c05fd395..379fd93ba2bd 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -319,7 +319,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut expected_len = elements.len(); if ddpos.is_some() { // Require known type only when `..` is present - if let ty::TyTuple(ref tys, _) = + if let ty::TyTuple(ref tys) = self.structurally_resolved_type(pat.span, expected).sty { expected_len = tys.len(); } @@ -332,7 +332,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::UniverseIndex::ROOT, TypeVariableOrigin::TypeInference(pat.span))); let element_tys = tcx.mk_type_list(element_tys_iter); - let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys, false)); + let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys)); self.demand_eqtype(pat.span, expected, pat_ty); for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { self.check_pat_walk(elem, &element_tys[i], def_bm, true); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 48bd7b14fc96..c2c113f2da9f 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -115,7 +115,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - ty::TyTuple(fields, _) => match fields.last() { + ty::TyTuple(fields) => match fields.last() { None => Some(PointerKind::Thin), Some(f) => self.pointer_kind(f, span)? }, diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 72e4b726a22b..562c0cb1b8d0 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -140,7 +140,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // the `closures` table. let sig = bound_sig.map_bound(|sig| { self.tcx.mk_fn_sig( - iter::once(self.tcx.intern_tup(sig.inputs(), false)), + iter::once(self.tcx.intern_tup(sig.inputs())), sig.output(), sig.variadic, sig.unsafety, @@ -312,7 +312,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ); let input_tys = match arg_param_ty.sty { - ty::TyTuple(tys, _) => tys.into_iter(), + ty::TyTuple(tys) => tys.into_iter(), _ => { return None; } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 2e00040d99a7..59cf8a0358ef 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -87,7 +87,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "cxchg" | "cxchgweak" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0), param(0)], - tcx.intern_tup(&[param(0), tcx.types.bool], false)), + tcx.intern_tup(&[param(0), tcx.types.bool])), "load" => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)), "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], @@ -281,7 +281,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => (1, vec![param(0), param(0)], - tcx.intern_tup(&[param(0), tcx.types.bool], false)), + tcx.intern_tup(&[param(0), tcx.types.bool])), "unchecked_div" | "unchecked_rem" => (1, vec![param(0), param(0)], param(0)), @@ -441,7 +441,7 @@ fn match_intrinsic_type_to_type<'a, 'tcx>( match *expected { Void => match t.sty { - ty::TyTuple(ref v, _) if v.is_empty() => {}, + ty::TyTuple(ref v) if v.is_empty() => {}, _ => simple_error(&format!("`{}`", t), "()"), }, // (The width we pass to LLVM doesn't concern the type checker.) @@ -515,7 +515,7 @@ fn match_intrinsic_type_to_type<'a, 'tcx>( } Aggregate(_flatten, ref expected_contents) => { match t.sty { - ty::TyTuple(contents, _) => { + ty::TyTuple(contents) => { if contents.len() != expected_contents.len() { simple_error(&format!("tuple with length {}", contents.len()), &format!("tuple with length {}", expected_contents.len())); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 48591998a1fb..ec6383bf9a52 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2160,8 +2160,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Tries to apply a fallback to `ty` if it is an unsolved variable. - // Non-numerics get replaced with ! or () (depending on whether - // feature(never_type) is enabled), unconstrained ints with i32, + // Non-numerics get replaced with !, unconstrained ints with i32, // unconstrained floats with f64. // Fallback becomes very dubious if we have encountered type-checking errors. // In that case, fallback to TyError. @@ -2174,7 +2173,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ if self.is_tainted_by_errors() => self.tcx().types.err, UnconstrainedInt => self.tcx.types.i32, UnconstrainedFloat => self.tcx.types.f64, - Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(), + Neither if self.type_var_diverges(ty) => self.tcx.types.never, Neither => return }; debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback); @@ -2438,7 +2437,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, - TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)], + TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])], }; self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr, @@ -2531,16 +2530,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let formal_tys = if tuple_arguments == TupleArguments { let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]); match tuple_type.sty { - ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => { + ty::TyTuple(arg_types) if arg_types.len() != args.len() => { parameter_count_error(tcx.sess, sp, expr_sp, arg_types.len(), args.len(), "E0057", false, def_span, false); expected_arg_tys = &[]; self.err_args(args.len()) } - ty::TyTuple(arg_types, _) => { + ty::TyTuple(arg_types) => { expected_arg_tys = match expected_arg_tys.get(0) { Some(&ty) => match ty.sty { - ty::TyTuple(ref tys, _) => &tys, + ty::TyTuple(ref tys) => &tys, _ => &[] }, None => &[] @@ -3193,7 +3192,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { None } } - ty::TyTuple(ref v, _) => { + ty::TyTuple(ref v) => { tuple_like = true; v.get(idx.node).cloned() } @@ -4060,7 +4059,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let flds = expected.only_has_type(self).and_then(|ty| { let ty = self.resolve_type_vars_with_obligations(ty); match ty.sty { - ty::TyTuple(ref flds, _) => Some(&flds[..]), + ty::TyTuple(ref flds) => Some(&flds[..]), _ => None } }); @@ -4078,7 +4077,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; t }); - let tuple = tcx.mk_tup(elt_ts_iter, false); + let tuple = tcx.mk_tup(elt_ts_iter); if tuple.references_error() { tcx.types.err } else { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 2a4e92034de8..a24e501aba95 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -287,7 +287,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { self.add_constraints_from_mt(current, mt, variance); } - ty::TyTuple(subtys, _) => { + ty::TyTuple(subtys) => { for &subty in subtys { self.add_constraints_from_ty(current, subty, variance); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ff281a53ab7e..904c24815cb7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1322,7 +1322,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option, has_self: boo Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => { assert_eq!(types.len(), 1); let inputs = match types[0].sty { - ty::TyTuple(ref tys, _) => tys.iter().map(|t| t.clean(cx)).collect(), + ty::TyTuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(), _ => { return PathParameters::AngleBracketed { lifetimes, @@ -1334,7 +1334,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option, has_self: boo let output = None; // FIXME(#20299) return type comes from a projection now // match types[1].sty { - // ty::TyTuple(ref v, _) if v.is_empty() => None, // -> () + // ty::TyTuple(ref v) if v.is_empty() => None, // -> () // _ => Some(types[1].clean(cx)) // }; PathParameters::Parenthesized { @@ -1377,7 +1377,7 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { // collect any late bound regions let mut late_bounds = vec![]; for ty_s in self.input_types().skip(1) { - if let ty::TyTuple(ts, _) = ty_s.sty { + if let ty::TyTuple(ts) = ty_s.sty { for &ty_s in ts { if let ty::TyRef(ref reg, _) = ty_s.sty { if let &ty::RegionKind::ReLateBound(..) = *reg { @@ -2731,7 +2731,7 @@ impl<'tcx> Clean for Ty<'tcx> { Never } } - ty::TyTuple(ref t, _) => Tuple(t.clean(cx)), + ty::TyTuple(ref t) => Tuple(t.clean(cx)), ty::TyProjection(ref data) => data.clean(cx), diff --git a/src/test/compile-fail/defaulted-unit-warning.rs b/src/test/compile-fail/defaulted-unit-warning.rs deleted file mode 100644 index 3f4e1cce548b..000000000000 --- a/src/test/compile-fail/defaulted-unit-warning.rs +++ /dev/null @@ -1,38 +0,0 @@ -// 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. - -#![allow(unused)] - -trait Deserialize: Sized { - fn deserialize() -> Result; -} - -impl Deserialize for () { - fn deserialize() -> Result<(), String> { - Ok(()) - } -} - -trait ImplementedForUnitButNotNever {} - -impl ImplementedForUnitButNotNever for () {} - -fn foo(_t: T) {} - -fn smeg() { - let _x = return; - foo(_x); - //~^ ERROR code relies on type - //~| WARNING previously accepted -} - -fn main() { - smeg(); -} diff --git a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs index 75b60aa8d10b..052575de4c26 100644 --- a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs @@ -31,5 +31,5 @@ trait Add { fn ice(a: A) { let r = loop {}; r = r + a; - //~^ ERROR the trait bound `(): Add` is not satisfied + //~^ ERROR the trait bound `!: Add` is not satisfied } diff --git a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr index 7924ab744440..c22a645385ad 100644 --- a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr +++ b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `(): Add` is not satisfied +error[E0277]: the trait bound `!: Add` is not satisfied --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:33:11 | LL | r = r + a; - | ^ the trait `Add` is not implemented for `()` + | ^ the trait `Add` is not implemented for `!` error: aborting due to previous error From a9fc3901b07d0494bd3eb9c37b10e63b429714b0 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sun, 21 Jan 2018 16:44:41 +0800 Subject: [PATCH 176/830] stabilise feature(never_type) Replace feature(never_type) with feature(exhaustive_patterns). feature(exhaustive_patterns) only covers the pattern-exhaustives checks that used to be covered by feature(never_type) --- src/libcore/cmp.rs | 8 +++--- src/libcore/fmt/mod.rs | 4 +-- src/libcore/lib.rs | 3 +- src/librustc/lib.rs | 2 +- src/librustc_lint/lib.rs | 1 + src/librustc_mir/build/matches/simplify.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 6 ++-- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/librustc_mir/lib.rs | 3 +- src/librustc_typeck/lib.rs | 3 +- src/libstd/error.rs | 2 +- src/libstd/lib.rs | 3 +- src/libstd/primitive_docs.rs | 11 ++++---- src/libsyntax/feature_gate.rs | 8 ++---- .../call-fn-never-arg-wrong-type.rs | 2 -- src/test/compile-fail/coerce-to-bang-cast.rs | 2 -- src/test/compile-fail/coerce-to-bang.rs | 1 - .../inhabitedness-infinite-loop.rs | 2 +- src/test/compile-fail/loop-break-value.rs | 2 -- .../compile-fail/match-privately-empty.rs | 2 +- .../compile-fail/never-assign-dead-code.rs | 2 +- .../compile-fail/never-assign-wrong-type.rs | 1 - .../recursive-types-are-not-uninhabited.rs | 2 -- .../compile-fail/uninhabited-irrefutable.rs | 2 +- src/test/compile-fail/uninhabited-patterns.rs | 2 +- .../compile-fail/unreachable-loop-patterns.rs | 2 +- .../compile-fail/unreachable-try-pattern.rs | 2 +- src/test/run-fail/adjust_never.rs | 2 -- src/test/run-fail/call-fn-never-arg.rs | 1 - src/test/run-fail/cast-never.rs | 2 -- src/test/run-fail/never-associated-type.rs | 2 -- src/test/run-fail/never-type-arg.rs | 2 -- .../diverging-fallback-control-flow.rs | 2 -- src/test/run-pass/empty-types-in-patterns.rs | 2 +- src/test/run-pass/impl-for-never.rs | 2 -- src/test/run-pass/issue-44402.rs | 2 +- src/test/run-pass/loop-break-value.rs | 2 -- src/test/run-pass/mir_calls_to_shims.rs | 1 - src/test/run-pass/never-result.rs | 2 -- .../feature-gate-exhaustive-patterns.rs} | 23 ++++++--------- .../feature-gate-exhaustive-patterns.stderr | 8 ++++++ src/test/ui/feature-gate-never_type.rs | 28 ------------------- src/test/ui/print_type_sizes/uninhabited.rs | 1 - src/test/ui/reachable/expr_add.rs | 1 - src/test/ui/reachable/expr_add.stderr | 4 +-- src/test/ui/reachable/expr_array.rs | 3 +- src/test/ui/reachable/expr_array.stderr | 4 +-- src/test/ui/reachable/expr_assign.rs | 1 - src/test/ui/reachable/expr_assign.stderr | 6 ++-- src/test/ui/reachable/expr_block.rs | 1 - src/test/ui/reachable/expr_block.stderr | 4 +-- src/test/ui/reachable/expr_call.rs | 1 - src/test/ui/reachable/expr_call.stderr | 4 +-- src/test/ui/reachable/expr_cast.rs | 1 - src/test/ui/reachable/expr_cast.stderr | 2 +- src/test/ui/reachable/expr_if.rs | 1 - src/test/ui/reachable/expr_if.stderr | 2 +- src/test/ui/reachable/expr_loop.rs | 1 - src/test/ui/reachable/expr_loop.stderr | 6 ++-- src/test/ui/reachable/expr_match.rs | 1 - src/test/ui/reachable/expr_match.stderr | 6 ++-- src/test/ui/reachable/expr_method.rs | 1 - src/test/ui/reachable/expr_method.stderr | 4 +-- src/test/ui/reachable/expr_repeat.rs | 1 - src/test/ui/reachable/expr_repeat.stderr | 2 +- src/test/ui/reachable/expr_return.rs | 1 - src/test/ui/reachable/expr_return.stderr | 2 +- src/test/ui/reachable/expr_struct.rs | 1 - src/test/ui/reachable/expr_struct.stderr | 8 +++--- src/test/ui/reachable/expr_tup.rs | 1 - src/test/ui/reachable/expr_tup.stderr | 4 +-- src/test/ui/reachable/expr_type.rs | 1 - src/test/ui/reachable/expr_type.stderr | 2 +- src/test/ui/reachable/expr_unary.rs | 1 - src/test/ui/reachable/expr_unary.stderr | 6 ++-- src/test/ui/reachable/expr_while.rs | 1 - src/test/ui/reachable/expr_while.stderr | 6 ++-- 77 files changed, 91 insertions(+), 164 deletions(-) rename src/test/{run-pass/issue-38972.rs => ui/feature-gate-exhaustive-patterns.rs} (54%) create mode 100644 src/test/ui/feature-gate-exhaustive-patterns.stderr delete mode 100644 src/test/ui/feature-gate-never_type.rs diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 6602643dc510..fdb9946469b4 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -882,24 +882,24 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl Eq for ! {} - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option { *self } } - #[unstable(feature = "never_type", issue = "35121")] + #[stable(feature = "never_type", since = "1.24.0")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 213b317f632e..3706da7c5218 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1579,14 +1579,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.24.0")] impl Debug for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self } } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.24.0")] impl Display for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index cefcc5ff03f0..a947c9f0b7c1 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -85,7 +85,7 @@ #![feature(iterator_repeat_with)] #![feature(lang_items)] #![feature(link_llvm_intrinsics)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(no_core)] #![feature(on_unimplemented)] #![feature(optin_builtin_traits)] @@ -103,6 +103,7 @@ #![feature(unwind_attributes)] #![cfg_attr(stage0, allow(unused_attributes))] +#![cfg_attr(stage0, feature(never_type))] #[prelude_import] #[allow(unused)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 77b3a87c0ed1..51882385b2ef 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -60,7 +60,7 @@ #![feature(match_default_bindings)] #![feature(macro_lifetime_matcher)] #![feature(macro_vis_matcher)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(non_exhaustive)] #![feature(nonzero)] #![feature(proc_macro_internals)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 235d733b253a..cbc1d7c38d61 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -32,6 +32,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] +#![cfg_attr(stage0, feature(never_type))] #[macro_use] extern crate syntax; diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index abea55835466..4e95ee6444dc 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -113,7 +113,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| { i == variant_index || { - self.hir.tcx().features().never_type && + self.hir.tcx().features().exhaustive_patterns && self.hir.tcx().is_variant_uninhabited_from_all_modules(v, substs) } }); diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 58aa9b06c642..6f8b1f8e7994 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -219,7 +219,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { } fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { - if self.tcx.features().never_type { + if self.tcx.features().exhaustive_patterns { self.tcx.is_ty_uninhabited_from(self.module, ty) } else { false @@ -245,7 +245,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { substs: &'tcx ty::subst::Substs<'tcx>) -> bool { - if self.tcx.features().never_type { + if self.tcx.features().exhaustive_patterns { self.tcx.is_enum_variant_uninhabited_from(self.module, variant, substs) } else { false @@ -694,7 +694,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, // test for details. // // FIXME: currently the only way I know of something can - // be a privately-empty enum is when the never_type + // be a privately-empty enum is when the exhaustive_patterns // feature flag is not present, so this is only // needed for that case. diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 69ed4e6064fc..d924baaf0052 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -222,7 +222,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { let pat_ty = self.tables.node_id_to_type(scrut.hir_id); let module = self.tcx.hir.get_module_parent(scrut.id); if inlined_arms.is_empty() { - let scrutinee_is_uninhabited = if self.tcx.features().never_type { + let scrutinee_is_uninhabited = if self.tcx.features().exhaustive_patterns { self.tcx.is_ty_uninhabited_from(module, pat_ty) } else { self.conservative_is_uninhabited(pat_ty) diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index c31e95fd826c..5510e2197806 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -32,13 +32,14 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(inclusive_range)] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(placement_in_syntax)] #![feature(collection_placement)] #![feature(nonzero)] #![feature(underscore_lifetimes)] +#![cfg_attr(stage0, feature(never_type))] extern crate arena; #[macro_use] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index ea90c35cb8f2..a97c6e84eab5 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -80,13 +80,14 @@ This API is completely unstable and subject to change. #![feature(crate_visibility_modifier)] #![feature(from_ref)] #![feature(match_default_bindings)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(option_filter)] #![feature(quote)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] #![feature(i128_type)] +#![cfg_attr(stage0, feature(never_type))] #[macro_use] extern crate log; #[macro_use] extern crate syntax; diff --git a/src/libstd/error.rs b/src/libstd/error.rs index eb5022ad5776..347b82244109 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -234,7 +234,7 @@ impl<'a> From> for Box { } } -#[unstable(feature = "never_type", issue = "35121")] +#[stable(feature = "never_type", since = "1.24.0")] impl Error for ! { fn description(&self) -> &str { *self } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index da15941374d8..eea0e6b67527 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -282,7 +282,7 @@ #![feature(macro_reexport)] #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] @@ -324,6 +324,7 @@ #![feature(doc_spotlight)] #![cfg_attr(test, feature(update_panic_count))] #![cfg_attr(windows, feature(used))] +#![cfg_attr(stage0, feature(never_type))] #![default_lib_allocator] diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 358aa2c37dfb..e6e6be2e4537 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -79,7 +79,6 @@ mod prim_bool { } /// write: /// /// ``` -/// #![feature(never_type)] /// # fn foo() -> u32 { /// let x: ! = { /// return 123 @@ -131,13 +130,15 @@ mod prim_bool { } /// [`Result`] which we can unpack like this: /// /// ```ignore (string-from-str-error-type-is-not-never-yet) +/// #[feature(exhaustive_patterns)] /// // NOTE: This does not work today! /// let Ok(s) = String::from_str("hello"); /// ``` /// -/// Since the [`Err`] variant contains a `!`, it can never occur. So we can exhaustively match on -/// [`Result`] by just taking the [`Ok`] variant. This illustrates another behaviour of `!` - -/// it can be used to "delete" certain enum variants from generic types like `Result`. +/// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns` +/// feature is present this means we can exhaustively match on [`Result`] by just taking the +/// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain +/// enum variants from generic types like `Result`. /// /// [`String::from_str`]: str/trait.FromStr.html#tymethod.from_str /// [`Result`]: result/enum.Result.html @@ -154,7 +155,6 @@ mod prim_bool { } /// for example: /// /// ``` -/// # #![feature(never_type)] /// # use std::fmt; /// # trait Debug { /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result; @@ -192,7 +192,6 @@ mod prim_bool { } /// [`Default`]: default/trait.Default.html /// [`default()`]: default/trait.Default.html#tymethod.default /// -#[unstable(feature = "never_type", issue = "35121")] mod prim_never { } #[doc(primitive = "char")] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ec9a15d9f2b4..91364fe6ed48 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -286,8 +286,8 @@ declare_features! ( // Allows `impl Trait` in function arguments. (active, universal_impl_trait, "1.23.0", Some(34511), None), - // The `!` type - (active, never_type, "1.13.0", Some(35121), None), + // Allows exhaustive pattern matching on types that contain uninhabited types. + (active, exhaustive_patterns, "1.13.0", None, None), // Allows all literals in attribute lists and values of key-value pairs. (active, attr_literals, "1.13.0", Some(34981), None), @@ -1566,10 +1566,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::TyKind::BareFn(ref bare_fn_ty) => { self.check_abi(bare_fn_ty.abi, ty.span); } - ast::TyKind::Never => { - gate_feature_post!(&self, never_type, ty.span, - "The `!` type is experimental"); - }, ast::TyKind::TraitObject(_, ast::TraitObjectSyntax::Dyn) => { gate_feature_post!(&self, dyn_trait, ty.span, "`dyn Trait` syntax is unstable"); diff --git a/src/test/compile-fail/call-fn-never-arg-wrong-type.rs b/src/test/compile-fail/call-fn-never-arg-wrong-type.rs index 583befed1e82..c2f157cd35cc 100644 --- a/src/test/compile-fail/call-fn-never-arg-wrong-type.rs +++ b/src/test/compile-fail/call-fn-never-arg-wrong-type.rs @@ -10,8 +10,6 @@ // Test that we can't pass other types for ! -#![feature(never_type)] - fn foo(x: !) -> ! { x } diff --git a/src/test/compile-fail/coerce-to-bang-cast.rs b/src/test/compile-fail/coerce-to-bang-cast.rs index 0d5bf6cd68cb..8b3a9ed092d9 100644 --- a/src/test/compile-fail/coerce-to-bang-cast.rs +++ b/src/test/compile-fail/coerce-to-bang-cast.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] - fn foo(x: usize, y: !, z: usize) { } #[deny(coerce_never)] diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs index b804bb2981ba..b365f142a9b7 100644 --- a/src/test/compile-fail/coerce-to-bang.rs +++ b/src/test/compile-fail/coerce-to-bang.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] #![deny(coerce_never)] fn foo(x: usize, y: !, z: usize) { } diff --git a/src/test/compile-fail/inhabitedness-infinite-loop.rs b/src/test/compile-fail/inhabitedness-infinite-loop.rs index 91b85d7510a2..b9741e0add61 100644 --- a/src/test/compile-fail/inhabitedness-infinite-loop.rs +++ b/src/test/compile-fail/inhabitedness-infinite-loop.rs @@ -10,7 +10,7 @@ // error-pattern:reached recursion limit -#![feature(never_type)] +#![feature(exhaustive_patterns)] struct Foo<'a, T: 'a> { ph: std::marker::PhantomData, diff --git a/src/test/compile-fail/loop-break-value.rs b/src/test/compile-fail/loop-break-value.rs index 938f7fba2a03..5ef46bb27fd6 100644 --- a/src/test/compile-fail/loop-break-value.rs +++ b/src/test/compile-fail/loop-break-value.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] - fn main() { let val: ! = loop { break break; }; //~^ ERROR mismatched types diff --git a/src/test/compile-fail/match-privately-empty.rs b/src/test/compile-fail/match-privately-empty.rs index 3affb1c03e95..e18c7d77ce36 100644 --- a/src/test/compile-fail/match-privately-empty.rs +++ b/src/test/compile-fail/match-privately-empty.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] +#![feature(exhaustive_patterns)] mod private { pub struct Private { diff --git a/src/test/compile-fail/never-assign-dead-code.rs b/src/test/compile-fail/never-assign-dead-code.rs index 1e0cc0f5357f..4e987d1ddce5 100644 --- a/src/test/compile-fail/never-assign-dead-code.rs +++ b/src/test/compile-fail/never-assign-dead-code.rs @@ -10,7 +10,7 @@ // Test that an assignment of type ! makes the rest of the block dead code. -#![feature(never_type, rustc_attrs)] +#![feature(rustc_attrs)] #![warn(unused)] #[rustc_error] diff --git a/src/test/compile-fail/never-assign-wrong-type.rs b/src/test/compile-fail/never-assign-wrong-type.rs index c0dd2cab749f..8c2de7d68d3d 100644 --- a/src/test/compile-fail/never-assign-wrong-type.rs +++ b/src/test/compile-fail/never-assign-wrong-type.rs @@ -10,7 +10,6 @@ // Test that we can't use another type in place of ! -#![feature(never_type)] #![deny(warnings)] fn main() { diff --git a/src/test/compile-fail/recursive-types-are-not-uninhabited.rs b/src/test/compile-fail/recursive-types-are-not-uninhabited.rs index f8d6c3de2ab0..fa9366970722 100644 --- a/src/test/compile-fail/recursive-types-are-not-uninhabited.rs +++ b/src/test/compile-fail/recursive-types-are-not-uninhabited.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//#![feature(never_type)] - struct R<'a> { r: &'a R<'a>, } diff --git a/src/test/compile-fail/uninhabited-irrefutable.rs b/src/test/compile-fail/uninhabited-irrefutable.rs index 4755fdd4fd5e..72b0afa6bd3e 100644 --- a/src/test/compile-fail/uninhabited-irrefutable.rs +++ b/src/test/compile-fail/uninhabited-irrefutable.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] +#![feature(exhaustive_patterns)] mod foo { pub struct SecretlyEmpty { diff --git a/src/test/compile-fail/uninhabited-patterns.rs b/src/test/compile-fail/uninhabited-patterns.rs index 4c894b0bdd3d..9f943f08232d 100644 --- a/src/test/compile-fail/uninhabited-patterns.rs +++ b/src/test/compile-fail/uninhabited-patterns.rs @@ -11,7 +11,7 @@ #![feature(box_patterns)] #![feature(slice_patterns)] #![feature(box_syntax)] -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![deny(unreachable_patterns)] mod foo { diff --git a/src/test/compile-fail/unreachable-loop-patterns.rs b/src/test/compile-fail/unreachable-loop-patterns.rs index 6147692658f9..dca79bdfb87f 100644 --- a/src/test/compile-fail/unreachable-loop-patterns.rs +++ b/src/test/compile-fail/unreachable-loop-patterns.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/compile-fail/unreachable-try-pattern.rs b/src/test/compile-fail/unreachable-try-pattern.rs index 46ea4a06a3bd..0caf7d512349 100644 --- a/src/test/compile-fail/unreachable-try-pattern.rs +++ b/src/test/compile-fail/unreachable-try-pattern.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type, rustc_attrs)] +#![feature(exhaustive_patterns, rustc_attrs)] #![warn(unreachable_code)] #![warn(unreachable_patterns)] diff --git a/src/test/run-fail/adjust_never.rs b/src/test/run-fail/adjust_never.rs index ccdb1ca15bba..7a4b5e59eeb7 100644 --- a/src/test/run-fail/adjust_never.rs +++ b/src/test/run-fail/adjust_never.rs @@ -10,8 +10,6 @@ // Test that a variable of type ! can coerce to another type. -#![feature(never_type)] - // error-pattern:explicit fn main() { let x: ! = panic!(); diff --git a/src/test/run-fail/call-fn-never-arg.rs b/src/test/run-fail/call-fn-never-arg.rs index 95101e70db95..56454586bb95 100644 --- a/src/test/run-fail/call-fn-never-arg.rs +++ b/src/test/run-fail/call-fn-never-arg.rs @@ -12,7 +12,6 @@ // error-pattern:wowzers! -#![feature(never_type)] #![allow(unreachable_code)] fn foo(x: !) -> ! { diff --git a/src/test/run-fail/cast-never.rs b/src/test/run-fail/cast-never.rs index acd002494f4e..0155332c51d1 100644 --- a/src/test/run-fail/cast-never.rs +++ b/src/test/run-fail/cast-never.rs @@ -10,8 +10,6 @@ // Test that we can explicitly cast ! to another type -#![feature(never_type)] - // error-pattern:explicit fn main() { let x: ! = panic!(); diff --git a/src/test/run-fail/never-associated-type.rs b/src/test/run-fail/never-associated-type.rs index 345674f3f522..d9b8461a1d07 100644 --- a/src/test/run-fail/never-associated-type.rs +++ b/src/test/run-fail/never-associated-type.rs @@ -10,8 +10,6 @@ // Test that we can use ! as an associated type. -#![feature(never_type)] - // error-pattern:kapow! trait Foo { diff --git a/src/test/run-fail/never-type-arg.rs b/src/test/run-fail/never-type-arg.rs index 826ca3a08c0e..0fe10d43910b 100644 --- a/src/test/run-fail/never-type-arg.rs +++ b/src/test/run-fail/never-type-arg.rs @@ -12,8 +12,6 @@ // error-pattern:oh no! -#![feature(never_type)] - struct Wub; impl PartialEq for Wub { diff --git a/src/test/run-pass/diverging-fallback-control-flow.rs b/src/test/run-pass/diverging-fallback-control-flow.rs index 723a98bcdfa0..a96f98b9efda 100644 --- a/src/test/run-pass/diverging-fallback-control-flow.rs +++ b/src/test/run-pass/diverging-fallback-control-flow.rs @@ -14,8 +14,6 @@ // These represent current behavior, but are pretty dubious. I would // like to revisit these and potentially change them. --nmatsakis -#![feature(never_type)] - trait BadDefault { fn default() -> Self; } diff --git a/src/test/run-pass/empty-types-in-patterns.rs b/src/test/run-pass/empty-types-in-patterns.rs index 033b185a0ef0..87db44019298 100644 --- a/src/test/run-pass/empty-types-in-patterns.rs +++ b/src/test/run-pass/empty-types-in-patterns.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] +#![feature(exhaustive_patterns)] #![feature(slice_patterns)] #![allow(unreachable_patterns)] #![allow(unreachable_code)] diff --git a/src/test/run-pass/impl-for-never.rs b/src/test/run-pass/impl-for-never.rs index 794f5969bff5..cf54e1c3bd59 100644 --- a/src/test/run-pass/impl-for-never.rs +++ b/src/test/run-pass/impl-for-never.rs @@ -10,8 +10,6 @@ // Test that we can call static methods on ! both directly and when it appears in a generic -#![feature(never_type)] - trait StringifyType { fn stringify_type() -> &'static str; } diff --git a/src/test/run-pass/issue-44402.rs b/src/test/run-pass/issue-44402.rs index 244aa65a3d56..a5a0a5a57944 100644 --- a/src/test/run-pass/issue-44402.rs +++ b/src/test/run-pass/issue-44402.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] +#![feature(exhaustive_patterns)] // Regression test for inhabitedness check. The old // cache used to cause us to incorrectly decide diff --git a/src/test/run-pass/loop-break-value.rs b/src/test/run-pass/loop-break-value.rs index 39053769b24b..ffdd99ebf6e5 100644 --- a/src/test/run-pass/loop-break-value.rs +++ b/src/test/run-pass/loop-break-value.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] - #[allow(unused)] fn never_returns() { loop { diff --git a/src/test/run-pass/mir_calls_to_shims.rs b/src/test/run-pass/mir_calls_to_shims.rs index 9641ed282936..dda7a46f3258 100644 --- a/src/test/run-pass/mir_calls_to_shims.rs +++ b/src/test/run-pass/mir_calls_to_shims.rs @@ -11,7 +11,6 @@ // ignore-wasm32-bare compiled with panic=abort by default #![feature(fn_traits)] -#![feature(never_type)] use std::panic; diff --git a/src/test/run-pass/never-result.rs b/src/test/run-pass/never-result.rs index 5c0af392f44d..8aa2a13ed8c8 100644 --- a/src/test/run-pass/never-result.rs +++ b/src/test/run-pass/never-result.rs @@ -10,8 +10,6 @@ // Test that we can extract a ! through pattern matching then use it as several different types. -#![feature(never_type)] - fn main() { let x: Result = Ok(123); match x { diff --git a/src/test/run-pass/issue-38972.rs b/src/test/ui/feature-gate-exhaustive-patterns.rs similarity index 54% rename from src/test/run-pass/issue-38972.rs rename to src/test/ui/feature-gate-exhaustive-patterns.rs index d5df84e0fb08..477dd1b38eb0 100644 --- a/src/test/run-pass/issue-38972.rs +++ b/src/test/ui/feature-gate-exhaustive-patterns.rs @@ -1,4 +1,4 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,18 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// This issue tracks a regression (a new warning) without -// feature(never_type). When we make that the default, please -// remove this test. - -enum Foo { } - -fn make_foo() -> Option { None } - -#[deny(warnings)] -fn main() { - match make_foo() { - None => {}, - Some(_) => {} - } +fn foo() -> Result { + Ok(123) } + +fn main() { + let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding +} + diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr new file mode 100644 index 000000000000..43a4adf93730 --- /dev/null +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -0,0 +1,8 @@ +error[E0005]: refutable pattern in local binding: `Err(_)` not covered + --> $DIR/feature-gate-exhaustive-patterns.rs:16:9 + | +16 | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding + | ^^^^^^ pattern `Err(_)` not covered + +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate-never_type.rs b/src/test/ui/feature-gate-never_type.rs deleted file mode 100644 index 11b9f412957e..000000000000 --- a/src/test/ui/feature-gate-never_type.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2012 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. - -// Test that ! errors when used in illegal positions with feature(never_type) disabled - -trait Foo { - type Wub; -} - -type Ma = (u32, !, i32); //~ ERROR type is experimental -type Meeshka = Vec; //~ ERROR type is experimental -type Mow = &fn(!) -> !; //~ ERROR type is experimental -type Skwoz = &mut !; //~ ERROR type is experimental - -impl Foo for Meeshka { - type Wub = !; //~ ERROR type is experimental -} - -fn main() { -} - diff --git a/src/test/ui/print_type_sizes/uninhabited.rs b/src/test/ui/print_type_sizes/uninhabited.rs index 4d0396903e55..7e8eff02c20a 100644 --- a/src/test/ui/print_type_sizes/uninhabited.rs +++ b/src/test/ui/print_type_sizes/uninhabited.rs @@ -11,7 +11,6 @@ // compile-flags: -Z print-type-sizes // must-compile-successfully -#![feature(never_type)] #![feature(start)] #[start] diff --git a/src/test/ui/reachable/expr_add.rs b/src/test/ui/reachable/expr_add.rs index dd43c58de6df..3e39b75d8c0f 100644 --- a/src/test/ui/reachable/expr_add.rs +++ b/src/test/ui/reachable/expr_add.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(never_type)] #![allow(unused_variables)] #![deny(unreachable_code)] diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr index d3e1da0e7189..f49a781ce336 100644 --- a/src/test/ui/reachable/expr_add.stderr +++ b/src/test/ui/reachable/expr_add.stderr @@ -1,11 +1,11 @@ error: unreachable expression - --> $DIR/expr_add.rs:27:13 + --> $DIR/expr_add.rs:26:13 | LL | let x = Foo + return; //~ ERROR unreachable | ^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/expr_add.rs:13:9 + --> $DIR/expr_add.rs:12:9 | LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_array.rs b/src/test/ui/reachable/expr_array.rs index 31229668796e..323a5752e220 100644 --- a/src/test/ui/reachable/expr_array.rs +++ b/src/test/ui/reachable/expr_array.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { @@ -21,7 +20,7 @@ fn a() { } fn b() { - // the `array is unreachable: + // the array is unreachable: let x: [usize; 2] = [22, return]; //~ ERROR unreachable } diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr index 3257514ea500..78ac76a6137f 100644 --- a/src/test/ui/reachable/expr_array.stderr +++ b/src/test/ui/reachable/expr_array.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_array.rs:20:34 + --> $DIR/expr_array.rs:19:34 | LL | let x: [usize; 2] = [return, 22]; //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_array.rs:25:25 + --> $DIR/expr_array.rs:24:25 | LL | let x: [usize; 2] = [22, return]; //~ ERROR unreachable | ^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_assign.rs b/src/test/ui/reachable/expr_assign.rs index e6fb46a5bac0..73083af34d97 100644 --- a/src/test/ui/reachable/expr_assign.rs +++ b/src/test/ui/reachable/expr_assign.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo() { // No error here. diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr index 15dcf2c2401d..628bfbf62171 100644 --- a/src/test/ui/reachable/expr_assign.stderr +++ b/src/test/ui/reachable/expr_assign.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_assign.rs:20:5 + --> $DIR/expr_assign.rs:19:5 | LL | x = return; //~ ERROR unreachable | ^^^^^^^^^^ @@ -11,13 +11,13 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_assign.rs:30:14 + --> $DIR/expr_assign.rs:29:14 | LL | *p = return; //~ ERROR unreachable | ^^^^^^ error: unreachable expression - --> $DIR/expr_assign.rs:36:15 + --> $DIR/expr_assign.rs:35:15 | LL | *{return; &mut i} = 22; //~ ERROR unreachable | ^^^^^^ diff --git a/src/test/ui/reachable/expr_block.rs b/src/test/ui/reachable/expr_block.rs index 57b5d3cabce6..93bce43f76d9 100644 --- a/src/test/ui/reachable/expr_block.rs +++ b/src/test/ui/reachable/expr_block.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn a() { // Here the tail expression is considered unreachable: diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr index a0cef6449f7d..5f5696aadb37 100644 --- a/src/test/ui/reachable/expr_block.stderr +++ b/src/test/ui/reachable/expr_block.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_block.rs:21:9 + --> $DIR/expr_block.rs:20:9 | LL | 22 //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable statement - --> $DIR/expr_block.rs:36:9 + --> $DIR/expr_block.rs:35:9 | LL | println!("foo"); | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_call.rs b/src/test/ui/reachable/expr_call.rs index 86b95aad9c25..2772dd429d18 100644 --- a/src/test/ui/reachable/expr_call.rs +++ b/src/test/ui/reachable/expr_call.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo(x: !, y: usize) { } diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr index 455e5ab3653d..414d29ec2a73 100644 --- a/src/test/ui/reachable/expr_call.stderr +++ b/src/test/ui/reachable/expr_call.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_call.rs:23:17 + --> $DIR/expr_call.rs:22:17 | LL | foo(return, 22); //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_call.rs:28:5 + --> $DIR/expr_call.rs:27:5 | LL | bar(return); //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_cast.rs b/src/test/ui/reachable/expr_cast.rs index 76b00c00ad98..88846b638416 100644 --- a/src/test/ui/reachable/expr_cast.rs +++ b/src/test/ui/reachable/expr_cast.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr index 8c37759aa469..458334e2af96 100644 --- a/src/test/ui/reachable/expr_cast.stderr +++ b/src/test/ui/reachable/expr_cast.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_cast.rs:20:13 + --> $DIR/expr_cast.rs:19:13 | LL | let x = {return} as !; //~ ERROR unreachable | ^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_if.rs b/src/test/ui/reachable/expr_if.rs index 2a265e772f35..d2fb1044e48b 100644 --- a/src/test/ui/reachable/expr_if.rs +++ b/src/test/ui/reachable/expr_if.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo() { if {return} { diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr index c14cdbfc2bc7..6e8afd1c5be8 100644 --- a/src/test/ui/reachable/expr_if.stderr +++ b/src/test/ui/reachable/expr_if.stderr @@ -1,5 +1,5 @@ error: unreachable statement - --> $DIR/expr_if.rs:38:5 + --> $DIR/expr_if.rs:37:5 | LL | println!("But I am."); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_loop.rs b/src/test/ui/reachable/expr_loop.rs index 3ed4b2dcf0cf..533cdac0968b 100644 --- a/src/test/ui/reachable/expr_loop.rs +++ b/src/test/ui/reachable/expr_loop.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn a() { loop { return; } diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr index 7f834567de36..a51ef293acf1 100644 --- a/src/test/ui/reachable/expr_loop.stderr +++ b/src/test/ui/reachable/expr_loop.stderr @@ -1,5 +1,5 @@ error: unreachable statement - --> $DIR/expr_loop.rs:19:5 + --> $DIR/expr_loop.rs:18:5 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(unreachable_code)] = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_loop.rs:31:5 + --> $DIR/expr_loop.rs:30:5 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | println!("I am dead."); = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_loop.rs:41:5 + --> $DIR/expr_loop.rs:40:5 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_match.rs b/src/test/ui/reachable/expr_match.rs index d2b96e51a951..193edd774357 100644 --- a/src/test/ui/reachable/expr_match.rs +++ b/src/test/ui/reachable/expr_match.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn a() { // The match is considered unreachable here, because the `return` diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr index d4cf21cef281..dfc1417f3d29 100644 --- a/src/test/ui/reachable/expr_match.stderr +++ b/src/test/ui/reachable/expr_match.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_match.rs:20:5 + --> $DIR/expr_match.rs:19:5 | LL | match {return} { } //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable statement - --> $DIR/expr_match.rs:25:5 + --> $DIR/expr_match.rs:24:5 | LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | println!("I am dead"); = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_match.rs:35:5 + --> $DIR/expr_match.rs:34:5 | LL | println!("I am dead"); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_method.rs b/src/test/ui/reachable/expr_method.rs index 8be71e464b20..7dabb3070976 100644 --- a/src/test/ui/reachable/expr_method.rs +++ b/src/test/ui/reachable/expr_method.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] struct Foo; diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr index b9348b5d4815..6d67bfcd54a7 100644 --- a/src/test/ui/reachable/expr_method.stderr +++ b/src/test/ui/reachable/expr_method.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_method.rs:26:21 + --> $DIR/expr_method.rs:25:21 | LL | Foo.foo(return, 22); //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_method.rs:31:5 + --> $DIR/expr_method.rs:30:5 | LL | Foo.bar(return); //~ ERROR unreachable | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_repeat.rs b/src/test/ui/reachable/expr_repeat.rs index 47ee2ba62b82..fd9fca413a7f 100644 --- a/src/test/ui/reachable/expr_repeat.rs +++ b/src/test/ui/reachable/expr_repeat.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr index 90cc3183c72e..36393de90b7c 100644 --- a/src/test/ui/reachable/expr_repeat.stderr +++ b/src/test/ui/reachable/expr_repeat.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_repeat.rs:20:25 + --> $DIR/expr_repeat.rs:19:25 | LL | let x: [usize; 2] = [return; 2]; //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_return.rs b/src/test/ui/reachable/expr_return.rs index fac1116dc689..9bbbe6f90998 100644 --- a/src/test/ui/reachable/expr_return.rs +++ b/src/test/ui/reachable/expr_return.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr index 3876da6541df..2dcc50944c5d 100644 --- a/src/test/ui/reachable/expr_return.stderr +++ b/src/test/ui/reachable/expr_return.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_return.rs:21:22 + --> $DIR/expr_return.rs:20:22 | LL | let x = {return {return {return;}}}; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_struct.rs b/src/test/ui/reachable/expr_struct.rs index b5acd395be62..66414f6084b8 100644 --- a/src/test/ui/reachable/expr_struct.rs +++ b/src/test/ui/reachable/expr_struct.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] struct Foo { diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr index 43985bbbb5c0..3f0ecb204798 100644 --- a/src/test/ui/reachable/expr_struct.stderr +++ b/src/test/ui/reachable/expr_struct.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_struct.rs:25:13 + --> $DIR/expr_struct.rs:24:13 | LL | let x = Foo { a: 22, b: 33, ..return }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,19 +11,19 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_struct.rs:30:33 + --> $DIR/expr_struct.rs:29:33 | LL | let x = Foo { a: return, b: 33, ..return }; //~ ERROR unreachable | ^^ error: unreachable expression - --> $DIR/expr_struct.rs:35:39 + --> $DIR/expr_struct.rs:34:39 | LL | let x = Foo { a: 22, b: return, ..return }; //~ ERROR unreachable | ^^^^^^ error: unreachable expression - --> $DIR/expr_struct.rs:40:13 + --> $DIR/expr_struct.rs:39:13 | LL | let x = Foo { a: 22, b: return }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_tup.rs b/src/test/ui/reachable/expr_tup.rs index 089020bf3853..e2c100902489 100644 --- a/src/test/ui/reachable/expr_tup.rs +++ b/src/test/ui/reachable/expr_tup.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr index ff9aa666d8e3..d372373ced0f 100644 --- a/src/test/ui/reachable/expr_tup.stderr +++ b/src/test/ui/reachable/expr_tup.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_tup.rs:20:38 + --> $DIR/expr_tup.rs:19:38 | LL | let x: (usize, usize) = (return, 2); //~ ERROR unreachable | ^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: unreachable expression - --> $DIR/expr_tup.rs:25:29 + --> $DIR/expr_tup.rs:24:29 | LL | let x: (usize, usize) = (2, return); //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs index 29c59d5304f9..2381ea2ac7a1 100644 --- a/src/test/ui/reachable/expr_type.rs +++ b/src/test/ui/reachable/expr_type.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] #![feature(type_ascription)] fn a() { diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr index d6b9f75edf10..9b165d6b3ee1 100644 --- a/src/test/ui/reachable/expr_type.stderr +++ b/src/test/ui/reachable/expr_type.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_type.rs:20:13 + --> $DIR/expr_type.rs:19:13 | LL | let x = {return}: !; //~ ERROR unreachable | ^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs index ad12cb876fe9..524784934c7e 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -13,7 +13,6 @@ #![allow(dead_code)] #![deny(unreachable_code)] #![deny(coerce_never)] -#![feature(never_type)] fn foo() { let x: ! = ! { return; 22 }; //~ ERROR unreachable diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index b09721e59570..1239701cabd2 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,5 +1,5 @@ error: unreachable expression - --> $DIR/expr_unary.rs:19:28 + --> $DIR/expr_unary.rs:18:28 | LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^ @@ -11,7 +11,7 @@ LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ error: cannot coerce `{integer}` to ! - --> $DIR/expr_unary.rs:19:28 + --> $DIR/expr_unary.rs:18:28 | LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^ @@ -25,7 +25,7 @@ LL | #![deny(coerce_never)] = note: for more information, see issue #46325 error[E0600]: cannot apply unary operator `!` to type `!` - --> $DIR/expr_unary.rs:19:16 + --> $DIR/expr_unary.rs:18:16 | LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/reachable/expr_while.rs b/src/test/ui/reachable/expr_while.rs index 7dcd609fbc8f..79fa69a9289b 100644 --- a/src/test/ui/reachable/expr_while.rs +++ b/src/test/ui/reachable/expr_while.rs @@ -12,7 +12,6 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![feature(never_type)] fn foo() { while {return} { diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr index cd0939066151..90c35bfaa7ac 100644 --- a/src/test/ui/reachable/expr_while.stderr +++ b/src/test/ui/reachable/expr_while.stderr @@ -1,5 +1,5 @@ error: unreachable statement - --> $DIR/expr_while.rs:19:9 + --> $DIR/expr_while.rs:18:9 | LL | println!("Hello, world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -12,7 +12,7 @@ LL | #![deny(unreachable_code)] = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_while.rs:33:9 + --> $DIR/expr_while.rs:32:9 | LL | println!("I am dead."); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | println!("I am dead."); = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: unreachable statement - --> $DIR/expr_while.rs:35:5 + --> $DIR/expr_while.rs:34:5 | LL | println!("I am, too."); | ^^^^^^^^^^^^^^^^^^^^^^^ From 32ddb30715f73498477262c992d1152cf10ca631 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sun, 21 Jan 2018 18:30:04 +0800 Subject: [PATCH 177/830] Fix version number --- src/libcore/cmp.rs | 8 ++++---- src/libcore/fmt/mod.rs | 4 ++-- src/libstd/error.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index fdb9946469b4..3923b652afcd 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -882,24 +882,24 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } - #[stable(feature = "never_type", since = "1.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[stable(feature = "never_type", since = "1.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl Eq for ! {} - #[stable(feature = "never_type", since = "1.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option { *self } } - #[stable(feature = "never_type", since = "1.24.0")] + #[stable(feature = "never_type", since = "1.25.0")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3706da7c5218..40b88ded27d0 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1579,14 +1579,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[stable(feature = "never_type", since = "1.24.0")] +#[stable(feature = "never_type", since = "1.25.0")] impl Debug for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self } } -#[stable(feature = "never_type", since = "1.24.0")] +#[stable(feature = "never_type", since = "1.25.0")] impl Display for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 347b82244109..1743dfbfb7b0 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -234,7 +234,7 @@ impl<'a> From> for Box { } } -#[stable(feature = "never_type", since = "1.24.0")] +#[stable(feature = "never_type", since = "1.25.0")] impl Error for ! { fn description(&self) -> &str { *self } } From 59688e119e1b9c2506fa9173728ae88eb196bf5e Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Feb 2018 15:23:04 +0800 Subject: [PATCH 178/830] Make coerce_never lint an error Remove the coerce_never lint and make the behaviour an error. --- src/librustc/lint/builtin.rs | 7 ---- src/librustc_lint/lib.rs | 5 --- src/librustc_typeck/check/cast.rs | 8 ++--- src/librustc_typeck/check/coercion.rs | 19 +--------- src/librustc_typeck/check/demand.rs | 2 +- src/librustc_typeck/check/mod.rs | 3 +- src/test/compile-fail/coerce-to-bang-cast.rs | 4 +-- src/test/compile-fail/coerce-to-bang.rs | 14 ++------ .../compile-fail/diverging-fn-tail-35849.rs | 4 +-- src/test/run-pass/diverging-fn-tail-35849.rs | 18 ---------- src/test/ui/reachable/expr_unary.rs | 5 +-- src/test/ui/reachable/expr_unary.stderr | 36 ++++++------------- 12 files changed, 22 insertions(+), 103 deletions(-) delete mode 100644 src/test/run-pass/diverging-fn-tail-35849.rs diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 1795866e103b..b4ed9c269bd8 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -230,12 +230,6 @@ declare_lint! { "detect mut variables which don't need to be mutable" } -declare_lint! { - pub COERCE_NEVER, - Deny, - "detect coercion to !" -} - declare_lint! { pub SINGLE_USE_LIFETIME, Allow, @@ -310,7 +304,6 @@ impl LintPass for HardwiredLints { DEPRECATED, UNUSED_UNSAFE, UNUSED_MUT, - COERCE_NEVER, SINGLE_USE_LIFETIME, TYVAR_BEHIND_RAW_POINTER, ELIDED_LIFETIME_IN_PATH, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index cbc1d7c38d61..010678ecfb5d 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -270,11 +270,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #46205 ", epoch: None, }, - FutureIncompatibleInfo { - id: LintId::of(COERCE_NEVER), - reference: "issue #46325 ", - epoch: None, - }, FutureIncompatibleInfo { id: LintId::of(TYVAR_BEHIND_RAW_POINTER), reference: "issue #46906 ", diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index c2c113f2da9f..e4bad8349ea2 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -38,7 +38,7 @@ //! expression, `e as U2` is not necessarily so (in fact it will only be valid if //! `U1` coerces to `U2`). -use super::{Diverges, FnCtxt}; +use super::FnCtxt; use errors::DiagnosticBuilder; use hir::def_id::DefId; @@ -59,7 +59,6 @@ use util::common::ErrorReported; pub struct CastCheck<'tcx> { expr: &'tcx hir::Expr, expr_ty: Ty<'tcx>, - expr_diverges: Diverges, cast_ty: Ty<'tcx>, cast_span: Span, span: Span, @@ -183,7 +182,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { pub fn new(fcx: &FnCtxt<'a, 'gcx, 'tcx>, expr: &'tcx hir::Expr, expr_ty: Ty<'tcx>, - expr_diverges: Diverges, cast_ty: Ty<'tcx>, cast_span: Span, span: Span) @@ -191,7 +189,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { let check = CastCheck { expr, expr_ty, - expr_diverges, cast_ty, cast_span, span, @@ -437,7 +434,6 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { let f = self.expr_ty.fn_sig(fcx.tcx); let res = fcx.try_coerce(self.expr, self.expr_ty, - self.expr_diverges, fcx.tcx.mk_fn_ptr(f)); if !res.is_ok() { return Err(CastError::NonScalar); @@ -620,7 +616,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool { - fcx.try_coerce(self.expr, self.expr_ty, self.expr_diverges, self.cast_ty).is_ok() + fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty).is_ok() } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index abb0acd699cb..144ca37f2c69 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -66,7 +66,6 @@ use rustc::hir; use rustc::hir::def_id::DefId; use rustc::infer::{Coercion, InferResult, InferOk}; use rustc::infer::type_variable::TypeVariableOrigin; -use rustc::lint; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability}; use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts}; @@ -752,27 +751,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn try_coerce(&self, expr: &hir::Expr, expr_ty: Ty<'tcx>, - expr_diverges: Diverges, target: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { let source = self.resolve_type_vars_with_obligations(expr_ty); debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target); - // Special-ish case: we can coerce any type `T` into the `!` - // type, but only if the source expression diverges. - if target.is_never() && expr_diverges.always() { - debug!("permit coercion to `!` because expr diverges"); - if self.can_eq(self.param_env, source, target).is_err() { - self.tcx.lint_node( - lint::builtin::COERCE_NEVER, - expr.id, - expr.span, - &format!("cannot coerce `{}` to !", source) - ); - return Ok(target); - } - } - let cause = self.cause(expr.span, ObligationCauseCode::ExprAssignable); let coerce = Coerce::new(self, cause); let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?; @@ -1123,7 +1106,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> if self.pushed == 0 { // Special-case the first expression we are coercing. // To be honest, I'm not entirely sure why we do this. - fcx.try_coerce(expression, expression_ty, expression_diverges, self.expected_ty) + fcx.try_coerce(expression, expression_ty, self.expected_ty) } else { match self.expressions { Expressions::Dynamic(ref exprs) => diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index d2702d0810ed..634a7ee56991 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { -> (Ty<'tcx>, Option>) { let expected = self.resolve_type_vars_with_obligations(expected); - let e = match self.try_coerce(expr, checked_ty, self.diverges.get(), expected) { + let e = match self.try_coerce(expr, checked_ty, expected) { Ok(ty) => return (ty, None), Err(e) => e }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ec6383bf9a52..80d95ea86e4b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3944,7 +3944,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let t_cast = self.resolve_type_vars_if_possible(&t_cast); let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast)); let t_cast = self.resolve_type_vars_if_possible(&t_cast); - let diverges = self.diverges.get(); // Eagerly check for some obvious errors. if t_expr.references_error() || t_cast.references_error() { @@ -3952,7 +3951,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { // Defer other checks until we're done type checking. let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); - match cast::CastCheck::new(self, e, t_expr, diverges, t_cast, t.span, expr.span) { + match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) { Ok(cast_check) => { deferred_cast_checks.push(cast_check); t_cast diff --git a/src/test/compile-fail/coerce-to-bang-cast.rs b/src/test/compile-fail/coerce-to-bang-cast.rs index 8b3a9ed092d9..5efb4dadc64b 100644 --- a/src/test/compile-fail/coerce-to-bang-cast.rs +++ b/src/test/compile-fail/coerce-to-bang-cast.rs @@ -10,11 +10,9 @@ fn foo(x: usize, y: !, z: usize) { } -#[deny(coerce_never)] fn cast_a() { let y = {return; 22} as !; - //~^ ERROR cannot coerce `i32` to ! - //~| hard error + //~^ ERROR non-primitive cast } fn cast_b() { diff --git a/src/test/compile-fail/coerce-to-bang.rs b/src/test/compile-fail/coerce-to-bang.rs index b365f142a9b7..15049232a4d3 100644 --- a/src/test/compile-fail/coerce-to-bang.rs +++ b/src/test/compile-fail/coerce-to-bang.rs @@ -8,17 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![deny(coerce_never)] - fn foo(x: usize, y: !, z: usize) { } fn call_foo_a() { - // FIXME(#40800) -- accepted because divergence happens **before** - // the coercion to `!`, but within same expression. Not clear that - // these are the rules we want. foo(return, 22, 44); - //~^ ERROR cannot coerce `{integer}` to ! - //~| hard error + //~^ ERROR mismatched types } fn call_foo_b() { @@ -38,8 +32,7 @@ fn call_foo_d() { let b = 22; let c = 44; foo(a, b, c); // ... and hence a reference to `a` is expected to diverge. - //~^ ERROR cannot coerce `{integer}` to ! - //~| hard error + //~^ ERROR mismatched types } fn call_foo_e() { @@ -79,8 +72,7 @@ fn tuple_a() { fn tuple_b() { // Divergence happens before coercion: OK let x: (usize, !, usize) = (return, 44, 66); - //~^ ERROR cannot coerce `{integer}` to ! - //~| hard error + //~^ ERROR mismatched types } fn tuple_c() { diff --git a/src/test/compile-fail/diverging-fn-tail-35849.rs b/src/test/compile-fail/diverging-fn-tail-35849.rs index a91c000bbf71..9ef5159cb771 100644 --- a/src/test/compile-fail/diverging-fn-tail-35849.rs +++ b/src/test/compile-fail/diverging-fn-tail-35849.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[deny(coerce_never)] fn assert_sizeof() -> ! { unsafe { ::std::mem::transmute::(panic!()) - //~^ ERROR cannot coerce `[u8; 8]` to ! - //~| hard error + //~^ ERROR mismatched types } } diff --git a/src/test/run-pass/diverging-fn-tail-35849.rs b/src/test/run-pass/diverging-fn-tail-35849.rs deleted file mode 100644 index dfd99bcc9fb4..000000000000 --- a/src/test/run-pass/diverging-fn-tail-35849.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -#[allow(coerce_never)] -fn assert_sizeof() -> ! { - unsafe { - ::std::mem::transmute::(panic!()) - } -} - -fn main() { } diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs index 524784934c7e..4096865f4c67 100644 --- a/src/test/ui/reachable/expr_unary.rs +++ b/src/test/ui/reachable/expr_unary.rs @@ -12,12 +12,9 @@ #![allow(unused_assignments)] #![allow(dead_code)] #![deny(unreachable_code)] -#![deny(coerce_never)] fn foo() { - let x: ! = ! { return; 22 }; //~ ERROR unreachable - //~^ ERROR cannot coerce - //~| hard error + let x: ! = ! { return; }; //~ ERROR unreachable //~| ERROR cannot apply unary operator `!` to type `!` } diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index 1239701cabd2..e39909eee7f3 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,8 +1,14 @@ -error: unreachable expression - --> $DIR/expr_unary.rs:18:28 +error[E0600]: cannot apply unary operator `!` to type `!` + --> $DIR/expr_unary.rs:17:16 | -LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^ +17 | let x: ! = ! { return; }; //~ ERROR unreachable + | ^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/expr_unary.rs:17:16 + | +LL | let x: ! = ! { return; }; //~ ERROR unreachable + | ^^^^^^^^^^^^^ | note: lint level defined here --> $DIR/expr_unary.rs:14:9 @@ -10,26 +16,6 @@ note: lint level defined here LL | #![deny(unreachable_code)] | ^^^^^^^^^^^^^^^^ -error: cannot coerce `{integer}` to ! - --> $DIR/expr_unary.rs:18:28 - | -LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^ - | -note: lint level defined here - --> $DIR/expr_unary.rs:15:9 - | -LL | #![deny(coerce_never)] - | ^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #46325 - -error[E0600]: cannot apply unary operator `!` to type `!` - --> $DIR/expr_unary.rs:18:16 - | -LL | let x: ! = ! { return; 22 }; //~ ERROR unreachable - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0600`. From edb9d2b20dd907903d0cf70194c4c28c8d40c063 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 01:26:51 +0800 Subject: [PATCH 179/830] Fix ui test errors --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 2 +- src/test/ui/reachable/expr_unary.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 43a4adf93730..c11c9da3963c 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -1,7 +1,7 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered --> $DIR/feature-gate-exhaustive-patterns.rs:16:9 | -16 | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding +LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding | ^^^^^^ pattern `Err(_)` not covered error: aborting due to previous error diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr index e39909eee7f3..165eccd42396 100644 --- a/src/test/ui/reachable/expr_unary.stderr +++ b/src/test/ui/reachable/expr_unary.stderr @@ -1,7 +1,7 @@ error[E0600]: cannot apply unary operator `!` to type `!` --> $DIR/expr_unary.rs:17:16 | -17 | let x: ! = ! { return; }; //~ ERROR unreachable +LL | let x: ! = ! { return; }; //~ ERROR unreachable | ^^^^^^^^^^^^^ error: unreachable expression From a704624ef5830541acb9912146fa28305b9a920c Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 01:41:10 +0800 Subject: [PATCH 180/830] change never_type stabilisation version --- src/libcore/cmp.rs | 8 ++++---- src/libcore/fmt/mod.rs | 4 ++-- src/libstd/error.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 3923b652afcd..67445daa4360 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -882,24 +882,24 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } - #[stable(feature = "never_type", since = "1.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } } - #[stable(feature = "never_type", since = "1.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl Eq for ! {} - #[stable(feature = "never_type", since = "1.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option { *self } } - #[stable(feature = "never_type", since = "1.25.0")] + #[stable(feature = "never_type", since = "1.26.0")] impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 40b88ded27d0..2456b5b66547 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1579,14 +1579,14 @@ macro_rules! fmt_refs { fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp } -#[stable(feature = "never_type", since = "1.25.0")] +#[stable(feature = "never_type", since = "1.26.0")] impl Debug for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self } } -#[stable(feature = "never_type", since = "1.25.0")] +#[stable(feature = "never_type", since = "1.26.0")] impl Display for ! { fn fmt(&self, _: &mut Formatter) -> Result { *self diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 1743dfbfb7b0..f8dbe193fed2 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -234,7 +234,7 @@ impl<'a> From> for Box { } } -#[stable(feature = "never_type", since = "1.25.0")] +#[stable(feature = "never_type", since = "1.26.0")] impl Error for ! { fn description(&self) -> &str { *self } } From 04cad569159006492f8d3c82bf2a07ced75363db Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 11:41:38 +0800 Subject: [PATCH 181/830] really fix ui test errors --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index c11c9da3963c..864c57e033f9 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -4,5 +4,4 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding | ^^^^^^ pattern `Err(_)` not covered -error: aborting due to previous error From b4f1081af1fa0ef9b579f8a9e469aa9803057c68 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 1 Mar 2018 13:54:20 +0800 Subject: [PATCH 182/830] really fix ui test errors for real --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 864c57e033f9..8bf8641ab68a 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -4,4 +4,7 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding | ^^^^^^ pattern `Err(_)` not covered +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0005" From 5a6b7812665f26e2483075ce2cbde92af822b2e4 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Sat, 3 Mar 2018 13:12:50 +0800 Subject: [PATCH 183/830] really actually fix ui test error for real --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 8bf8641ab68a..51fdac064cea 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -7,4 +7,3 @@ LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding error: aborting due to previous error If you want more information on this error, try using "rustc --explain E0005" - From 5b32211e620a47b2c14dd313f0c3aa91e78f7361 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Mon, 12 Mar 2018 12:15:06 +0800 Subject: [PATCH 184/830] Add note about fallback to `!: !Trait` error --- src/librustc/infer/outlives/bounds.rs | 2 +- src/librustc/traits/error_reporting.rs | 45 ++++++++++++++++--- src/librustc/traits/mod.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 4 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/mod.rs | 27 ++++++----- src/librustc_typeck/check/op.rs | 2 +- src/librustc_typeck/coherence/builtin.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/test/compile-fail/defaulted-never-note.rs | 41 +++++++++++++++++ 12 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 src/test/compile-fail/defaulted-never-note.rs diff --git a/src/librustc/infer/outlives/bounds.rs b/src/librustc/infer/outlives/bounds.rs index abb35d24d795..8bb3f4158ff5 100644 --- a/src/librustc/infer/outlives/bounds.rs +++ b/src/librustc/infer/outlives/bounds.rs @@ -151,7 +151,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { // get solved *here*. match fulfill_cx.select_all_or_error(self) { Ok(()) => (), - Err(errors) => self.report_fulfillment_errors(&errors, None), + Err(errors) => self.report_fulfillment_errors(&errors, None, false), } implied_bounds diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 5d994a0e444c..b19935b8c4fb 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -47,7 +47,8 @@ use syntax_pos::{DUMMY_SP, Span}; impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn report_fulfillment_errors(&self, errors: &Vec>, - body_id: Option) { + body_id: Option, + fallback_has_occurred: bool) { #[derive(Debug)] struct ErrorDescriptor<'tcx> { predicate: ty::Predicate<'tcx>, @@ -107,7 +108,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { for (error, suppressed) in errors.iter().zip(is_suppressed) { if !suppressed { - self.report_fulfillment_error(error, body_id); + self.report_fulfillment_error(error, body_id, fallback_has_occurred); } } } @@ -151,11 +152,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>, - body_id: Option) { + body_id: Option, + fallback_has_occurred: bool) { debug!("report_fulfillment_errors({:?})", error); match error.code { FulfillmentErrorCode::CodeSelectionError(ref e) => { - self.report_selection_error(&error.obligation, e); + self.report_selection_error(&error.obligation, e, fallback_has_occurred); } FulfillmentErrorCode::CodeProjectionError(ref e) => { self.report_projection_error(&error.obligation, e); @@ -533,9 +535,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn report_selection_error(&self, obligation: &PredicateObligation<'tcx>, - error: &SelectionError<'tcx>) + error: &SelectionError<'tcx>, + fallback_has_occurred: bool) { let span = obligation.cause.span; + let _ = fallback_has_occurred; let mut err = match *error { SelectionError::Unimplemented => { @@ -619,6 +623,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.report_similar_impl_candidates(impl_candidates, &mut err); } + // If this error is due to `!: !Trait` but `(): Trait` then add a note + // about the fallback behaviour change. + if trait_predicate.skip_binder().self_ty().is_never() { + let predicate = trait_predicate.map_bound(|mut trait_pred| { + { + let trait_ref = &mut trait_pred.trait_ref; + let never_substs = trait_ref.substs; + let mut unit_substs = Vec::with_capacity(never_substs.len()); + unit_substs.push(self.tcx.mk_nil().into()); + unit_substs.extend(&never_substs[1..]); + trait_ref.substs = self.tcx.intern_substs(&unit_substs); + } + trait_pred + }); + let unit_obligation = Obligation { + cause: obligation.cause.clone(), + param_env: obligation.param_env, + recursion_depth: obligation.recursion_depth, + predicate, + }; + let mut selcx = SelectionContext::new(self); + if let Ok(Some(..)) = selcx.select(&unit_obligation) { + err.note("the trait is implemented for `()`. \ + Possibly this error has been caused by changes to \ + Rust's type-inference algorithm \ + (see: https://github.com/rust-lang/rust/issues/48950 \ + for more info). Consider whether you meant to use the \ + type `()` here instead."); + } + } + err } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index a2a5aa246cf7..bd8f99780f9f 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -580,7 +580,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ) { Ok(predicates) => predicates, Err(errors) => { - infcx.report_fulfillment_errors(&errors, None); + infcx.report_fulfillment_errors(&errors, None, false); // An unnormalized env is better than nothing. return elaborated_env; } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 94446a98e63f..59a872a23b06 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -1246,7 +1246,7 @@ impl MirPass for QualifyAndPromoteConstants { tcx.require_lang_item(lang_items::SyncTraitLangItem), cause); if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(&err, None); + infcx.report_fulfillment_errors(&err, None, false); } }); } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 144ca37f2c69..269ee49f38e7 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -571,7 +571,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // Object safety violations or miscellaneous. Err(err) => { - self.report_selection_error(&obligation, &err); + self.report_selection_error(&obligation, &err, false); // Treat this like an obligation and follow through // with the unsizing - the lack of a coercion should // be silent, as it causes a type mismatch later. diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index b6459b624104..60ac31ac8eba 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -334,7 +334,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Check that all obligations are satisfied by the implementation's // version. if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(errors, None); + infcx.report_fulfillment_errors(errors, None, false); return Err(ErrorReported); } @@ -839,7 +839,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Check that all obligations are satisfied by the implementation's // version. if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(errors, None); + infcx.report_fulfillment_errors(errors, None, false); return; } diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 67c9832cbf9f..596381d7ea67 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -112,7 +112,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>( if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) { // this could be reached when we get lazy normalization - infcx.report_fulfillment_errors(errors, None); + infcx.report_fulfillment_errors(errors, None, false); return Err(ErrorReported); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 80d95ea86e4b..18de8d1bee74 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -873,11 +873,12 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; // All type checking constraints were added, try to fallback unsolved variables. - fcx.select_obligations_where_possible(); + fcx.select_obligations_where_possible(false); + let mut fallback_has_occurred = false; for ty in &fcx.unsolved_variables() { - fcx.fallback_if_possible(ty); + fallback_has_occurred |= fcx.fallback_if_possible(ty); } - fcx.select_obligations_where_possible(); + fcx.select_obligations_where_possible(fallback_has_occurred); // Even though coercion casts provide type hints, we check casts after fallback for // backwards compatibility. This makes fallback a stronger type hint than a cast coercion. @@ -1837,7 +1838,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // possible. This can help substantially when there are // indirect dependencies that don't seem worth tracking // precisely. - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); ty = self.resolve_type_vars_if_possible(&ty); debug!("resolve_type_vars_with_obligations: ty={:?}", ty); @@ -2154,7 +2155,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn resolve_generator_interiors(&self, def_id: DefId) { let mut generators = self.deferred_generator_interiors.borrow_mut(); for (body_id, interior) in generators.drain(..) { - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); generator_interior::resolve_interior(self, def_id, body_id, interior); } } @@ -2164,7 +2165,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // unconstrained floats with f64. // Fallback becomes very dubious if we have encountered type-checking errors. // In that case, fallback to TyError. - fn fallback_if_possible(&self, ty: Ty<'tcx>) { + // The return value indicates whether fallback has occured. + fn fallback_if_possible(&self, ty: Ty<'tcx>) -> bool { use rustc::ty::error::UnconstrainedNumeric::Neither; use rustc::ty::error::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat}; @@ -2174,24 +2176,27 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { UnconstrainedInt => self.tcx.types.i32, UnconstrainedFloat => self.tcx.types.f64, Neither if self.type_var_diverges(ty) => self.tcx.types.never, - Neither => return + Neither => return false, }; debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback); self.demand_eqtype(syntax_pos::DUMMY_SP, ty, fallback); + true } fn select_all_obligations_or_error(&self) { debug!("select_all_obligations_or_error"); if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) { - self.report_fulfillment_errors(&errors, self.inh.body_id); + self.report_fulfillment_errors(&errors, self.inh.body_id, false); } } /// Select as many obligations as we can at present. - fn select_obligations_where_possible(&self) { + fn select_obligations_where_possible(&self, fallback_has_occurred: bool) { match self.fulfillment_cx.borrow_mut().select_where_possible(self) { Ok(()) => { } - Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); } + Err(errors) => { + self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred); + }, } } @@ -2595,7 +2600,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // an "opportunistic" vtable resolution of any trait bounds on // the call. This helps coercions. if check_closures { - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); } // For variadic functions, we don't have a declared type for all of diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 47a229cbd3b5..eae692f4cdad 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -479,7 +479,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match method { Some(ok) => { let method = self.register_infer_ok_obligations(ok); - self.select_obligations_where_possible(); + self.select_obligations_where_possible(false); Ok(method) } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 2f1c42bbef8c..9493c36fe95a 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -386,7 +386,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Check that all transitive obligations are satisfied. if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) { - infcx.report_fulfillment_errors(&errors, None); + infcx.report_fulfillment_errors(&errors, None, false); } // Finally, resolve all regions. diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index a97c6e84eab5..964c0021133a 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -174,7 +174,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match fulfill_cx.select_all_or_error(infcx) { Ok(()) => true, Err(errors) => { - infcx.report_fulfillment_errors(&errors, None); + infcx.report_fulfillment_errors(&errors, None, false); false } } diff --git a/src/test/compile-fail/defaulted-never-note.rs b/src/test/compile-fail/defaulted-never-note.rs new file mode 100644 index 000000000000..798544f16493 --- /dev/null +++ b/src/test/compile-fail/defaulted-never-note.rs @@ -0,0 +1,41 @@ +// 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. + +#![allow(unused)] + +trait Deserialize: Sized { + fn deserialize() -> Result; +} + +impl Deserialize for () { + fn deserialize() -> Result<(), String> { + Ok(()) + } +} + +trait ImplementedForUnitButNotNever {} + +impl ImplementedForUnitButNotNever for () {} + +fn foo(_t: T) {} +//~^ NOTE required by `foo` + +fn smeg() { + let _x = return; + foo(_x); + //~^ ERROR the trait bound + //~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented + //~| NOTE the trait is implemented for `()` +} + +fn main() { + smeg(); +} + From 00a52a2be36fd80e8430a524e8c0dad7b249af41 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 12:03:33 +0800 Subject: [PATCH 185/830] Fix fallback note --- src/librustc/traits/error_reporting.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index b19935b8c4fb..206a4bf66892 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -539,7 +539,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fallback_has_occurred: bool) { let span = obligation.cause.span; - let _ = fallback_has_occurred; let mut err = match *error { SelectionError::Unimplemented => { @@ -623,9 +622,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.report_similar_impl_candidates(impl_candidates, &mut err); } - // If this error is due to `!: !Trait` but `(): Trait` then add a note - // about the fallback behaviour change. - if trait_predicate.skip_binder().self_ty().is_never() { + // If this error is due to `!: Trait` not implemented but `(): Trait` is + // implemented, and fallback has occured, then it could be due to a + // variable that used to fallback to `()` now falling back to `!`. Issue a + // note informing about the change in behaviour. + if trait_predicate.skip_binder().self_ty().is_never() + && fallback_has_occurred + { let predicate = trait_predicate.map_bound(|mut trait_pred| { { let trait_ref = &mut trait_pred.trait_ref; @@ -638,13 +641,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_pred }); let unit_obligation = Obligation { - cause: obligation.cause.clone(), - param_env: obligation.param_env, - recursion_depth: obligation.recursion_depth, - predicate, + predicate: ty::Predicate::Trait(predicate), + .. obligation.clone() }; let mut selcx = SelectionContext::new(self); - if let Ok(Some(..)) = selcx.select(&unit_obligation) { + if selcx.evaluate_obligation(&unit_obligation) { err.note("the trait is implemented for `()`. \ Possibly this error has been caused by changes to \ Rust's type-inference algorithm \ From 81ae93e3390aa686c09c5ae3a2e25274ad1fdab2 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 12:04:29 +0800 Subject: [PATCH 186/830] register removed lints --- src/librustc_lint/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 010678ecfb5d..8b86c9054895 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -306,4 +306,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "converted into hard error, see https://github.com/rust-lang/rust/issues/36892"); store.register_removed("extra_requirement_in_impl", "converted into hard error, see https://github.com/rust-lang/rust/issues/37166"); + store.register_removed("coerce_never", + "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); + store.register_removed("resolve_trait_on_defaulted_unit", + "converted into hard error, see https://github.com/rust-lang/rust/issues/48950"); } From b1526ca384028bb1ca52dc58eb4d47f930afae62 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 12:36:58 +0800 Subject: [PATCH 187/830] Fixes after rebase --- src/librustc/infer/canonical.rs | 8 +--- src/librustc/traits/query/dropck_outlives.rs | 2 +- src/librustc_traits/dropck_outlives.rs | 2 +- src/test/ui/feature-gate-never_type.stderr | 43 -------------------- 4 files changed, 3 insertions(+), 52 deletions(-) delete mode 100644 src/test/ui/feature-gate-never_type.stderr diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 9519baa3ff7b..4e0cf59e8a7f 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -609,12 +609,6 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> bug!("encountered a canonical type during canonicalization") } - // Replace a `()` that "would've fallen back" to `!` with just `()`. - ty::TyTuple(ref tys, true) => { - assert!(tys.is_empty()); - self.tcx().mk_nil() - } - ty::TyClosure(..) | ty::TyGenerator(..) | ty::TyGeneratorWitness(..) @@ -634,7 +628,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> | ty::TyFnPtr(_) | ty::TyDynamic(..) | ty::TyNever - | ty::TyTuple(_, false) + | ty::TyTuple(..) | ty::TyProjection(..) | ty::TyForeign(..) | ty::TyParam(..) diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 0fe4daa36ed4..1caab6fd89ef 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -236,7 +236,7 @@ fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>) // (T1..Tn) and closures have same properties as T1..Tn -- // check if *any* of those are trivial. - ty::TyTuple(ref tys, _) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)), + ty::TyTuple(ref tys) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)), ty::TyClosure(def_id, ref substs) => substs .upvar_tys(def_id, tcx) .all(|t| trivial_dropck_outlives(tcx, t)), diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 2274f3942bdb..2a8cfe5cc06b 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -184,7 +184,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ety) } - ty::TyTuple(tys, _) => tys.iter() + ty::TyTuple(tys) => tys.iter() .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty)) .collect(), diff --git a/src/test/ui/feature-gate-never_type.stderr b/src/test/ui/feature-gate-never_type.stderr deleted file mode 100644 index 187be6d82913..000000000000 --- a/src/test/ui/feature-gate-never_type.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0658]: The `!` type is experimental (see issue #35121) - --> $DIR/feature-gate-never_type.rs:17:17 - | -LL | type Ma = (u32, !, i32); //~ ERROR type is experimental - | ^ - | - = help: add #![feature(never_type)] to the crate attributes to enable - -error[E0658]: The `!` type is experimental (see issue #35121) - --> $DIR/feature-gate-never_type.rs:18:20 - | -LL | type Meeshka = Vec; //~ ERROR type is experimental - | ^ - | - = help: add #![feature(never_type)] to the crate attributes to enable - -error[E0658]: The `!` type is experimental (see issue #35121) - --> $DIR/feature-gate-never_type.rs:19:16 - | -LL | type Mow = &fn(!) -> !; //~ ERROR type is experimental - | ^ - | - = help: add #![feature(never_type)] to the crate attributes to enable - -error[E0658]: The `!` type is experimental (see issue #35121) - --> $DIR/feature-gate-never_type.rs:20:19 - | -LL | type Skwoz = &mut !; //~ ERROR type is experimental - | ^ - | - = help: add #![feature(never_type)] to the crate attributes to enable - -error[E0658]: The `!` type is experimental (see issue #35121) - --> $DIR/feature-gate-never_type.rs:23:16 - | -LL | type Wub = !; //~ ERROR type is experimental - | ^ - | - = help: add #![feature(never_type)] to the crate attributes to enable - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0658`. From a8a0c691914b72d1ca54057914b4cee2bd097ae3 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Wed, 14 Mar 2018 13:31:02 +0800 Subject: [PATCH 188/830] fix ui test error again --- src/test/ui/feature-gate-exhaustive-patterns.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gate-exhaustive-patterns.stderr index 51fdac064cea..4afe5b5d5e01 100644 --- a/src/test/ui/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gate-exhaustive-patterns.stderr @@ -6,4 +6,4 @@ LL | let Ok(_x) = foo(); //~ ERROR refutable pattern in local binding error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0005" +For more information about this error, try `rustc --explain E0005`. From 4a254c00506abdbb660e9c71d34b5b836b86da8d Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Wed, 14 Mar 2018 18:11:42 +0900 Subject: [PATCH 189/830] Escape stringified expression Payload of `Literal` token must be escaped. Also print printable non-ASCII characters. --- src/libsyntax_ext/assert.rs | 68 +++++++++++++++++++++++++++--- src/libsyntax_ext/lib.rs | 1 + src/test/run-pass/assert-escape.rs | 13 ++++++ 3 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/assert-escape.rs diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index 7962ec26c37a..8b29e6adeb9e 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -15,7 +15,7 @@ use syntax::ext::build::AstBuilder; use syntax::parse::token; use syntax::print::pprust; use syntax::tokenstream::{TokenStream, TokenTree}; -use syntax_pos::Span; +use syntax_pos::{Span, DUMMY_SP}; pub fn expand_assert<'cx>( cx: &'cx mut ExtCtxt, @@ -41,10 +41,18 @@ pub fn expand_assert<'cx>( tts: if let Some(ts) = custom_msg_args { ts.into() } else { - let panic_str = format!("assertion failed: {}", pprust::expr_to_string(&cond_expr)); - TokenStream::from(token::Literal( - token::Lit::Str_(Name::intern(&panic_str)), - None, + // `expr_to_string` escapes the string literals with `.escape_default()` + // which escapes all non-ASCII characters with `\u`. + let escaped_expr = escape_format_string(&unescape_printable_unicode( + &pprust::expr_to_string(&cond_expr), + )); + + TokenStream::from(TokenTree::Token( + DUMMY_SP, + token::Literal( + token::Lit::Str_(Name::intern(&format!("assertion failed: {}", escaped_expr))), + None, + ), )).into() }, }; @@ -62,3 +70,53 @@ pub fn expand_assert<'cx>( ); MacEager::expr(if_expr) } + +/// Escapes a string for use as a formatting string. +fn escape_format_string(s: &str) -> String { + let mut res = String::with_capacity(s.len()); + for c in s.chars() { + res.extend(c.escape_debug()); + match c { + '{' | '}' => res.push(c), + _ => {} + } + } + res +} + +#[test] +fn test_escape_format_string() { + assert!(escape_format_string(r"foo{}\") == r"foo{{}}\\"); +} + +/// Unescapes the escaped unicodes (`\u{...}`) that are printable. +fn unescape_printable_unicode(mut s: &str) -> String { + use std::{char, u32}; + + let mut res = String::with_capacity(s.len()); + + loop { + if let Some(start) = s.find(r"\u{") { + res.push_str(&s[0..start]); + s = &s[start..]; + s.find('}') + .and_then(|end| { + let v = u32::from_str_radix(&s[3..end], 16).ok()?; + let c = char::from_u32(v)?; + // Escape unprintable characters. + res.extend(c.escape_debug()); + s = &s[end + 1..]; + Some(()) + }) + .expect("lexer should have rejected invalid escape sequences"); + } else { + res.push_str(s); + return res; + } + } +} + +#[test] +fn test_unescape_printable_unicode() { + assert!(unescape_printable_unicode(r"\u{2603}\n\u{0}") == r"☃\n\u{0}"); +} diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index a01878530b2a..1a0d22a82c4c 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -17,6 +17,7 @@ #![feature(proc_macro_internals)] #![feature(decl_macro)] +#![feature(str_escape)] extern crate fmt_macros; #[macro_use] diff --git a/src/test/run-pass/assert-escape.rs b/src/test/run-pass/assert-escape.rs new file mode 100644 index 000000000000..d340806c3577 --- /dev/null +++ b/src/test/run-pass/assert-escape.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + assert!(r#"☃\backslash"#.contains("\\")); +} From 12ac032c72aed9cc7a10d057fbdd5b5f50f2b7c8 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 11 Mar 2018 00:18:05 +0300 Subject: [PATCH 190/830] Implement import renaming with `_` (RFC 2166) --- src/libsyntax/feature_gate.rs | 18 +++++ src/libsyntax/parse/parser.rs | 6 +- .../ui/feature-gate-underscore-imports.rs | 14 ++++ .../ui/feature-gate-underscore-imports.stderr | 19 ++++++ .../ui/rfc-2166-underscore-imports/basic.rs | 67 +++++++++++++++++++ .../rfc-2166-underscore-imports/basic.stderr | 30 +++++++++ 6 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/feature-gate-underscore-imports.rs create mode 100644 src/test/ui/feature-gate-underscore-imports.stderr create mode 100644 src/test/ui/rfc-2166-underscore-imports/basic.rs create mode 100644 src/test/ui/rfc-2166-underscore-imports/basic.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ec9a15d9f2b4..61fa78b1d575 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -455,6 +455,9 @@ declare_features! ( // Parentheses in patterns (active, pattern_parentheses, "1.26.0", None, None), + + // `use path as _;` and `extern crate c as _;` + (active, underscore_imports, "1.26.0", Some(48216), None), ); declare_features! ( @@ -1436,9 +1439,24 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } + fn visit_use_tree(&mut self, use_tree: &'a ast::UseTree, id: NodeId, _nested: bool) { + if let ast::UseTreeKind::Simple(ident) = use_tree.kind { + if ident.name == "_" { + gate_feature_post!(&self, underscore_imports, use_tree.span, + "renaming imports with `_` is unstable"); + } + } + + visit::walk_use_tree(self, use_tree, id); + } + fn visit_item(&mut self, i: &'a ast::Item) { match i.node { ast::ItemKind::ExternCrate(_) => { + if i.ident.name == "_" { + gate_feature_post!(&self, underscore_imports, i.span, + "renaming extern crates with `_` is unstable"); + } if let Some(attr) = attr::find_by_name(&i.attrs[..], "macro_reexport") { gate_feature_post!(&self, macro_reexport, attr.span, "macros re-exports are experimental \ diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bd0ca0e67048..2506a7f72d22 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7040,7 +7040,11 @@ impl<'a> Parser<'a> { fn parse_rename(&mut self) -> PResult<'a, Option> { if self.eat_keyword(keywords::As) { - self.parse_ident().map(Some) + if self.eat(&token::Underscore) { + Ok(Some(Ident::with_empty_ctxt(Symbol::gensym("_")))) + } else { + self.parse_ident().map(Some) + } } else { Ok(None) } diff --git a/src/test/ui/feature-gate-underscore-imports.rs b/src/test/ui/feature-gate-underscore-imports.rs new file mode 100644 index 000000000000..ceb8afe124a8 --- /dev/null +++ b/src/test/ui/feature-gate-underscore-imports.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate std as _; //~ ERROR renaming extern crates with `_` is unstable +use std::vec as _; //~ ERROR renaming imports with `_` is unstable + +fn main() {} diff --git a/src/test/ui/feature-gate-underscore-imports.stderr b/src/test/ui/feature-gate-underscore-imports.stderr new file mode 100644 index 000000000000..2eea95260d5e --- /dev/null +++ b/src/test/ui/feature-gate-underscore-imports.stderr @@ -0,0 +1,19 @@ +error[E0658]: renaming extern crates with `_` is unstable (see issue #48216) + --> $DIR/feature-gate-underscore-imports.rs:11:1 + | +LL | extern crate std as _; //~ ERROR renaming extern crates with `_` is unstable + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(underscore_imports)] to the crate attributes to enable + +error[E0658]: renaming imports with `_` is unstable (see issue #48216) + --> $DIR/feature-gate-underscore-imports.rs:12:5 + | +LL | use std::vec as _; //~ ERROR renaming imports with `_` is unstable + | ^^^^^^^^^^^^^ + | + = help: add #![feature(underscore_imports)] to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/rfc-2166-underscore-imports/basic.rs new file mode 100644 index 000000000000..06651a71d0c0 --- /dev/null +++ b/src/test/ui/rfc-2166-underscore-imports/basic.rs @@ -0,0 +1,67 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully + +#![feature(underscore_imports)] +#![warn(unused_imports, unused_extern_crates)] + +struct S; + +mod m { + pub trait Tr1 { + fn tr1_is_in_scope(&self) {} + } + pub trait Tr2 { + fn tr2_is_in_scope(&self) {} + } + + impl Tr1 for ::S {} + impl Tr2 for ::S {} +} + +mod unused { + use m::Tr1 as _; //~ WARN unused import + use S as _; //~ WARN unused import + extern crate core as _; //~ WARN unused extern crate +} + +mod outer { + mod middle { + pub use m::Tr1 as _; + pub use m::Tr2 as _; // OK, no name conflict + struct Tr1; // OK, no name conflict + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } + + mod inner { + // `_` imports are fetched by glob imports + use super::*; + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } + } + } + + // `_` imports are fetched by glob imports + use self::middle::*; + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } +} + +fn main() {} diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/rfc-2166-underscore-imports/basic.stderr new file mode 100644 index 000000000000..4530d0fa604a --- /dev/null +++ b/src/test/ui/rfc-2166-underscore-imports/basic.stderr @@ -0,0 +1,30 @@ +warning: unused import: `m::Tr1 as _` + --> $DIR/basic.rs:31:9 + | +LL | use m::Tr1 as _; //~ WARN unused import + | ^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/basic.rs:14:9 + | +LL | #![warn(unused_imports, unused_extern_crates)] + | ^^^^^^^^^^^^^^ + +warning: unused import: `S as _` + --> $DIR/basic.rs:32:9 + | +LL | use S as _; //~ WARN unused import + | ^^^^^^ + +warning: unused extern crate + --> $DIR/basic.rs:33:5 + | +LL | extern crate core as _; //~ WARN unused extern crate + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/basic.rs:14:25 + | +LL | #![warn(unused_imports, unused_extern_crates)] + | ^^^^^^^^^^^^^^^^^^^^ + From 92bfcd2b192e59d12d64acf6f46c1897a3273b3e Mon Sep 17 00:00:00 2001 From: snf Date: Thu, 8 Mar 2018 14:36:43 +0000 Subject: [PATCH 191/830] implementing fallible allocation API (try_reserve) for Vec, String and HashMap --- src/liballoc/allocator.rs | 18 ++ src/liballoc/lib.rs | 1 + src/liballoc/raw_vec.rs | 102 ++++++---- src/liballoc/string.rs | 74 +++++++ src/liballoc/tests/lib.rs | 1 + src/liballoc/tests/string.rs | 163 +++++++++++++++ src/liballoc/tests/vec.rs | 209 +++++++++++++++++++- src/liballoc/tests/vec_deque.rs | 208 +++++++++++++++++++ src/liballoc/vec.rs | 78 ++++++++ src/liballoc/vec_deque.rs | 92 +++++++++ src/libstd/collections/hash/map.rs | 96 +++++++-- src/libstd/collections/hash/table.rs | 57 ++++-- src/libstd/collections/mod.rs | 3 + src/libstd/lib.rs | 1 + src/test/ui/feature-gate-try_reserve.rs | 14 ++ src/test/ui/feature-gate-try_reserve.stderr | 11 ++ 16 files changed, 1056 insertions(+), 72 deletions(-) create mode 100644 src/test/ui/feature-gate-try_reserve.rs create mode 100644 src/test/ui/feature-gate-try_reserve.stderr diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs index 55e8c0b430f5..fdc4efc66b98 100644 --- a/src/liballoc/allocator.rs +++ b/src/liballoc/allocator.rs @@ -373,6 +373,24 @@ impl fmt::Display for CannotReallocInPlace { } } +/// Augments `AllocErr` with a CapacityOverflow variant. +#[derive(Clone, PartialEq, Eq, Debug)] +#[unstable(feature = "try_reserve", reason = "new API", issue="48043")] +pub enum CollectionAllocErr { + /// Error due to the computed capacity exceeding the collection's maximum + /// (usually `isize::MAX` bytes). + CapacityOverflow, + /// Error due to the allocator (see the `AllocErr` type's docs). + AllocErr(AllocErr), +} + +#[unstable(feature = "try_reserve", reason = "new API", issue="48043")] +impl From for CollectionAllocErr { + fn from(err: AllocErr) -> Self { + CollectionAllocErr::AllocErr(err) + } +} + /// An implementation of `Alloc` can allocate, reallocate, and /// deallocate arbitrary blocks of data described via `Layout`. /// diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3f3067845588..b93e128d5081 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -117,6 +117,7 @@ #![feature(staged_api)] #![feature(str_internals)] #![feature(trusted_len)] +#![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(unicode)] #![feature(unsize)] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 621e19069613..229ae54d7474 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -15,6 +15,8 @@ use core::ptr::{self, Unique}; use core::slice; use heap::{Alloc, Layout, Heap}; use super::boxed::Box; +use super::allocator::CollectionAllocErr; +use super::allocator::CollectionAllocErr::*; /// A low-level utility for more ergonomically allocating, reallocating, and deallocating /// a buffer of memory on the heap without having to worry about all the corner cases @@ -84,7 +86,7 @@ impl RawVec { let elem_size = mem::size_of::(); let alloc_size = cap.checked_mul(elem_size).expect("capacity overflow"); - alloc_guard(alloc_size); + alloc_guard(alloc_size).expect("capacity overflow"); // handles ZSTs and `cap = 0` alike let ptr = if alloc_size == 0 { @@ -308,7 +310,7 @@ impl RawVec { let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; let new_layout = Layout::from_size_align_unchecked(new_size, cur.align()); - alloc_guard(new_size); + alloc_guard(new_size).expect("capacity overflow"); let ptr_res = self.a.realloc(self.ptr.as_ptr() as *mut u8, cur, new_layout); @@ -367,7 +369,7 @@ impl RawVec { // overflow and the alignment is sufficiently small. let new_cap = 2 * self.cap; let new_size = new_cap * elem_size; - alloc_guard(new_size); + alloc_guard(new_size).expect("capacity overflow"); let ptr = self.ptr() as *mut _; let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align()); match self.a.grow_in_place(ptr, old_layout, new_layout) { @@ -403,7 +405,9 @@ impl RawVec { /// # Aborts /// /// Aborts on OOM - pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) { + pub fn try_reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) + -> Result<(), CollectionAllocErr> { + unsafe { // NOTE: we don't early branch on ZSTs here because we want this // to actually catch "asking for more than usize::MAX" in that case. @@ -413,16 +417,15 @@ impl RawVec { // Don't actually need any more capacity. // Wrapping in case they gave a bad `used_cap`. if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { - return; + return Ok(()); } // Nothing we can really do about these checks :( - let new_cap = used_cap.checked_add(needed_extra_cap).expect("capacity overflow"); - let new_layout = match Layout::array::(new_cap) { - Some(layout) => layout, - None => panic!("capacity overflow"), - }; - alloc_guard(new_layout.size()); + let new_cap = used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?; + let new_layout = Layout::array::(new_cap).ok_or(CapacityOverflow)?; + + alloc_guard(new_layout.size())?; + let res = match self.current_layout() { Some(layout) => { let old_ptr = self.ptr.as_ptr() as *mut u8; @@ -430,26 +433,34 @@ impl RawVec { } None => self.a.alloc(new_layout), }; - let uniq = match res { - Ok(ptr) => Unique::new_unchecked(ptr as *mut T), - Err(e) => self.a.oom(e), - }; - self.ptr = uniq; + + self.ptr = Unique::new_unchecked(res? as *mut T); self.cap = new_cap; + + Ok(()) } } + pub fn reserve_exact(&mut self, used_cap: usize, needed_extra_cap: usize) { + match self.try_reserve_exact(used_cap, needed_extra_cap) { + Err(CapacityOverflow) => panic!("capacity overflow"), + Err(AllocErr(e)) => self.a.oom(e), + Ok(()) => { /* yay */ } + } + } + /// Calculates the buffer's new size given that it'll hold `used_cap + /// needed_extra_cap` elements. This logic is used in amortized reserve methods. /// Returns `(new_capacity, new_alloc_size)`. - fn amortized_new_size(&self, used_cap: usize, needed_extra_cap: usize) -> usize { + fn amortized_new_size(&self, used_cap: usize, needed_extra_cap: usize) + -> Result { + // Nothing we can really do about these checks :( - let required_cap = used_cap.checked_add(needed_extra_cap) - .expect("capacity overflow"); + let required_cap = used_cap.checked_add(needed_extra_cap).ok_or(CapacityOverflow)?; // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`. let double_cap = self.cap * 2; // `double_cap` guarantees exponential growth. - cmp::max(double_cap, required_cap) + Ok(cmp::max(double_cap, required_cap)) } /// Ensures that the buffer contains at least enough space to hold @@ -504,8 +515,9 @@ impl RawVec { /// # vector.push_all(&[1, 3, 5, 7, 9]); /// # } /// ``` - pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) { - unsafe { + pub fn try_reserve(&mut self, used_cap: usize, needed_extra_cap: usize) + -> Result<(), CollectionAllocErr> { + unsafe { // NOTE: we don't early branch on ZSTs here because we want this // to actually catch "asking for more than usize::MAX" in that case. // If we make it past the first branch then we are guaranteed to @@ -514,17 +526,15 @@ impl RawVec { // Don't actually need any more capacity. // Wrapping in case they give a bad `used_cap` if self.cap().wrapping_sub(used_cap) >= needed_extra_cap { - return; + return Ok(()); } - let new_cap = self.amortized_new_size(used_cap, needed_extra_cap); + let new_cap = self.amortized_new_size(used_cap, needed_extra_cap)?; + let new_layout = Layout::array::(new_cap).ok_or(CapacityOverflow)?; + + // FIXME: may crash and burn on over-reserve + alloc_guard(new_layout.size())?; - let new_layout = match Layout::array::(new_cap) { - Some(layout) => layout, - None => panic!("capacity overflow"), - }; - // FIXME: may crash and burn on over-reserve - alloc_guard(new_layout.size()); let res = match self.current_layout() { Some(layout) => { let old_ptr = self.ptr.as_ptr() as *mut u8; @@ -532,15 +542,22 @@ impl RawVec { } None => self.a.alloc(new_layout), }; - let uniq = match res { - Ok(ptr) => Unique::new_unchecked(ptr as *mut T), - Err(e) => self.a.oom(e), - }; - self.ptr = uniq; + + self.ptr = Unique::new_unchecked(res? as *mut T); self.cap = new_cap; + + Ok(()) } } + /// The same as try_reserve, but errors are lowered to a call to oom(). + pub fn reserve(&mut self, used_cap: usize, needed_extra_cap: usize) { + match self.try_reserve(used_cap, needed_extra_cap) { + Err(CapacityOverflow) => panic!("capacity overflow"), + Err(AllocErr(e)) => self.a.oom(e), + Ok(()) => { /* yay */ } + } + } /// Attempts to ensure that the buffer contains at least enough space to hold /// `used_cap + needed_extra_cap` elements. If it doesn't already have /// enough capacity, will reallocate in place enough space plus comfortable slack @@ -576,7 +593,8 @@ impl RawVec { return false; } - let new_cap = self.amortized_new_size(used_cap, needed_extra_cap); + let new_cap = self.amortized_new_size(used_cap, needed_extra_cap) + .expect("capacity overflow"); // Here, `cap < used_cap + needed_extra_cap <= new_cap` // (regardless of whether `self.cap - used_cap` wrapped). @@ -585,7 +603,7 @@ impl RawVec { let ptr = self.ptr() as *mut _; let new_layout = Layout::new::().repeat(new_cap).unwrap().0; // FIXME: may crash and burn on over-reserve - alloc_guard(new_layout.size()); + alloc_guard(new_layout.size()).expect("capacity overflow"); match self.a.grow_in_place(ptr, old_layout, new_layout) { Ok(_) => { self.cap = new_cap; @@ -709,14 +727,14 @@ unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec { // all 4GB in user-space. e.g. PAE or x32 #[inline] -fn alloc_guard(alloc_size: usize) { - if mem::size_of::() < 8 { - assert!(alloc_size <= ::core::isize::MAX as usize, - "capacity overflow"); +fn alloc_guard(alloc_size: usize) -> Result<(), CollectionAllocErr> { + if mem::size_of::() < 8 && alloc_size > ::core::isize::MAX as usize { + Err(CapacityOverflow) + } else { + Ok(()) } } - #[cfg(test)] mod tests { use super::*; diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 370fb6b4e890..dcc814173460 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -71,6 +71,7 @@ use Bound::{Excluded, Included, Unbounded}; use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; use vec::Vec; use boxed::Box; +use super::allocator::CollectionAllocErr; /// A UTF-8 encoded, growable string. /// @@ -920,6 +921,79 @@ impl String { self.vec.reserve_exact(additional) } + /// Tries to reserve capacity for at least `additional` more elements to be inserted + /// in the given `String`. The collection may reserve more space to avoid + /// frequent reallocations. After calling `reserve`, capacity will be + /// greater than or equal to `self.len() + additional`. Does nothing if + /// capacity is already sufficient. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(try_reserve)] + /// use std::collections::CollectionAllocErr; + /// + /// fn process_data(data: &str) -> Result { + /// let mut output = String::new(); + /// + /// // Pre-reserve the memory, exiting if we can't + /// output.try_reserve(data.len())?; + /// + /// // Now we know this can't OOM in the middle of our complex work + /// output.push_str(data); + /// + /// Ok(output) + /// } + /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?"); + /// ``` + #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + self.vec.try_reserve(additional) + } + + /// Tries to reserves the minimum capacity for exactly `additional` more elements to + /// be inserted in the given `String`. After calling `reserve_exact`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it + /// requests. Therefore capacity can not be relied upon to be precisely + /// minimal. Prefer `reserve` if future insertions are expected. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(try_reserve)] + /// use std::collections::CollectionAllocErr; + /// + /// fn process_data(data: &str) -> Result { + /// let mut output = String::new(); + /// + /// // Pre-reserve the memory, exiting if we can't + /// output.try_reserve(data.len())?; + /// + /// // Now we know this can't OOM in the middle of our complex work + /// output.push_str(data); + /// + /// Ok(output) + /// } + /// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?"); + /// ``` + #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + self.vec.try_reserve_exact(additional) + } + /// Shrinks the capacity of this `String` to match its length. /// /// # Examples diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 168dbb2ce9b1..285cba0270c0 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -26,6 +26,7 @@ #![feature(splice)] #![feature(str_escape)] #![feature(string_retain)] +#![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(unicode)] #![feature(exact_chunks)] diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index ef6f5e10a72d..d1e746ea43b4 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -9,6 +9,9 @@ // except according to those terms. use std::borrow::Cow; +use std::collections::CollectionAllocErr::*; +use std::mem::size_of; +use std::{usize, isize}; pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { fn into_cow(self) -> Cow<'a, B>; @@ -504,3 +507,163 @@ fn test_into_boxed_str() { let ys = xs.into_boxed_str(); assert_eq!(&*ys, "hello my name is bob"); } + +#[test] +fn test_reserve_exact() { + // This is all the same as test_reserve + + let mut s = String::new(); + assert_eq!(s.capacity(), 0); + + s.reserve_exact(2); + assert!(s.capacity() >= 2); + + for _i in 0..16 { + s.push('0'); + } + + assert!(s.capacity() >= 16); + s.reserve_exact(16); + assert!(s.capacity() >= 32); + + s.push('0'); + + s.reserve_exact(16); + assert!(s.capacity() >= 33) +} + +#[test] +fn test_try_reserve() { + + // These are the interesting cases: + // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM) + // * > isize::MAX should always fail + // * On 16/32-bit should CapacityOverflow + // * On 64-bit should OOM + // * overflow may trigger when adding `len` to `cap` (in number of elements) + // * overflow may trigger when multiplying `new_cap` by size_of:: (to get bytes) + + const MAX_CAP: usize = isize::MAX as usize; + const MAX_USIZE: usize = usize::MAX; + + // On 16/32-bit, we check that allocations don't exceed isize::MAX, + // on 64-bit, we assume the OS will give an OOM for such a ridiculous size. + // Any platform that succeeds for these requests is technically broken with + // ptr::offset because LLVM is the worst. + let guards_against_isize = size_of::() < 8; + + { + // Note: basic stuff is checked by test_reserve + let mut empty_string: String = String::new(); + + // Check isize::MAX doesn't count as an overflow + if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + // Play it again, frank! (just to be sure) + if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + + if guards_against_isize { + // Check isize::MAX + 1 does count as overflow + if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an overflow!") } + + // Check usize::MAX does count as overflow + if let Err(CapacityOverflow) = empty_string.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } else { + // Check isize::MAX + 1 is an OOM + if let Err(AllocErr(_)) = empty_string.try_reserve(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + + // Check usize::MAX is an OOM + if let Err(AllocErr(_)) = empty_string.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an OOM!") } + } + } + + + { + // Same basic idea, but with non-zero len + let mut ten_bytes: String = String::from("0123456789"); + + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_bytes.try_reserve(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + // Should always overflow in the add-to-len + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + +} + +#[test] +fn test_try_reserve_exact() { + + // This is exactly the same as test_try_reserve with the method changed. + // See that test for comments. + + const MAX_CAP: usize = isize::MAX as usize; + const MAX_USIZE: usize = usize::MAX; + + let guards_against_isize = size_of::() < 8; + + { + let mut empty_string: String = String::new(); + + if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + + if guards_against_isize { + if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an overflow!") } + + if let Err(CapacityOverflow) = empty_string.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } else { + if let Err(AllocErr(_)) = empty_string.try_reserve_exact(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + + if let Err(AllocErr(_)) = empty_string.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an OOM!") } + } + } + + + { + let mut ten_bytes: String = String::from("0123456789"); + + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + +} diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 9cfde5dcc73c..3c17a401bbaf 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -10,8 +10,9 @@ use std::borrow::Cow; use std::mem::size_of; -use std::panic; +use std::{usize, isize, panic}; use std::vec::{Drain, IntoIter}; +use std::collections::CollectionAllocErr::*; struct DropCounter<'a> { count: &'a mut u32, @@ -965,3 +966,209 @@ fn drain_filter_complex() { assert_eq!(vec, vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]); } } + +#[test] +fn test_reserve_exact() { + // This is all the same as test_reserve + + let mut v = Vec::new(); + assert_eq!(v.capacity(), 0); + + v.reserve_exact(2); + assert!(v.capacity() >= 2); + + for i in 0..16 { + v.push(i); + } + + assert!(v.capacity() >= 16); + v.reserve_exact(16); + assert!(v.capacity() >= 32); + + v.push(16); + + v.reserve_exact(16); + assert!(v.capacity() >= 33) +} + +#[test] +fn test_try_reserve() { + + // These are the interesting cases: + // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM) + // * > isize::MAX should always fail + // * On 16/32-bit should CapacityOverflow + // * On 64-bit should OOM + // * overflow may trigger when adding `len` to `cap` (in number of elements) + // * overflow may trigger when multiplying `new_cap` by size_of:: (to get bytes) + + const MAX_CAP: usize = isize::MAX as usize; + const MAX_USIZE: usize = usize::MAX; + + // On 16/32-bit, we check that allocations don't exceed isize::MAX, + // on 64-bit, we assume the OS will give an OOM for such a ridiculous size. + // Any platform that succeeds for these requests is technically broken with + // ptr::offset because LLVM is the worst. + let guards_against_isize = size_of::() < 8; + + { + // Note: basic stuff is checked by test_reserve + let mut empty_bytes: Vec = Vec::new(); + + // Check isize::MAX doesn't count as an overflow + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + // Play it again, frank! (just to be sure) + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + + if guards_against_isize { + // Check isize::MAX + 1 does count as overflow + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an overflow!") } + + // Check usize::MAX does count as overflow + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } else { + // Check isize::MAX + 1 is an OOM + if let Err(AllocErr(_)) = empty_bytes.try_reserve(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + + // Check usize::MAX is an OOM + if let Err(AllocErr(_)) = empty_bytes.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an OOM!") } + } + } + + + { + // Same basic idea, but with non-zero len + let mut ten_bytes: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_bytes.try_reserve(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + // Should always overflow in the add-to-len + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + + + { + // Same basic idea, but with interesting type size + let mut ten_u32s: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_u32s.try_reserve(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + // Should fail in the mul-by-size + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) { + } else { + panic!("usize::MAX should trigger an overflow!"); + } + } + +} + +#[test] +fn test_try_reserve_exact() { + + // This is exactly the same as test_try_reserve with the method changed. + // See that test for comments. + + const MAX_CAP: usize = isize::MAX as usize; + const MAX_USIZE: usize = usize::MAX; + + let guards_against_isize = size_of::() < 8; + + { + let mut empty_bytes: Vec = Vec::new(); + + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + + if guards_against_isize { + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an overflow!") } + + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } else { + if let Err(AllocErr(_)) = empty_bytes.try_reserve_exact(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + + if let Err(AllocErr(_)) = empty_bytes.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an OOM!") } + } + } + + + { + let mut ten_bytes: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + + + { + let mut ten_u32s: Vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + +} diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index f2935c05d4f7..fc1a0b624a55 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -11,6 +11,9 @@ use std::collections::VecDeque; use std::fmt::Debug; use std::collections::vec_deque::{Drain}; +use std::collections::CollectionAllocErr::*; +use std::mem::size_of; +use std::{usize, isize}; use self::Taggy::*; use self::Taggypar::*; @@ -1022,3 +1025,208 @@ fn test_placement_in() { } assert_eq!(buf, [5,4,3,1,2,6]); } + +#[test] +fn test_reserve_exact_2() { + // This is all the same as test_reserve + + let mut v = VecDeque::new(); + + v.reserve_exact(2); + assert!(v.capacity() >= 2); + + for i in 0..16 { + v.push_back(i); + } + + assert!(v.capacity() >= 16); + v.reserve_exact(16); + assert!(v.capacity() >= 32); + + v.push_back(16); + + v.reserve_exact(16); + assert!(v.capacity() >= 48) +} + +#[test] +fn test_try_reserve() { + + // These are the interesting cases: + // * exactly isize::MAX should never trigger a CapacityOverflow (can be OOM) + // * > isize::MAX should always fail + // * On 16/32-bit should CapacityOverflow + // * On 64-bit should OOM + // * overflow may trigger when adding `len` to `cap` (in number of elements) + // * overflow may trigger when multiplying `new_cap` by size_of:: (to get bytes) + + const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1; + const MAX_USIZE: usize = usize::MAX; + + // On 16/32-bit, we check that allocations don't exceed isize::MAX, + // on 64-bit, we assume the OS will give an OOM for such a ridiculous size. + // Any platform that succeeds for these requests is technically broken with + // ptr::offset because LLVM is the worst. + let guards_against_isize = size_of::() < 8; + + { + // Note: basic stuff is checked by test_reserve + let mut empty_bytes: VecDeque = VecDeque::new(); + + // Check isize::MAX doesn't count as an overflow + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + // Play it again, frank! (just to be sure) + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + + if guards_against_isize { + // Check isize::MAX + 1 does count as overflow + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an overflow!") } + + // Check usize::MAX does count as overflow + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } else { + // Check isize::MAX is an OOM + // VecDeque starts with capacity 7, always adds 1 to the capacity + // and also rounds the number to next power of 2 so this is the + // furthest we can go without triggering CapacityOverflow + if let Err(AllocErr(_)) = empty_bytes.try_reserve(MAX_CAP) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + } + + + { + // Same basic idea, but with non-zero len + let mut ten_bytes: VecDeque = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); + + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_bytes.try_reserve(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + // Should always overflow in the add-to-len + if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + + + { + // Same basic idea, but with interesting type size + let mut ten_u32s: VecDeque = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); + + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_u32s.try_reserve(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + // Should fail in the mul-by-size + if let Err(CapacityOverflow) = ten_u32s.try_reserve(MAX_USIZE - 20) { + } else { + panic!("usize::MAX should trigger an overflow!"); + } + } + +} + +#[test] +fn test_try_reserve_exact() { + + // This is exactly the same as test_try_reserve with the method changed. + // See that test for comments. + + const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1; + const MAX_USIZE: usize = usize::MAX; + + let guards_against_isize = size_of::() < 8; + + { + let mut empty_bytes: VecDeque = VecDeque::new(); + + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + + if guards_against_isize { + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_CAP + 1) { + } else { panic!("isize::MAX + 1 should trigger an overflow!") } + + if let Err(CapacityOverflow) = empty_bytes.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } else { + // Check isize::MAX is an OOM + // VecDeque starts with capacity 7, always adds 1 to the capacity + // and also rounds the number to next power of 2 so this is the + // furthest we can go without triggering CapacityOverflow + if let Err(AllocErr(_)) = empty_bytes.try_reserve_exact(MAX_CAP) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + } + + + { + let mut ten_bytes: VecDeque = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); + + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_bytes.try_reserve_exact(MAX_CAP - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + if let Err(CapacityOverflow) = ten_bytes.try_reserve_exact(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + + + { + let mut ten_u32s: VecDeque = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10].into_iter().collect(); + + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 10) { + panic!("isize::MAX shouldn't trigger an overflow!"); + } + if guards_against_isize { + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an overflow!"); } + } else { + if let Err(AllocErr(_)) = ten_u32s.try_reserve_exact(MAX_CAP/4 - 9) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + if let Err(CapacityOverflow) = ten_u32s.try_reserve_exact(MAX_USIZE - 20) { + } else { panic!("usize::MAX should trigger an overflow!") } + } + +} diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 1bb2bed463b0..953f95876be1 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -86,6 +86,7 @@ use borrow::Cow; use boxed::Box; use raw_vec::RawVec; use super::range::RangeArgument; +use super::allocator::CollectionAllocErr; use Bound::{Excluded, Included, Unbounded}; /// A contiguous growable array type, written `Vec` but pronounced 'vector'. @@ -489,6 +490,83 @@ impl Vec { self.buf.reserve_exact(self.len, additional); } + /// Tries to reserve capacity for at least `additional` more elements to be inserted + /// in the given `Vec`. The collection may reserve more space to avoid + /// frequent reallocations. After calling `reserve`, capacity will be + /// greater than or equal to `self.len() + additional`. Does nothing if + /// capacity is already sufficient. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(try_reserve)] + /// use std::collections::CollectionAllocErr; + /// + /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr> { + /// let mut output = Vec::new(); + /// + /// // Pre-reserve the memory, exiting if we can't + /// output.try_reserve(data.len())?; + /// + /// // Now we know this can't OOM in the middle of our complex work + /// output.extend(data.iter().map(|&val| { + /// val * 2 + 5 // very complicated + /// })); + /// + /// Ok(output) + /// } + /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); + /// ``` + #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + self.buf.try_reserve(self.len, additional) + } + + /// Tries to reserves the minimum capacity for exactly `additional` more elements to + /// be inserted in the given `Vec`. After calling `reserve_exact`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it + /// requests. Therefore capacity can not be relied upon to be precisely + /// minimal. Prefer `reserve` if future insertions are expected. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(try_reserve)] + /// use std::collections::CollectionAllocErr; + /// + /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr> { + /// let mut output = Vec::new(); + /// + /// // Pre-reserve the memory, exiting if we can't + /// output.try_reserve(data.len())?; + /// + /// // Now we know this can't OOM in the middle of our complex work + /// output.extend(data.iter().map(|&val| { + /// val * 2 + 5 // very complicated + /// })); + /// + /// Ok(output) + /// } + /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); + /// ``` + #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + self.buf.try_reserve_exact(self.len, additional) + } + /// Shrinks the capacity of the vector as much as possible. /// /// It will drop down as close as possible to the length but the allocator diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index 68add3cbd51f..0658777f0a0e 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -31,6 +31,7 @@ use core::cmp; use raw_vec::RawVec; +use super::allocator::CollectionAllocErr; use super::range::RangeArgument; use Bound::{Excluded, Included, Unbounded}; use super::vec::Vec; @@ -566,6 +567,97 @@ impl VecDeque { } } + /// Tries to reserves the minimum capacity for exactly `additional` more elements to + /// be inserted in the given `VecDeque`. After calling `reserve_exact`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it + /// requests. Therefore capacity can not be relied upon to be precisely + /// minimal. Prefer `reserve` if future insertions are expected. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(try_reserve)] + /// use std::collections::CollectionAllocErr; + /// use std::collections::VecDeque; + /// + /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr> { + /// let mut output = VecDeque::new(); + /// + /// // Pre-reserve the memory, exiting if we can't + /// output.try_reserve_exact(data.len())?; + /// + /// // Now we know this can't OOM in the middle of our complex work + /// output.extend(data.iter().map(|&val| { + /// val * 2 + 5 // very complicated + /// })); + /// + /// Ok(output) + /// } + /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); + /// ``` + #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + self.try_reserve(additional) + } + + /// Tries to reserve capacity for at least `additional` more elements to be inserted + /// in the given `VecDeque`. The collection may reserve more space to avoid + /// frequent reallocations. After calling `reserve`, capacity will be + /// greater than or equal to `self.len() + additional`. Does nothing if + /// capacity is already sufficient. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(try_reserve)] + /// use std::collections::CollectionAllocErr; + /// use std::collections::VecDeque; + /// + /// fn process_data(data: &[u32]) -> Result, CollectionAllocErr> { + /// let mut output = VecDeque::new(); + /// + /// // Pre-reserve the memory, exiting if we can't + /// output.try_reserve(data.len())?; + /// + /// // Now we know this can't OOM in the middle of our complex work + /// output.extend(data.iter().map(|&val| { + /// val * 2 + 5 // very complicated + /// })); + /// + /// Ok(output) + /// } + /// # process_data(&[1, 2, 3]).expect("why is the test harness OOMing on 12 bytes?"); + /// ``` + #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { + let old_cap = self.cap(); + let used_cap = self.len() + 1; + let new_cap = used_cap.checked_add(additional) + .and_then(|needed_cap| needed_cap.checked_next_power_of_two()) + .ok_or(CollectionAllocErr::CapacityOverflow)?; + + if new_cap > old_cap { + self.buf.try_reserve_exact(used_cap, new_cap - used_cap)?; + unsafe { + self.handle_cap_increase(old_cap); + } + } + Ok(()) + } + /// Shrinks the capacity of the `VecDeque` as much as possible. /// /// It will drop down as close as possible to the length but the allocator may still inform the diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 6f4528a0e243..b18b38ec3024 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -11,6 +11,8 @@ use self::Entry::*; use self::VacantEntryState::*; +use alloc::heap::{Heap, Alloc}; +use alloc::allocator::CollectionAllocErr; use cell::Cell; use borrow::Borrow; use cmp::max; @@ -42,21 +44,28 @@ impl DefaultResizePolicy { /// provide that capacity, accounting for maximum loading. The raw capacity /// is always zero or a power of two. #[inline] - fn raw_capacity(&self, len: usize) -> usize { + fn try_raw_capacity(&self, len: usize) -> Result { if len == 0 { - 0 + Ok(0) } else { // 1. Account for loading: `raw_capacity >= len * 1.1`. // 2. Ensure it is a power of two. // 3. Ensure it is at least the minimum size. - let mut raw_cap = len * 11 / 10; - assert!(raw_cap >= len, "raw_cap overflow"); - raw_cap = raw_cap.checked_next_power_of_two().expect("raw_capacity overflow"); + let mut raw_cap = len.checked_mul(11) + .map(|l| l / 10) + .and_then(|l| l.checked_next_power_of_two()) + .ok_or(CollectionAllocErr::CapacityOverflow)?; + raw_cap = max(MIN_NONZERO_RAW_CAPACITY, raw_cap); - raw_cap + Ok(raw_cap) } } + #[inline] + fn raw_capacity(&self, len: usize) -> usize { + self.try_raw_capacity(len).expect("raw_capacity overflow") + } + /// The capacity of the given raw capacity. #[inline] fn capacity(&self, raw_cap: usize) -> usize { @@ -775,17 +784,45 @@ impl HashMap /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn reserve(&mut self, additional: usize) { + match self.try_reserve(additional) { + Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), + Err(CollectionAllocErr::AllocErr(e)) => Heap.oom(e), + Ok(()) => { /* yay */ } + } + } + + /// Tries to reserve capacity for at least `additional` more elements to be inserted + /// in the given `HashMap`. The collection may reserve more space to avoid + /// frequent reallocations. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + /// + /// # Examples + /// + /// ``` + /// #![feature(try_reserve)] + /// use std::collections::HashMap; + /// let mut map: HashMap<&str, isize> = HashMap::new(); + /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); + /// ``` + #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] + pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> { let remaining = self.capacity() - self.len(); // this can't overflow if remaining < additional { - let min_cap = self.len().checked_add(additional).expect("reserve overflow"); - let raw_cap = self.resize_policy.raw_capacity(min_cap); - self.resize(raw_cap); + let min_cap = self.len().checked_add(additional) + .ok_or(CollectionAllocErr::CapacityOverflow)?; + let raw_cap = self.resize_policy.try_raw_capacity(min_cap)?; + self.try_resize(raw_cap)?; } else if self.table.tag() && remaining <= self.len() { // Probe sequence is too long and table is half full, // resize early to reduce probing length. let new_capacity = self.table.capacity() * 2; - self.resize(new_capacity); + self.try_resize(new_capacity)?; } + Ok(()) } /// Resizes the internal vectors to a new capacity. It's your @@ -795,15 +832,15 @@ impl HashMap /// 2) Ensure `new_raw_cap` is a power of two or zero. #[inline(never)] #[cold] - fn resize(&mut self, new_raw_cap: usize) { + fn try_resize(&mut self, new_raw_cap: usize) -> Result<(), CollectionAllocErr> { assert!(self.table.size() <= new_raw_cap); assert!(new_raw_cap.is_power_of_two() || new_raw_cap == 0); - let mut old_table = replace(&mut self.table, RawTable::new(new_raw_cap)); + let mut old_table = replace(&mut self.table, RawTable::try_new(new_raw_cap)?); let old_size = old_table.size(); if old_table.size() == 0 { - return; + return Ok(()); } let mut bucket = Bucket::head_bucket(&mut old_table); @@ -838,6 +875,7 @@ impl HashMap } assert_eq!(self.table.size(), old_size); + Ok(()) } /// Shrinks the capacity of the map as much as possible. It will drop @@ -2717,6 +2755,9 @@ mod test_map { use cell::RefCell; use rand::{thread_rng, Rng}; use panic; + use realstd::collections::CollectionAllocErr::*; + use realstd::mem::size_of; + use realstd::usize; #[test] fn test_zero_capacities() { @@ -3651,4 +3692,33 @@ mod test_map { let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { hm.entry(0) <- makepanic(); })); assert_eq!(hm.len(), 0); } + + #[test] + fn test_try_reserve() { + + let mut empty_bytes: HashMap = HashMap::new(); + + const MAX_USIZE: usize = usize::MAX; + + // HashMap and RawTables use complicated size calculations + // hashes_size is sizeof(HashUint) * capacity; + // pairs_size is sizeof((K. V)) * capacity; + // alignment_hashes_size is 8 + // alignment_pairs size is 4 + let size_of_multiplier = (size_of::() + size_of::<(u8, u8)>()).next_power_of_two(); + // The following formula is used to calculate the new capacity + let max_no_ovf = ((MAX_USIZE / 11) * 10) / size_of_multiplier - 1; + + if let Err(CapacityOverflow) = empty_bytes.try_reserve(MAX_USIZE) { + } else { panic!("usize::MAX should trigger an overflow!"); } + + if size_of::() < 8 { + if let Err(CapacityOverflow) = empty_bytes.try_reserve(max_no_ovf) { + } else { panic!("isize::MAX + 1 should trigger a CapacityOverflow!") } + } else { + if let Err(AllocErr(_)) = empty_bytes.try_reserve(max_no_ovf) { + } else { panic!("isize::MAX + 1 should trigger an OOM!") } + } + } + } diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 73bd5747c105..8e78dc546c6c 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -17,6 +17,7 @@ use mem::{align_of, size_of, needs_drop}; use mem; use ops::{Deref, DerefMut}; use ptr::{self, Unique, NonNull}; +use alloc::allocator::CollectionAllocErr; use self::BucketState::*; @@ -741,14 +742,15 @@ fn test_offset_calculation() { impl RawTable { /// Does not initialize the buckets. The caller should ensure they, /// at the very least, set every hash to EMPTY_BUCKET. - unsafe fn new_uninitialized(capacity: usize) -> RawTable { + /// Returns an error if it cannot allocate or capacity overflows. + unsafe fn try_new_uninitialized(capacity: usize) -> Result, CollectionAllocErr> { if capacity == 0 { - return RawTable { + return Ok(RawTable { size: 0, capacity_mask: capacity.wrapping_sub(1), hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint), marker: marker::PhantomData, - }; + }); } // No need for `checked_mul` before a more restrictive check performed @@ -768,25 +770,38 @@ impl RawTable { align_of::(), pairs_size, align_of::<(K, V)>()); - assert!(!oflo, "capacity overflow"); + if oflo { + return Err(CollectionAllocErr::CapacityOverflow); + } // One check for overflow that covers calculation and rounding of size. - let size_of_bucket = size_of::().checked_add(size_of::<(K, V)>()).unwrap(); - assert!(size >= - capacity.checked_mul(size_of_bucket) - .expect("capacity overflow"), - "capacity overflow"); + let size_of_bucket = size_of::().checked_add(size_of::<(K, V)>()) + .ok_or(CollectionAllocErr::CapacityOverflow)?; + let capacity_mul_size_of_bucket = capacity.checked_mul(size_of_bucket); + if capacity_mul_size_of_bucket.is_none() || size < capacity_mul_size_of_bucket.unwrap() { + return Err(CollectionAllocErr::CapacityOverflow); + } - let buffer = Heap.alloc(Layout::from_size_align(size, alignment).unwrap()) - .unwrap_or_else(|e| Heap.oom(e)); + let buffer = Heap.alloc(Layout::from_size_align(size, alignment) + .ok_or(CollectionAllocErr::CapacityOverflow)?)?; let hashes = buffer as *mut HashUint; - RawTable { + Ok(RawTable { capacity_mask: capacity.wrapping_sub(1), size: 0, hashes: TaggedHashUintPtr::new(hashes), marker: marker::PhantomData, + }) + } + + /// Does not initialize the buckets. The caller should ensure they, + /// at the very least, set every hash to EMPTY_BUCKET. + unsafe fn new_uninitialized(capacity: usize) -> RawTable { + match Self::try_new_uninitialized(capacity) { + Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), + Err(CollectionAllocErr::AllocErr(e)) => Heap.oom(e), + Ok(table) => { table } } } @@ -809,13 +824,23 @@ impl RawTable { } } + /// Tries to create a new raw table from a given capacity. If it cannot allocate, + /// it returns with AllocErr. + pub fn try_new(capacity: usize) -> Result, CollectionAllocErr> { + unsafe { + let ret = RawTable::try_new_uninitialized(capacity)?; + ptr::write_bytes(ret.hashes.ptr(), 0, capacity); + Ok(ret) + } + } + /// Creates a new raw table from a given capacity. All buckets are /// initially empty. pub fn new(capacity: usize) -> RawTable { - unsafe { - let ret = RawTable::new_uninitialized(capacity); - ptr::write_bytes(ret.hashes.ptr(), 0, capacity); - ret + match Self::try_new(capacity) { + Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"), + Err(CollectionAllocErr::AllocErr(e)) => Heap.oom(e), + Ok(table) => { table } } } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index e9a150f34a51..be88f4e268aa 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -438,6 +438,9 @@ pub use self::hash_set::HashSet; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc::range; +#[unstable(feature = "try_reserve", reason = "new API", issue="48043")] +pub use alloc::allocator::CollectionAllocErr; + mod hash; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index da15941374d8..ccc5373acc7e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -314,6 +314,7 @@ #![feature(thread_local)] #![feature(toowned_clone_into)] #![feature(try_from)] +#![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(unicode)] #![feature(untagged_unions)] diff --git a/src/test/ui/feature-gate-try_reserve.rs b/src/test/ui/feature-gate-try_reserve.rs new file mode 100644 index 000000000000..9322dbd272f7 --- /dev/null +++ b/src/test/ui/feature-gate-try_reserve.rs @@ -0,0 +1,14 @@ +// 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. + +fn main() { + let v = Vec::new(); + v.try_reserve(10); //~ ERROR: use of unstable library feature 'try_reserve' +} diff --git a/src/test/ui/feature-gate-try_reserve.stderr b/src/test/ui/feature-gate-try_reserve.stderr new file mode 100644 index 000000000000..b1fef61dd245 --- /dev/null +++ b/src/test/ui/feature-gate-try_reserve.stderr @@ -0,0 +1,11 @@ +error[E0658]: use of unstable library feature 'try_reserve': new API (see issue #48043) + --> $DIR/feature-gate-try_reserve.rs:13:7 + | +LL | v.try_reserve(10); //~ ERROR: use of unstable library feature 'try_reserve' + | ^^^^^^^^^^^ + | + = help: add #![feature(try_reserve)] to the crate attributes to enable + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0658" From b08b5ae0ec22e67d1cab7495865a0b34d4e6c5a2 Mon Sep 17 00:00:00 2001 From: snf Date: Tue, 13 Mar 2018 03:41:45 -0700 Subject: [PATCH 192/830] try_reserve: disabling tests for asmjs, blocked by #48968 --- src/liballoc/tests/string.rs | 5 +++++ src/liballoc/tests/vec.rs | 7 ++++++- src/liballoc/tests/vec_deque.rs | 8 +++++++- src/libstd/collections/hash/map.rs | 4 ++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index d1e746ea43b4..9bbba4e22b03 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -9,8 +9,11 @@ // except according to those terms. use std::borrow::Cow; +#[cfg(not(target_arch = "asmjs"))] use std::collections::CollectionAllocErr::*; +#[cfg(not(target_arch = "asmjs"))] use std::mem::size_of; +#[cfg(not(target_arch = "asmjs"))] use std::{usize, isize}; pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { @@ -532,6 +535,7 @@ fn test_reserve_exact() { assert!(s.capacity() >= 33) } +#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { @@ -609,6 +613,7 @@ fn test_try_reserve() { } +#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve_exact() { diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 3c17a401bbaf..85e11d8b8ee6 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -10,8 +10,11 @@ use std::borrow::Cow; use std::mem::size_of; -use std::{usize, isize, panic}; +use std::{usize, panic}; +#[cfg(not(target_arch = "asmjs"))] +use std::isize; use std::vec::{Drain, IntoIter}; +#[cfg(not(target_arch = "asmjs"))] use std::collections::CollectionAllocErr::*; struct DropCounter<'a> { @@ -991,6 +994,7 @@ fn test_reserve_exact() { assert!(v.capacity() >= 33) } +#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { @@ -1093,6 +1097,7 @@ fn test_try_reserve() { } +#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve_exact() { diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index fc1a0b624a55..9fd38ed6f6f4 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -11,9 +11,13 @@ use std::collections::VecDeque; use std::fmt::Debug; use std::collections::vec_deque::{Drain}; +#[cfg(not(target_arch = "asmjs"))] use std::collections::CollectionAllocErr::*; +#[cfg(not(target_arch = "asmjs"))] use std::mem::size_of; -use std::{usize, isize}; +use std::isize; +#[cfg(not(target_arch = "asmjs"))] +use std::usize; use self::Taggy::*; use self::Taggypar::*; @@ -1049,6 +1053,7 @@ fn test_reserve_exact_2() { assert!(v.capacity() >= 48) } +#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { @@ -1150,6 +1155,7 @@ fn test_try_reserve() { } +#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve_exact() { diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index b18b38ec3024..5f5dec2dd4ff 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2755,8 +2755,11 @@ mod test_map { use cell::RefCell; use rand::{thread_rng, Rng}; use panic; + #[cfg(not(target_arch = "asmjs"))] use realstd::collections::CollectionAllocErr::*; + #[cfg(not(target_arch = "asmjs"))] use realstd::mem::size_of; + #[cfg(not(target_arch = "asmjs"))] use realstd::usize; #[test] @@ -3693,6 +3696,7 @@ mod test_map { assert_eq!(hm.len(), 0); } + #[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { From 06057d9143bc42f82c35b20c5c26fbfce58abc95 Mon Sep 17 00:00:00 2001 From: snf Date: Wed, 14 Mar 2018 03:48:04 -0700 Subject: [PATCH 193/830] try_reserve: updating message for feature-gate-try_reserve.stderr --- src/test/ui/feature-gate-try_reserve.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/feature-gate-try_reserve.stderr b/src/test/ui/feature-gate-try_reserve.stderr index b1fef61dd245..928d266b37ae 100644 --- a/src/test/ui/feature-gate-try_reserve.stderr +++ b/src/test/ui/feature-gate-try_reserve.stderr @@ -8,4 +8,4 @@ LL | v.try_reserve(10); //~ ERROR: use of unstable library feature 'try_rese error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. From cbdf4ec03e92ed36c162bb8c645993e48a1caa02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 7 Mar 2018 02:44:10 +0100 Subject: [PATCH 194/830] Remove syntax and syntax_pos thread locals --- src/Cargo.lock | 2 + src/librustc/session/config.rs | 58 +- src/librustc_driver/lib.rs | 11 + src/librustc_driver/test.rs | 13 +- src/librustdoc/clean/cfg.rs | 860 +++++++++--------- src/librustdoc/lib.rs | 9 +- src/librustdoc/test.rs | 5 +- src/libsyntax/Cargo.toml | 1 + src/libsyntax/attr.rs | 35 +- src/libsyntax/fold.rs | 43 +- src/libsyntax/lib.rs | 30 + src/libsyntax/parse/lexer/mod.rs | 255 +++--- src/libsyntax/parse/mod.rs | 585 ++++++------ src/libsyntax/print/pprust.rs | 47 +- src/libsyntax/test_snippet.rs | 53 +- src/libsyntax/tokenstream.rs | 81 +- src/libsyntax_pos/Cargo.toml | 1 + src/libsyntax_pos/hygiene.rs | 11 +- src/libsyntax_pos/lib.rs | 23 +- src/libsyntax_pos/span_encoding.rs | 11 +- src/libsyntax_pos/symbol.rs | 19 +- src/test/run-fail-fulldeps/qquote.rs | 4 + src/test/run-make/issue-19371/foo.rs | 30 +- .../run-pass-fulldeps/ast_stmt_expr_attr.rs | 4 + src/test/run-pass-fulldeps/issue-35829.rs | 4 + .../pprust-expr-roundtrip.rs | 5 +- src/test/run-pass-fulldeps/qquote.rs | 4 + src/tools/error_index_generator/main.rs | 5 +- src/tools/tidy/src/deps.rs | 1 + 29 files changed, 1212 insertions(+), 998 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index ed32984bb584..e34983e23c02 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2432,6 +2432,7 @@ dependencies = [ "rustc_cratesio_shim 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "syntax_pos 0.0.0", ] @@ -2453,6 +2454,7 @@ name = "syntax_pos" version = "0.0.0" dependencies = [ "rustc_data_structures 0.0.0", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1c5cfa87ef46..885658df5654 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -2391,6 +2391,7 @@ mod tests { use super::{Externs, OutputType, OutputTypes}; use rustc_back::{PanicStrategy, RelroLevel}; use syntax::symbol::Symbol; + use syntax; fn optgroups() -> getopts::Options { let mut opts = getopts::Options::new(); @@ -2411,45 +2412,50 @@ mod tests { // When the user supplies --test we should implicitly supply --cfg test #[test] fn test_switch_implies_cfg_test() { - let matches = &match optgroups().parse(&["--test".to_string()]) { - Ok(m) => m, - Err(f) => panic!("test_switch_implies_cfg_test: {}", f), - }; - let registry = errors::registry::Registry::new(&[]); - let (sessopts, cfg) = build_session_options_and_crate_config(matches); - let sess = build_session(sessopts, None, registry); - let cfg = build_configuration(&sess, cfg); - assert!(cfg.contains(&(Symbol::intern("test"), None))); + syntax::with_globals(|| { + let matches = &match optgroups().parse(&["--test".to_string()]) { + Ok(m) => m, + Err(f) => panic!("test_switch_implies_cfg_test: {}", f), + }; + let registry = errors::registry::Registry::new(&[]); + let (sessopts, cfg) = build_session_options_and_crate_config(matches); + let sess = build_session(sessopts, None, registry); + let cfg = build_configuration(&sess, cfg); + assert!(cfg.contains(&(Symbol::intern("test"), None))); + }); } // When the user supplies --test and --cfg test, don't implicitly add // another --cfg test #[test] fn test_switch_implies_cfg_test_unless_cfg_test() { - let matches = &match optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]) { - Ok(m) => m, - Err(f) => panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f), - }; - let registry = errors::registry::Registry::new(&[]); - let (sessopts, cfg) = build_session_options_and_crate_config(matches); - let sess = build_session(sessopts, None, registry); - let cfg = build_configuration(&sess, cfg); - let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test"); - assert!(test_items.next().is_some()); - assert!(test_items.next().is_none()); + syntax::with_globals(|| { + let matches = &match optgroups().parse(&["--test".to_string(), + "--cfg=test".to_string()]) { + Ok(m) => m, + Err(f) => panic!("test_switch_implies_cfg_test_unless_cfg_test: {}", f), + }; + let registry = errors::registry::Registry::new(&[]); + let (sessopts, cfg) = build_session_options_and_crate_config(matches); + let sess = build_session(sessopts, None, registry); + let cfg = build_configuration(&sess, cfg); + let mut test_items = cfg.iter().filter(|&&(name, _)| name == "test"); + assert!(test_items.next().is_some()); + assert!(test_items.next().is_none()); + }); } #[test] fn test_can_print_warnings() { - { + syntax::with_globals(|| { let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap(); let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); assert!(!sess.diagnostic().flags.can_emit_warnings); - } + }); - { + syntax::with_globals(|| { let matches = optgroups() .parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]) .unwrap(); @@ -2457,15 +2463,15 @@ mod tests { let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); assert!(sess.diagnostic().flags.can_emit_warnings); - } + }); - { + syntax::with_globals(|| { let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap(); let registry = errors::registry::Registry::new(&[]); let (sessopts, _) = build_session_options_and_crate_config(&matches); let sess = build_session(sessopts, None, registry); assert!(sess.diagnostic().flags.can_emit_warnings); - } + }); } #[test] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 746f2db4767f..04513bfa53d0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -447,6 +447,17 @@ pub fn run_compiler<'a>(args: &[String], file_loader: Option>, emitter_dest: Option>) -> (CompileResult, Option) +{ + syntax::with_globals(|| { + run_compiler_impl(args, callbacks, file_loader, emitter_dest) + }) +} + +fn run_compiler_impl<'a>(args: &[String], + callbacks: &mut CompilerCalls<'a>, + file_loader: Option>, + emitter_dest: Option>) + -> (CompileResult, Option) { macro_rules! do_or_return {($expr: expr, $sess: expr) => { match $expr { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 06610609ebdb..fb48f900be52 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -29,6 +29,7 @@ use rustc::hir::map as hir_map; use rustc::session::{self, config}; use rustc::session::config::{OutputFilenames, OutputTypes}; use rustc_data_structures::sync::Lrc; +use syntax; use syntax::ast; use syntax::abi::Abi; use syntax::codemap::{CodeMap, FilePathMapping, FileName}; @@ -93,9 +94,19 @@ fn errors(msgs: &[&str]) -> (Box, usize) { } fn test_env(source_string: &str, - (emitter, expected_err_count): (Box, usize), + args: (Box, usize), body: F) where F: FnOnce(Env) +{ + syntax::with_globals(|| { + test_env_impl(source_string, args, body) + }); +} + +fn test_env_impl(source_string: &str, + (emitter, expected_err_count): (Box, usize), + body: F) + where F: FnOnce(Env) { let mut options = config::basic_options(); options.debugging_opts.verbose = true; diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index a769771f8aa8..5cac2d1bbe7e 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -398,6 +398,7 @@ mod test { use syntax::ast::*; use syntax::codemap::dummy_spanned; use syntax_pos::DUMMY_SP; + use syntax::with_globals; fn word_cfg(s: &str) -> Cfg { Cfg::Cfg(Symbol::intern(s), None) @@ -409,479 +410,494 @@ mod test { #[test] fn test_cfg_not() { - assert_eq!(!Cfg::False, Cfg::True); - assert_eq!(!Cfg::True, Cfg::False); - assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test")))); - assert_eq!( - !Cfg::All(vec![word_cfg("a"), word_cfg("b")]), - Cfg::Not(Box::new(Cfg::All(vec![word_cfg("a"), word_cfg("b")]))) - ); - assert_eq!( - !Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), - Cfg::Not(Box::new(Cfg::Any(vec![word_cfg("a"), word_cfg("b")]))) - ); - assert_eq!(!Cfg::Not(Box::new(word_cfg("test"))), word_cfg("test")); + with_globals(|| { + assert_eq!(!Cfg::False, Cfg::True); + assert_eq!(!Cfg::True, Cfg::False); + assert_eq!(!word_cfg("test"), Cfg::Not(Box::new(word_cfg("test")))); + assert_eq!( + !Cfg::All(vec![word_cfg("a"), word_cfg("b")]), + Cfg::Not(Box::new(Cfg::All(vec![word_cfg("a"), word_cfg("b")]))) + ); + assert_eq!( + !Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), + Cfg::Not(Box::new(Cfg::Any(vec![word_cfg("a"), word_cfg("b")]))) + ); + assert_eq!(!Cfg::Not(Box::new(word_cfg("test"))), word_cfg("test")); + }) } #[test] fn test_cfg_and() { - let mut x = Cfg::False; - x &= Cfg::True; - assert_eq!(x, Cfg::False); + with_globals(|| { + let mut x = Cfg::False; + x &= Cfg::True; + assert_eq!(x, Cfg::False); - x = word_cfg("test"); - x &= Cfg::False; - assert_eq!(x, Cfg::False); + x = word_cfg("test"); + x &= Cfg::False; + assert_eq!(x, Cfg::False); - x = word_cfg("test2"); - x &= Cfg::True; - assert_eq!(x, word_cfg("test2")); + x = word_cfg("test2"); + x &= Cfg::True; + assert_eq!(x, word_cfg("test2")); - x = Cfg::True; - x &= word_cfg("test3"); - assert_eq!(x, word_cfg("test3")); + x = Cfg::True; + x &= word_cfg("test3"); + assert_eq!(x, word_cfg("test3")); - x &= word_cfg("test4"); - assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); + x &= word_cfg("test4"); + assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4")])); - x &= word_cfg("test5"); - assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); + x &= word_cfg("test5"); + assert_eq!(x, Cfg::All(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); - x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]); - assert_eq!(x, Cfg::All(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - ])); + x &= Cfg::All(vec![word_cfg("test6"), word_cfg("test7")]); + assert_eq!(x, Cfg::All(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + ])); - let mut y = Cfg::Any(vec![word_cfg("a"), word_cfg("b")]); - y &= x; - assert_eq!(y, Cfg::All(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), - ])); + let mut y = Cfg::Any(vec![word_cfg("a"), word_cfg("b")]); + y &= x; + assert_eq!(y, Cfg::All(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + Cfg::Any(vec![word_cfg("a"), word_cfg("b")]), + ])); - assert_eq!( - word_cfg("a") & word_cfg("b") & word_cfg("c"), - Cfg::All(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) - ); + assert_eq!( + word_cfg("a") & word_cfg("b") & word_cfg("c"), + Cfg::All(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) + ); + }) } #[test] fn test_cfg_or() { - let mut x = Cfg::True; - x |= Cfg::False; - assert_eq!(x, Cfg::True); + with_globals(|| { + let mut x = Cfg::True; + x |= Cfg::False; + assert_eq!(x, Cfg::True); - x = word_cfg("test"); - x |= Cfg::True; - assert_eq!(x, Cfg::True); + x = word_cfg("test"); + x |= Cfg::True; + assert_eq!(x, Cfg::True); - x = word_cfg("test2"); - x |= Cfg::False; - assert_eq!(x, word_cfg("test2")); + x = word_cfg("test2"); + x |= Cfg::False; + assert_eq!(x, word_cfg("test2")); - x = Cfg::False; - x |= word_cfg("test3"); - assert_eq!(x, word_cfg("test3")); + x = Cfg::False; + x |= word_cfg("test3"); + assert_eq!(x, word_cfg("test3")); - x |= word_cfg("test4"); - assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); + x |= word_cfg("test4"); + assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4")])); - x |= word_cfg("test5"); - assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); + x |= word_cfg("test5"); + assert_eq!(x, Cfg::Any(vec![word_cfg("test3"), word_cfg("test4"), word_cfg("test5")])); - x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]); - assert_eq!(x, Cfg::Any(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - ])); + x |= Cfg::Any(vec![word_cfg("test6"), word_cfg("test7")]); + assert_eq!(x, Cfg::Any(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + ])); - let mut y = Cfg::All(vec![word_cfg("a"), word_cfg("b")]); - y |= x; - assert_eq!(y, Cfg::Any(vec![ - word_cfg("test3"), - word_cfg("test4"), - word_cfg("test5"), - word_cfg("test6"), - word_cfg("test7"), - Cfg::All(vec![word_cfg("a"), word_cfg("b")]), - ])); + let mut y = Cfg::All(vec![word_cfg("a"), word_cfg("b")]); + y |= x; + assert_eq!(y, Cfg::Any(vec![ + word_cfg("test3"), + word_cfg("test4"), + word_cfg("test5"), + word_cfg("test6"), + word_cfg("test7"), + Cfg::All(vec![word_cfg("a"), word_cfg("b")]), + ])); - assert_eq!( - word_cfg("a") | word_cfg("b") | word_cfg("c"), - Cfg::Any(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) - ); + assert_eq!( + word_cfg("a") | word_cfg("b") | word_cfg("c"), + Cfg::Any(vec![word_cfg("a"), word_cfg("b"), word_cfg("c")]) + ); + }) } #[test] fn test_parse_ok() { - let mi = MetaItem { - name: Symbol::intern("all"), - node: MetaItemKind::Word, - span: DUMMY_SP, - }; - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); + with_globals(|| { + let mi = MetaItem { + name: Symbol::intern("all"), + node: MetaItemKind::Word, + span: DUMMY_SP, + }; + assert_eq!(Cfg::parse(&mi), Ok(word_cfg("all"))); - let mi = MetaItem { - name: Symbol::intern("all"), - node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str( - Symbol::intern("done"), - StrStyle::Cooked, - ))), - span: DUMMY_SP, - }; - assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); + let mi = MetaItem { + name: Symbol::intern("all"), + node: MetaItemKind::NameValue(dummy_spanned(LitKind::Str( + Symbol::intern("done"), + StrStyle::Cooked, + ))), + span: DUMMY_SP, + }; + assert_eq!(Cfg::parse(&mi), Ok(name_value_cfg("all", "done"))); - let mi = MetaItem { - name: Symbol::intern("all"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("b"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b"))); + let mi = MetaItem { + name: Symbol::intern("all"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("b"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b"))); - let mi = MetaItem { - name: Symbol::intern("any"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("b"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b"))); + let mi = MetaItem { + name: Symbol::intern("any"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("b"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") | word_cfg("b"))); - let mi = MetaItem { - name: Symbol::intern("not"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a"))); + let mi = MetaItem { + name: Symbol::intern("not"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert_eq!(Cfg::parse(&mi), Ok(!word_cfg("a"))); - let mi = MetaItem { - name: Symbol::intern("not"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("any"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("all"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("b"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("c"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c"))))); + let mi = MetaItem { + name: Symbol::intern("not"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("any"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("all"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("b"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("c"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert_eq!(Cfg::parse(&mi), Ok(!(word_cfg("a") | (word_cfg("b") & word_cfg("c"))))); - let mi = MetaItem { - name: Symbol::intern("all"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("b"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("c"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b") & word_cfg("c"))); + let mi = MetaItem { + name: Symbol::intern("all"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("b"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("c"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert_eq!(Cfg::parse(&mi), Ok(word_cfg("a") & word_cfg("b") & word_cfg("c"))); + }) } #[test] fn test_parse_err() { - let mi = MetaItem { - name: Symbol::intern("foo"), - node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))), - span: DUMMY_SP, - }; - assert!(Cfg::parse(&mi).is_err()); + with_globals(|| { + let mi = MetaItem { + name: Symbol::intern("foo"), + node: MetaItemKind::NameValue(dummy_spanned(LitKind::Bool(false))), + span: DUMMY_SP, + }; + assert!(Cfg::parse(&mi).is_err()); - let mi = MetaItem { - name: Symbol::intern("not"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("b"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert!(Cfg::parse(&mi).is_err()); + let mi = MetaItem { + name: Symbol::intern("not"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("b"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert!(Cfg::parse(&mi).is_err()); - let mi = MetaItem { - name: Symbol::intern("not"), - node: MetaItemKind::List(vec![]), - span: DUMMY_SP, - }; - assert!(Cfg::parse(&mi).is_err()); + let mi = MetaItem { + name: Symbol::intern("not"), + node: MetaItemKind::List(vec![]), + span: DUMMY_SP, + }; + assert!(Cfg::parse(&mi).is_err()); - let mi = MetaItem { - name: Symbol::intern("foo"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert!(Cfg::parse(&mi).is_err()); + let mi = MetaItem { + name: Symbol::intern("foo"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert!(Cfg::parse(&mi).is_err()); - let mi = MetaItem { - name: Symbol::intern("all"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("foo"), - node: MetaItemKind::List(vec![]), - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("b"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert!(Cfg::parse(&mi).is_err()); + let mi = MetaItem { + name: Symbol::intern("all"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("foo"), + node: MetaItemKind::List(vec![]), + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("b"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert!(Cfg::parse(&mi).is_err()); - let mi = MetaItem { - name: Symbol::intern("any"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("a"), - node: MetaItemKind::Word, - span: DUMMY_SP, - })), - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("foo"), - node: MetaItemKind::List(vec![]), - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert!(Cfg::parse(&mi).is_err()); + let mi = MetaItem { + name: Symbol::intern("any"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("a"), + node: MetaItemKind::Word, + span: DUMMY_SP, + })), + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("foo"), + node: MetaItemKind::List(vec![]), + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert!(Cfg::parse(&mi).is_err()); - let mi = MetaItem { - name: Symbol::intern("not"), - node: MetaItemKind::List(vec![ - dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { - name: Symbol::intern("foo"), - node: MetaItemKind::List(vec![]), - span: DUMMY_SP, - })), - ]), - span: DUMMY_SP, - }; - assert!(Cfg::parse(&mi).is_err()); + let mi = MetaItem { + name: Symbol::intern("not"), + node: MetaItemKind::List(vec![ + dummy_spanned(NestedMetaItemKind::MetaItem(MetaItem { + name: Symbol::intern("foo"), + node: MetaItemKind::List(vec![]), + span: DUMMY_SP, + })), + ]), + span: DUMMY_SP, + }; + assert!(Cfg::parse(&mi).is_err()); + }) } #[test] fn test_render_short_html() { - assert_eq!( - word_cfg("unix").render_short_html(), - "Unix" - ); - assert_eq!( - name_value_cfg("target_os", "macos").render_short_html(), - "macOS" - ); - assert_eq!( - name_value_cfg("target_pointer_width", "16").render_short_html(), - "16-bit" - ); - assert_eq!( - name_value_cfg("target_endian", "little").render_short_html(), - "Little-endian" - ); - assert_eq!( - (!word_cfg("windows")).render_short_html(), - "Non-Windows" - ); - assert_eq!( - (word_cfg("unix") & word_cfg("windows")).render_short_html(), - "Unix and Windows" - ); - assert_eq!( - (word_cfg("unix") | word_cfg("windows")).render_short_html(), - "Unix or Windows" - ); - assert_eq!( - ( - word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") - ).render_short_html(), - "Unix and Windows and debug-assertions enabled" - ); - assert_eq!( - ( - word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") - ).render_short_html(), - "Unix or Windows or debug-assertions enabled" - ); - assert_eq!( - ( - !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) - ).render_short_html(), - "Neither Unix nor Windows nor debug-assertions enabled" - ); - assert_eq!( - ( - (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | - (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) - ).render_short_html(), - "Unix and x86-64, or Windows and 64-bit" - ); - assert_eq!( - (!(word_cfg("unix") & word_cfg("windows"))).render_short_html(), - "Not (Unix and Windows)" - ); - assert_eq!( - ( - (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") - ).render_short_html(), - "(Debug-assertions enabled or Windows) and Unix" - ); + with_globals(|| { + assert_eq!( + word_cfg("unix").render_short_html(), + "Unix" + ); + assert_eq!( + name_value_cfg("target_os", "macos").render_short_html(), + "macOS" + ); + assert_eq!( + name_value_cfg("target_pointer_width", "16").render_short_html(), + "16-bit" + ); + assert_eq!( + name_value_cfg("target_endian", "little").render_short_html(), + "Little-endian" + ); + assert_eq!( + (!word_cfg("windows")).render_short_html(), + "Non-Windows" + ); + assert_eq!( + (word_cfg("unix") & word_cfg("windows")).render_short_html(), + "Unix and Windows" + ); + assert_eq!( + (word_cfg("unix") | word_cfg("windows")).render_short_html(), + "Unix or Windows" + ); + assert_eq!( + ( + word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") + ).render_short_html(), + "Unix and Windows and debug-assertions enabled" + ); + assert_eq!( + ( + word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") + ).render_short_html(), + "Unix or Windows or debug-assertions enabled" + ); + assert_eq!( + ( + !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) + ).render_short_html(), + "Neither Unix nor Windows nor debug-assertions enabled" + ); + assert_eq!( + ( + (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | + (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) + ).render_short_html(), + "Unix and x86-64, or Windows and 64-bit" + ); + assert_eq!( + (!(word_cfg("unix") & word_cfg("windows"))).render_short_html(), + "Not (Unix and Windows)" + ); + assert_eq!( + ( + (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") + ).render_short_html(), + "(Debug-assertions enabled or Windows) and Unix" + ); + }) } #[test] fn test_render_long_html() { - assert_eq!( - word_cfg("unix").render_long_html(), - "This is supported on Unix only." - ); - assert_eq!( - name_value_cfg("target_os", "macos").render_long_html(), - "This is supported on macOS only." - ); - assert_eq!( - name_value_cfg("target_pointer_width", "16").render_long_html(), - "This is supported on 16-bit only." - ); - assert_eq!( - name_value_cfg("target_endian", "little").render_long_html(), - "This is supported on little-endian only." - ); - assert_eq!( - (!word_cfg("windows")).render_long_html(), - "This is supported on non-Windows only." - ); - assert_eq!( - (word_cfg("unix") & word_cfg("windows")).render_long_html(), - "This is supported on Unix and Windows only." - ); - assert_eq!( - (word_cfg("unix") | word_cfg("windows")).render_long_html(), - "This is supported on Unix or Windows only." - ); - assert_eq!( - ( - word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") - ).render_long_html(), - "This is supported on Unix and Windows and debug-assertions enabled \ - only." - ); - assert_eq!( - ( - word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") - ).render_long_html(), - "This is supported on Unix or Windows or debug-assertions enabled \ - only." - ); - assert_eq!( - ( - !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) - ).render_long_html(), - "This is supported on neither Unix nor Windows nor debug-assertions \ - enabled." - ); - assert_eq!( - ( - (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | - (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) - ).render_long_html(), - "This is supported on Unix and x86-64, or Windows and 64-bit only." - ); - assert_eq!( - (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(), - "This is supported on not (Unix and Windows)." - ); - assert_eq!( - ( - (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") - ).render_long_html(), - "This is supported on (debug-assertions enabled or Windows) and Unix \ - only." - ); + with_globals(|| { + assert_eq!( + word_cfg("unix").render_long_html(), + "This is supported on Unix only." + ); + assert_eq!( + name_value_cfg("target_os", "macos").render_long_html(), + "This is supported on macOS only." + ); + assert_eq!( + name_value_cfg("target_pointer_width", "16").render_long_html(), + "This is supported on 16-bit only." + ); + assert_eq!( + name_value_cfg("target_endian", "little").render_long_html(), + "This is supported on little-endian only." + ); + assert_eq!( + (!word_cfg("windows")).render_long_html(), + "This is supported on non-Windows only." + ); + assert_eq!( + (word_cfg("unix") & word_cfg("windows")).render_long_html(), + "This is supported on Unix and Windows only." + ); + assert_eq!( + (word_cfg("unix") | word_cfg("windows")).render_long_html(), + "This is supported on Unix or Windows only." + ); + assert_eq!( + ( + word_cfg("unix") & word_cfg("windows") & word_cfg("debug_assertions") + ).render_long_html(), + "This is supported on Unix and Windows and debug-assertions enabled\ + only." + ); + assert_eq!( + ( + word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions") + ).render_long_html(), + "This is supported on Unix or Windows or debug-assertions enabled\ + only." + ); + assert_eq!( + ( + !(word_cfg("unix") | word_cfg("windows") | word_cfg("debug_assertions")) + ).render_long_html(), + "This is supported on neither Unix nor Windows nor debug-assertions \ + enabled." + ); + assert_eq!( + ( + (word_cfg("unix") & name_value_cfg("target_arch", "x86_64")) | + (word_cfg("windows") & name_value_cfg("target_pointer_width", "64")) + ).render_long_html(), + "This is supported on Unix and x86-64, or Windows and 64-bit \ + only." + ); + assert_eq!( + (!(word_cfg("unix") & word_cfg("windows"))).render_long_html(), + "This is supported on not (Unix and Windows)." + ); + assert_eq!( + ( + (word_cfg("debug_assertions") | word_cfg("windows")) & word_cfg("unix") + ).render_long_html(), + "This is supported on (debug-assertions enabled or Windows) and Unix\ + only." + ); + }) } } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 702031cfaca3..da52fd5aa372 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -102,7 +102,9 @@ pub fn main() { const STACK_SIZE: usize = 32_000_000; // 32MB env_logger::init(); let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || { - get_args().map(|args| main_args(&args)).unwrap_or(1) + syntax::with_globals(move || { + get_args().map(|args| main_args(&args)).unwrap_or(1) + }) }).unwrap().join().unwrap_or(101); process::exit(res as i32); } @@ -554,7 +556,8 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { }); let (tx, rx) = channel(); - rustc_driver::monitor(move || { + + rustc_driver::monitor(move || syntax::with_globals(move || { use rustc::session::config::Input; let (mut krate, renderinfo) = @@ -623,7 +626,7 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { let krate = pm.run_plugins(krate); tx.send(f(Output { krate: krate, renderinfo: renderinfo, passes: passes })).unwrap(); - }); + })); rx.recv().unwrap() } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index e4477bee5c0e..117b21d47587 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -35,6 +35,7 @@ use rustc_resolve::MakeGlobMap; use syntax::ast; use syntax::codemap::CodeMap; use syntax::feature_gate::UnstableFeatures; +use syntax::with_globals; use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName}; use errors; use errors::emitter::ColorConfig; @@ -518,7 +519,7 @@ impl Collector { let panic = io::set_panic(None); let print = io::set_print(None); match { - rustc_driver::in_rustc_thread(move || { + rustc_driver::in_rustc_thread(move || with_globals(move || { io::set_panic(panic); io::set_print(print); run_test(&test, @@ -536,7 +537,7 @@ impl Collector { &opts, maybe_sysroot, linker) - }) + })) } { Ok(()) => (), Err(err) => panic::resume_unwind(err), diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 07631e0dcfc1..8c24f36615bd 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -12,6 +12,7 @@ crate-type = ["dylib"] bitflags = "1.0" serialize = { path = "../libserialize" } log = "0.4" +scoped-tls = "0.1" syntax_pos = { path = "../libsyntax_pos" } rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } rustc_errors = { path = "../librustc_errors" } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 4818248129e7..f2cdcda98da5 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -30,15 +30,10 @@ use ptr::P; use symbol::Symbol; use tokenstream::{TokenStream, TokenTree, Delimited}; use util::ThinVec; +use GLOBALS; -use std::cell::RefCell; use std::iter; -thread_local! { - static USED_ATTRS: RefCell> = RefCell::new(Vec::new()); - static KNOWN_ATTRS: RefCell> = RefCell::new(Vec::new()); -} - enum AttrError { MultipleItem(Name), UnknownMetaItem(Name), @@ -65,22 +60,24 @@ fn handle_errors(diag: &Handler, span: Span, error: AttrError) { pub fn mark_used(attr: &Attribute) { debug!("Marking {:?} as used.", attr); let AttrId(id) = attr.id; - USED_ATTRS.with(|slot| { + GLOBALS.with(|globals| { + let mut slot = globals.used_attrs.lock(); let idx = (id / 64) as usize; let shift = id % 64; - if slot.borrow().len() <= idx { - slot.borrow_mut().resize(idx + 1, 0); + if slot.len() <= idx { + slot.resize(idx + 1, 0); } - slot.borrow_mut()[idx] |= 1 << shift; + slot[idx] |= 1 << shift; }); } pub fn is_used(attr: &Attribute) -> bool { let AttrId(id) = attr.id; - USED_ATTRS.with(|slot| { + GLOBALS.with(|globals| { + let slot = globals.used_attrs.lock(); let idx = (id / 64) as usize; let shift = id % 64; - slot.borrow().get(idx).map(|bits| bits & (1 << shift) != 0) + slot.get(idx).map(|bits| bits & (1 << shift) != 0) .unwrap_or(false) }) } @@ -88,22 +85,24 @@ pub fn is_used(attr: &Attribute) -> bool { pub fn mark_known(attr: &Attribute) { debug!("Marking {:?} as known.", attr); let AttrId(id) = attr.id; - KNOWN_ATTRS.with(|slot| { + GLOBALS.with(|globals| { + let mut slot = globals.known_attrs.lock(); let idx = (id / 64) as usize; let shift = id % 64; - if slot.borrow().len() <= idx { - slot.borrow_mut().resize(idx + 1, 0); + if slot.len() <= idx { + slot.resize(idx + 1, 0); } - slot.borrow_mut()[idx] |= 1 << shift; + slot[idx] |= 1 << shift; }); } pub fn is_known(attr: &Attribute) -> bool { let AttrId(id) = attr.id; - KNOWN_ATTRS.with(|slot| { + GLOBALS.with(|globals| { + let slot = globals.known_attrs.lock(); let idx = (id / 64) as usize; let shift = id % 64; - slot.borrow().get(idx).map(|bits| bits & (1 << shift) != 0) + slot.get(idx).map(|bits| bits & (1 << shift) != 0) .unwrap_or(false) }) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index bc1854d3cd89..2cf99e15d1f9 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1386,6 +1386,7 @@ mod tests { use util::parser_testing::{string_to_crate, matches_codepattern}; use print::pprust; use fold; + use with_globals; use super::*; // this version doesn't care about getting comments or docstrings in. @@ -1423,28 +1424,32 @@ mod tests { // make sure idents get transformed everywhere #[test] fn ident_transformation () { - let mut zz_fold = ToZzIdentFolder; - let ast = string_to_crate( - "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); - let folded_crate = zz_fold.fold_crate(ast); - assert_pred!( - matches_codepattern, - "matches_codepattern", - pprust::to_string(|s| fake_print_crate(s, &folded_crate)), - "#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()); + with_globals(|| { + let mut zz_fold = ToZzIdentFolder; + let ast = string_to_crate( + "#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string()); + let folded_crate = zz_fold.fold_crate(ast); + assert_pred!( + matches_codepattern, + "matches_codepattern", + pprust::to_string(|s| fake_print_crate(s, &folded_crate)), + "#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()); + }) } // even inside macro defs.... #[test] fn ident_transformation_in_defs () { - let mut zz_fold = ToZzIdentFolder; - let ast = string_to_crate( - "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ - (g $(d $d $e)+))} ".to_string()); - let folded_crate = zz_fold.fold_crate(ast); - assert_pred!( - matches_codepattern, - "matches_codepattern", - pprust::to_string(|s| fake_print_crate(s, &folded_crate)), - "macro_rules! zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)));".to_string()); + with_globals(|| { + let mut zz_fold = ToZzIdentFolder; + let ast = string_to_crate( + "macro_rules! a {(b $c:expr $(d $e:token)f+ => \ + (g $(d $d $e)+))} ".to_string()); + let folded_crate = zz_fold.fold_crate(ast); + assert_pred!( + matches_codepattern, + "matches_codepattern", + pprust::to_string(|s| fake_print_crate(s, &folded_crate)), + "macro_rules! zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)));".to_string()); + }) } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 50e94e5cba7a..5f58b3bc3a05 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -39,9 +39,12 @@ extern crate std_unicode; pub extern crate rustc_errors as errors; extern crate syntax_pos; extern crate rustc_data_structures; +#[macro_use] extern crate scoped_tls; extern crate serialize as rustc_serialize; // used by deriving +use rustc_data_structures::sync::Lock; + // A variant of 'try!' that panics on an Err. This is used as a crutch on the // way towards a non-panic!-prone parser. It should be used for fatal parsing // errors; eventually we plan to convert all code using panictry to just use @@ -72,6 +75,33 @@ macro_rules! unwrap_or { } } +struct Globals { + used_attrs: Lock>, + known_attrs: Lock>, + syntax_pos_globals: syntax_pos::Globals, +} + +impl Globals { + fn new() -> Globals { + Globals { + used_attrs: Lock::new(Vec::new()), + known_attrs: Lock::new(Vec::new()), + syntax_pos_globals: syntax_pos::Globals::new(), + } + } +} + +pub fn with_globals(f: F) -> R + where F: FnOnce() -> R +{ + let globals = Globals::new(); + GLOBALS.set(&globals, || { + syntax_pos::GLOBALS.set(&globals.syntax_pos_globals, f) + }) +} + +scoped_thread_local!(static GLOBALS: Globals); + #[macro_use] pub mod diagnostics { #[macro_use] diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index cdf38453d7ea..d0075c896567 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1766,6 +1766,7 @@ mod tests { use std::path::PathBuf; use diagnostics::plugin::ErrorMap; use rustc_data_structures::sync::Lock; + use with_globals; fn mk_sess(cm: Lrc) -> ParseSess { let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()), Some(cm.clone()), @@ -1794,33 +1795,35 @@ mod tests { #[test] fn t1() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - let mut string_reader = setup(&cm, - &sh, - "/* my source file */ fn main() { println!(\"zebra\"); }\n" - .to_string()); - let id = Ident::from_str("fn"); - assert_eq!(string_reader.next_token().tok, token::Comment); - assert_eq!(string_reader.next_token().tok, token::Whitespace); - let tok1 = string_reader.next_token(); - let tok2 = TokenAndSpan { - tok: token::Ident(id), - sp: Span::new(BytePos(21), BytePos(23), NO_EXPANSION), - }; - assert_eq!(tok1, tok2); - assert_eq!(string_reader.next_token().tok, token::Whitespace); - // the 'main' id is already read: - assert_eq!(string_reader.pos.clone(), BytePos(28)); - // read another token: - let tok3 = string_reader.next_token(); - let tok4 = TokenAndSpan { - tok: token::Ident(Ident::from_str("main")), - sp: Span::new(BytePos(24), BytePos(28), NO_EXPANSION), - }; - assert_eq!(tok3, tok4); - // the lparen is already read: - assert_eq!(string_reader.pos.clone(), BytePos(29)) + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + let mut string_reader = setup(&cm, + &sh, + "/* my source file */ fn main() { println!(\"zebra\"); }\n" + .to_string()); + let id = Ident::from_str("fn"); + assert_eq!(string_reader.next_token().tok, token::Comment); + assert_eq!(string_reader.next_token().tok, token::Whitespace); + let tok1 = string_reader.next_token(); + let tok2 = TokenAndSpan { + tok: token::Ident(id), + sp: Span::new(BytePos(21), BytePos(23), NO_EXPANSION), + }; + assert_eq!(tok1, tok2); + assert_eq!(string_reader.next_token().tok, token::Whitespace); + // the 'main' id is already read: + assert_eq!(string_reader.pos.clone(), BytePos(28)); + // read another token: + let tok3 = string_reader.next_token(); + let tok4 = TokenAndSpan { + tok: token::Ident(Ident::from_str("main")), + sp: Span::new(BytePos(24), BytePos(28), NO_EXPANSION), + }; + assert_eq!(tok3, tok4); + // the lparen is already read: + assert_eq!(string_reader.pos.clone(), BytePos(29)) + }) } // check that the given reader produces the desired stream @@ -1838,113 +1841,133 @@ mod tests { #[test] fn doublecolonparsing() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - check_tokenization(setup(&cm, &sh, "a b".to_string()), - vec![mk_ident("a"), token::Whitespace, mk_ident("b")]); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + check_tokenization(setup(&cm, &sh, "a b".to_string()), + vec![mk_ident("a"), token::Whitespace, mk_ident("b")]); + }) } #[test] fn dcparsing_2() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - check_tokenization(setup(&cm, &sh, "a::b".to_string()), - vec![mk_ident("a"), token::ModSep, mk_ident("b")]); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + check_tokenization(setup(&cm, &sh, "a::b".to_string()), + vec![mk_ident("a"), token::ModSep, mk_ident("b")]); + }) } #[test] fn dcparsing_3() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - check_tokenization(setup(&cm, &sh, "a ::b".to_string()), - vec![mk_ident("a"), token::Whitespace, token::ModSep, mk_ident("b")]); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + check_tokenization(setup(&cm, &sh, "a ::b".to_string()), + vec![mk_ident("a"), token::Whitespace, token::ModSep, mk_ident("b")]); + }) } #[test] fn dcparsing_4() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - check_tokenization(setup(&cm, &sh, "a:: b".to_string()), - vec![mk_ident("a"), token::ModSep, token::Whitespace, mk_ident("b")]); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + check_tokenization(setup(&cm, &sh, "a:: b".to_string()), + vec![mk_ident("a"), token::ModSep, token::Whitespace, mk_ident("b")]); + }) } #[test] fn character_a() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - assert_eq!(setup(&cm, &sh, "'a'".to_string()).next_token().tok, - token::Literal(token::Char(Symbol::intern("a")), None)); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + assert_eq!(setup(&cm, &sh, "'a'".to_string()).next_token().tok, + token::Literal(token::Char(Symbol::intern("a")), None)); + }) } #[test] fn character_space() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - assert_eq!(setup(&cm, &sh, "' '".to_string()).next_token().tok, - token::Literal(token::Char(Symbol::intern(" ")), None)); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + assert_eq!(setup(&cm, &sh, "' '".to_string()).next_token().tok, + token::Literal(token::Char(Symbol::intern(" ")), None)); + }) } #[test] fn character_escaped() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - assert_eq!(setup(&cm, &sh, "'\\n'".to_string()).next_token().tok, - token::Literal(token::Char(Symbol::intern("\\n")), None)); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + assert_eq!(setup(&cm, &sh, "'\\n'".to_string()).next_token().tok, + token::Literal(token::Char(Symbol::intern("\\n")), None)); + }) } #[test] fn lifetime_name() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - assert_eq!(setup(&cm, &sh, "'abc".to_string()).next_token().tok, - token::Lifetime(Ident::from_str("'abc"))); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + assert_eq!(setup(&cm, &sh, "'abc".to_string()).next_token().tok, + token::Lifetime(Ident::from_str("'abc"))); + }) } #[test] fn raw_string() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - assert_eq!(setup(&cm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()) - .next_token() - .tok, - token::Literal(token::StrRaw(Symbol::intern("\"#a\\b\x00c\""), 3), None)); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + assert_eq!(setup(&cm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()) + .next_token() + .tok, + token::Literal(token::StrRaw(Symbol::intern("\"#a\\b\x00c\""), 3), None)); + }) } #[test] fn literal_suffixes() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - macro_rules! test { - ($input: expr, $tok_type: ident, $tok_contents: expr) => {{ - assert_eq!(setup(&cm, &sh, format!("{}suffix", $input)).next_token().tok, - token::Literal(token::$tok_type(Symbol::intern($tok_contents)), - Some(Symbol::intern("suffix")))); - // with a whitespace separator: - assert_eq!(setup(&cm, &sh, format!("{} suffix", $input)).next_token().tok, - token::Literal(token::$tok_type(Symbol::intern($tok_contents)), - None)); - }} - } + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + macro_rules! test { + ($input: expr, $tok_type: ident, $tok_contents: expr) => {{ + assert_eq!(setup(&cm, &sh, format!("{}suffix", $input)).next_token().tok, + token::Literal(token::$tok_type(Symbol::intern($tok_contents)), + Some(Symbol::intern("suffix")))); + // with a whitespace separator: + assert_eq!(setup(&cm, &sh, format!("{} suffix", $input)).next_token().tok, + token::Literal(token::$tok_type(Symbol::intern($tok_contents)), + None)); + }} + } - test!("'a'", Char, "a"); - test!("b'a'", Byte, "a"); - test!("\"a\"", Str_, "a"); - test!("b\"a\"", ByteStr, "a"); - test!("1234", Integer, "1234"); - test!("0b101", Integer, "0b101"); - test!("0xABC", Integer, "0xABC"); - test!("1.0", Float, "1.0"); - test!("1.0e10", Float, "1.0e10"); + test!("'a'", Char, "a"); + test!("b'a'", Byte, "a"); + test!("\"a\"", Str_, "a"); + test!("b\"a\"", ByteStr, "a"); + test!("1234", Integer, "1234"); + test!("0b101", Integer, "0b101"); + test!("0xABC", Integer, "0xABC"); + test!("1.0", Float, "1.0"); + test!("1.0e10", Float, "1.0e10"); - assert_eq!(setup(&cm, &sh, "2us".to_string()).next_token().tok, - token::Literal(token::Integer(Symbol::intern("2")), - Some(Symbol::intern("us")))); - assert_eq!(setup(&cm, &sh, "r###\"raw\"###suffix".to_string()).next_token().tok, - token::Literal(token::StrRaw(Symbol::intern("raw"), 3), - Some(Symbol::intern("suffix")))); - assert_eq!(setup(&cm, &sh, "br###\"raw\"###suffix".to_string()).next_token().tok, - token::Literal(token::ByteStrRaw(Symbol::intern("raw"), 3), - Some(Symbol::intern("suffix")))); + assert_eq!(setup(&cm, &sh, "2us".to_string()).next_token().tok, + token::Literal(token::Integer(Symbol::intern("2")), + Some(Symbol::intern("us")))); + assert_eq!(setup(&cm, &sh, "r###\"raw\"###suffix".to_string()).next_token().tok, + token::Literal(token::StrRaw(Symbol::intern("raw"), 3), + Some(Symbol::intern("suffix")))); + assert_eq!(setup(&cm, &sh, "br###\"raw\"###suffix".to_string()).next_token().tok, + token::Literal(token::ByteStrRaw(Symbol::intern("raw"), 3), + Some(Symbol::intern("suffix")))); + }) } #[test] @@ -1956,27 +1979,31 @@ mod tests { #[test] fn nested_block_comments() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - let mut lexer = setup(&cm, &sh, "/* /* */ */'a'".to_string()); - match lexer.next_token().tok { - token::Comment => {} - _ => panic!("expected a comment!"), - } - assert_eq!(lexer.next_token().tok, - token::Literal(token::Char(Symbol::intern("a")), None)); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + let mut lexer = setup(&cm, &sh, "/* /* */ */'a'".to_string()); + match lexer.next_token().tok { + token::Comment => {} + _ => panic!("expected a comment!"), + } + assert_eq!(lexer.next_token().tok, + token::Literal(token::Char(Symbol::intern("a")), None)); + }) } #[test] fn crlf_comments() { - let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); - let sh = mk_sess(cm.clone()); - let mut lexer = setup(&cm, &sh, "// test\r\n/// test\r\n".to_string()); - let comment = lexer.next_token(); - assert_eq!(comment.tok, token::Comment); - assert_eq!((comment.sp.lo(), comment.sp.hi()), (BytePos(0), BytePos(7))); - assert_eq!(lexer.next_token().tok, token::Whitespace); - assert_eq!(lexer.next_token().tok, - token::DocComment(Symbol::intern("/// test"))); + with_globals(|| { + let cm = Lrc::new(CodeMap::new(FilePathMapping::empty())); + let sh = mk_sess(cm.clone()); + let mut lexer = setup(&cm, &sh, "// test\r\n/// test\r\n".to_string()); + let comment = lexer.next_token(); + assert_eq!(comment.tok, token::Comment); + assert_eq!((comment.sp.lo(), comment.sp.hi()), (BytePos(0), BytePos(7))); + assert_eq!(lexer.next_token().tok, token::Whitespace); + assert_eq!(lexer.next_token().tok, + token::DocComment(Symbol::intern("/// test"))); + }) } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 3fb0c209f70f..ff097c362fe6 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -680,6 +680,7 @@ mod tests { use util::parser_testing::{string_to_stream, string_to_parser}; use util::parser_testing::{string_to_expr, string_to_item, string_to_stmt}; use util::ThinVec; + use with_globals; // produce a syntax_pos::span fn sp(a: u32, b: u32) -> Span { @@ -691,156 +692,170 @@ mod tests { } #[test] fn path_exprs_1() { - assert!(string_to_expr("a".to_string()) == - P(ast::Expr{ - id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Path(None, ast::Path { + with_globals(|| { + assert!(string_to_expr("a".to_string()) == + P(ast::Expr{ + id: ast::DUMMY_NODE_ID, + node: ast::ExprKind::Path(None, ast::Path { + span: sp(0, 1), + segments: vec![str2seg("a", 0, 1)], + }), span: sp(0, 1), - segments: vec![str2seg("a", 0, 1)], - }), - span: sp(0, 1), - attrs: ThinVec::new(), - })) + attrs: ThinVec::new(), + })) + }) } #[test] fn path_exprs_2 () { - assert!(string_to_expr("::a::b".to_string()) == - P(ast::Expr { - id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Path(None, ast::Path { + with_globals(|| { + assert!(string_to_expr("::a::b".to_string()) == + P(ast::Expr { + id: ast::DUMMY_NODE_ID, + node: ast::ExprKind::Path(None, ast::Path { + span: sp(0, 6), + segments: vec![ast::PathSegment::crate_root(sp(0, 2)), + str2seg("a", 2, 3), + str2seg("b", 5, 6)] + }), span: sp(0, 6), - segments: vec![ast::PathSegment::crate_root(sp(0, 2)), - str2seg("a", 2, 3), - str2seg("b", 5, 6)] - }), - span: sp(0, 6), - attrs: ThinVec::new(), - })) + attrs: ThinVec::new(), + })) + }) } #[should_panic] #[test] fn bad_path_expr_1() { - string_to_expr("::abc::def::return".to_string()); + with_globals(|| { + string_to_expr("::abc::def::return".to_string()); + }) } // check the token-tree-ization of macros #[test] fn string_to_tts_macro () { - let tts: Vec<_> = - string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect(); - let tts: &[TokenTree] = &tts[..]; + with_globals(|| { + let tts: Vec<_> = + string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect(); + let tts: &[TokenTree] = &tts[..]; - match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) { - ( - 4, - Some(&TokenTree::Token(_, token::Ident(name_macro_rules))), - Some(&TokenTree::Token(_, token::Not)), - Some(&TokenTree::Token(_, token::Ident(name_zip))), - Some(&TokenTree::Delimited(_, ref macro_delimed)), - ) - if name_macro_rules.name == "macro_rules" - && name_zip.name == "zip" => { - let tts = ¯o_delimed.stream().trees().collect::>(); - match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) { - ( - 3, - Some(&TokenTree::Delimited(_, ref first_delimed)), - Some(&TokenTree::Token(_, token::FatArrow)), - Some(&TokenTree::Delimited(_, ref second_delimed)), - ) - if macro_delimed.delim == token::Paren => { - let tts = &first_delimed.stream().trees().collect::>(); - match (tts.len(), tts.get(0), tts.get(1)) { - ( - 2, - Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident))), - ) - if first_delimed.delim == token::Paren && ident.name == "a" => {}, - _ => panic!("value 3: {:?}", *first_delimed), - } - let tts = &second_delimed.stream().trees().collect::>(); - match (tts.len(), tts.get(0), tts.get(1)) { - ( - 2, - Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident))), - ) - if second_delimed.delim == token::Paren - && ident.name == "a" => {}, - _ => panic!("value 4: {:?}", *second_delimed), - } - }, - _ => panic!("value 2: {:?}", *macro_delimed), - } - }, - _ => panic!("value: {:?}",tts), - } + match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) { + ( + 4, + Some(&TokenTree::Token(_, token::Ident(name_macro_rules))), + Some(&TokenTree::Token(_, token::Not)), + Some(&TokenTree::Token(_, token::Ident(name_zip))), + Some(&TokenTree::Delimited(_, ref macro_delimed)), + ) + if name_macro_rules.name == "macro_rules" + && name_zip.name == "zip" => { + let tts = ¯o_delimed.stream().trees().collect::>(); + match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) { + ( + 3, + Some(&TokenTree::Delimited(_, ref first_delimed)), + Some(&TokenTree::Token(_, token::FatArrow)), + Some(&TokenTree::Delimited(_, ref second_delimed)), + ) + if macro_delimed.delim == token::Paren => { + let tts = &first_delimed.stream().trees().collect::>(); + match (tts.len(), tts.get(0), tts.get(1)) { + ( + 2, + Some(&TokenTree::Token(_, token::Dollar)), + Some(&TokenTree::Token(_, token::Ident(ident))), + ) + if first_delimed.delim == token::Paren && ident.name == "a" => {}, + _ => panic!("value 3: {:?}", *first_delimed), + } + let tts = &second_delimed.stream().trees().collect::>(); + match (tts.len(), tts.get(0), tts.get(1)) { + ( + 2, + Some(&TokenTree::Token(_, token::Dollar)), + Some(&TokenTree::Token(_, token::Ident(ident))), + ) + if second_delimed.delim == token::Paren + && ident.name == "a" => {}, + _ => panic!("value 4: {:?}", *second_delimed), + } + }, + _ => panic!("value 2: {:?}", *macro_delimed), + } + }, + _ => panic!("value: {:?}",tts), + } + }) } #[test] fn string_to_tts_1() { - let tts = string_to_stream("fn a (b : i32) { b; }".to_string()); + with_globals(|| { + let tts = string_to_stream("fn a (b : i32) { b; }".to_string()); - let expected = TokenStream::concat(vec![ - TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))).into(), - TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))).into(), - TokenTree::Delimited( - sp(5, 14), - tokenstream::Delimited { - delim: token::DelimToken::Paren, - tts: TokenStream::concat(vec![ - TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))).into(), - TokenTree::Token(sp(8, 9), token::Colon).into(), - TokenTree::Token(sp(10, 13), token::Ident(Ident::from_str("i32"))).into(), - ]).into(), - }).into(), - TokenTree::Delimited( - sp(15, 21), - tokenstream::Delimited { - delim: token::DelimToken::Brace, - tts: TokenStream::concat(vec![ - TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))).into(), - TokenTree::Token(sp(18, 19), token::Semi).into(), - ]).into(), - }).into() - ]); + let expected = TokenStream::concat(vec![ + TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))).into(), + TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))).into(), + TokenTree::Delimited( + sp(5, 14), + tokenstream::Delimited { + delim: token::DelimToken::Paren, + tts: TokenStream::concat(vec![ + TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))).into(), + TokenTree::Token(sp(8, 9), token::Colon).into(), + TokenTree::Token(sp(10, 13), + token::Ident(Ident::from_str("i32"))).into(), + ]).into(), + }).into(), + TokenTree::Delimited( + sp(15, 21), + tokenstream::Delimited { + delim: token::DelimToken::Brace, + tts: TokenStream::concat(vec![ + TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))).into(), + TokenTree::Token(sp(18, 19), token::Semi).into(), + ]).into(), + }).into() + ]); - assert_eq!(tts, expected); + assert_eq!(tts, expected); + }) } #[test] fn ret_expr() { - assert!(string_to_expr("return d".to_string()) == - P(ast::Expr{ - id: ast::DUMMY_NODE_ID, - node:ast::ExprKind::Ret(Some(P(ast::Expr{ + with_globals(|| { + assert!(string_to_expr("return d".to_string()) == + P(ast::Expr{ id: ast::DUMMY_NODE_ID, - node:ast::ExprKind::Path(None, ast::Path{ - span: sp(7, 8), - segments: vec![str2seg("d", 7, 8)], - }), - span:sp(7,8), + node:ast::ExprKind::Ret(Some(P(ast::Expr{ + id: ast::DUMMY_NODE_ID, + node:ast::ExprKind::Path(None, ast::Path{ + span: sp(7, 8), + segments: vec![str2seg("d", 7, 8)], + }), + span:sp(7,8), + attrs: ThinVec::new(), + }))), + span:sp(0,8), attrs: ThinVec::new(), - }))), - span:sp(0,8), - attrs: ThinVec::new(), - })) + })) + }) } #[test] fn parse_stmt_1 () { - assert!(string_to_stmt("b;".to_string()) == - Some(ast::Stmt { - node: ast::StmtKind::Expr(P(ast::Expr { - id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Path(None, ast::Path { - span:sp(0,1), - segments: vec![str2seg("b", 0, 1)], - }), - span: sp(0,1), - attrs: ThinVec::new()})), - id: ast::DUMMY_NODE_ID, - span: sp(0,1)})) - + with_globals(|| { + assert!(string_to_stmt("b;".to_string()) == + Some(ast::Stmt { + node: ast::StmtKind::Expr(P(ast::Expr { + id: ast::DUMMY_NODE_ID, + node: ast::ExprKind::Path(None, ast::Path { + span:sp(0,1), + segments: vec![str2seg("b", 0, 1)], + }), + span: sp(0,1), + attrs: ThinVec::new()})), + id: ast::DUMMY_NODE_ID, + span: sp(0,1)})) + }) } fn parser_done(p: Parser){ @@ -848,120 +863,128 @@ mod tests { } #[test] fn parse_ident_pat () { - let sess = ParseSess::new(FilePathMapping::empty()); - let mut parser = string_to_parser(&sess, "b".to_string()); - assert!(panictry!(parser.parse_pat()) - == P(ast::Pat{ - id: ast::DUMMY_NODE_ID, - node: PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable), - Spanned{ span:sp(0, 1), - node: Ident::from_str("b") - }, - None), - span: sp(0,1)})); - parser_done(parser); + with_globals(|| { + let sess = ParseSess::new(FilePathMapping::empty()); + let mut parser = string_to_parser(&sess, "b".to_string()); + assert!(panictry!(parser.parse_pat()) + == P(ast::Pat{ + id: ast::DUMMY_NODE_ID, + node: PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable), + Spanned{ span:sp(0, 1), + node: Ident::from_str("b") + }, + None), + span: sp(0,1)})); + parser_done(parser); + }) } // check the contents of the tt manually: #[test] fn parse_fundecl () { - // this test depends on the intern order of "fn" and "i32" - let item = string_to_item("fn a (b : i32) { b; }".to_string()).map(|m| { - m.map(|mut m| { - m.tokens = None; - m - }) - }); - assert_eq!(item, - Some( - P(ast::Item{ident:Ident::from_str("a"), - attrs:Vec::new(), - id: ast::DUMMY_NODE_ID, - tokens: None, - node: ast::ItemKind::Fn(P(ast::FnDecl { - inputs: vec![ast::Arg{ - ty: P(ast::Ty{id: ast::DUMMY_NODE_ID, - node: ast::TyKind::Path(None, ast::Path{ - span:sp(10,13), - segments: vec![str2seg("i32", 10, 13)], + with_globals(|| { + // this test depends on the intern order of "fn" and "i32" + let item = string_to_item("fn a (b : i32) { b; }".to_string()).map(|m| { + m.map(|mut m| { + m.tokens = None; + m + }) + }); + assert_eq!(item, + Some( + P(ast::Item{ident:Ident::from_str("a"), + attrs:Vec::new(), + id: ast::DUMMY_NODE_ID, + tokens: None, + node: ast::ItemKind::Fn(P(ast::FnDecl { + inputs: vec![ast::Arg{ + ty: P(ast::Ty{id: ast::DUMMY_NODE_ID, + node: ast::TyKind::Path(None, ast::Path{ + span:sp(10,13), + segments: vec![str2seg("i32", 10, 13)], + }), + span:sp(10,13) }), - span:sp(10,13) - }), - pat: P(ast::Pat { - id: ast::DUMMY_NODE_ID, - node: PatKind::Ident( - ast::BindingMode::ByValue( - ast::Mutability::Immutable), - Spanned{ - span: sp(6,7), - node: Ident::from_str("b")}, - None - ), - span: sp(6,7) - }), - id: ast::DUMMY_NODE_ID - }], - output: ast::FunctionRetTy::Default(sp(15, 15)), - variadic: false - }), - ast::Unsafety::Normal, - Spanned { - span: sp(0,2), - node: ast::Constness::NotConst, - }, - Abi::Rust, - ast::Generics{ - params: Vec::new(), - where_clause: ast::WhereClause { + pat: P(ast::Pat { id: ast::DUMMY_NODE_ID, - predicates: Vec::new(), + node: PatKind::Ident( + ast::BindingMode::ByValue( + ast::Mutability::Immutable), + Spanned{ + span: sp(6,7), + node: Ident::from_str("b")}, + None + ), + span: sp(6,7) + }), + id: ast::DUMMY_NODE_ID + }], + output: ast::FunctionRetTy::Default(sp(15, 15)), + variadic: false + }), + ast::Unsafety::Normal, + Spanned { + span: sp(0,2), + node: ast::Constness::NotConst, + }, + Abi::Rust, + ast::Generics{ + params: Vec::new(), + where_clause: ast::WhereClause { + id: ast::DUMMY_NODE_ID, + predicates: Vec::new(), + span: syntax_pos::DUMMY_SP, + }, span: syntax_pos::DUMMY_SP, }, - span: syntax_pos::DUMMY_SP, - }, - P(ast::Block { - stmts: vec![ast::Stmt { - node: ast::StmtKind::Semi(P(ast::Expr{ + P(ast::Block { + stmts: vec![ast::Stmt { + node: ast::StmtKind::Semi(P(ast::Expr{ + id: ast::DUMMY_NODE_ID, + node: ast::ExprKind::Path(None, + ast::Path{ + span:sp(17,18), + segments: vec![str2seg("b", 17, 18)], + }), + span: sp(17,18), + attrs: ThinVec::new()})), id: ast::DUMMY_NODE_ID, - node: ast::ExprKind::Path(None, - ast::Path{ - span:sp(17,18), - segments: vec![str2seg("b", 17, 18)], - }), - span: sp(17,18), - attrs: ThinVec::new()})), + span: sp(17,19)}], id: ast::DUMMY_NODE_ID, - span: sp(17,19)}], - id: ast::DUMMY_NODE_ID, - rules: ast::BlockCheckMode::Default, // no idea - span: sp(15,21), - recovered: false, - })), - vis: respan(sp(0, 0), ast::VisibilityKind::Inherited), - span: sp(0,21)}))); + rules: ast::BlockCheckMode::Default, // no idea + span: sp(15,21), + recovered: false, + })), + vis: respan(sp(0, 0), ast::VisibilityKind::Inherited), + span: sp(0,21)}))); + }) } #[test] fn parse_use() { - let use_s = "use foo::bar::baz;"; - let vitem = string_to_item(use_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], use_s); + with_globals(|| { + let use_s = "use foo::bar::baz;"; + let vitem = string_to_item(use_s.to_string()).unwrap(); + let vitem_s = item_to_string(&vitem); + assert_eq!(&vitem_s[..], use_s); - let use_s = "use foo::bar as baz;"; - let vitem = string_to_item(use_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], use_s); + let use_s = "use foo::bar as baz;"; + let vitem = string_to_item(use_s.to_string()).unwrap(); + let vitem_s = item_to_string(&vitem); + assert_eq!(&vitem_s[..], use_s); + }) } #[test] fn parse_extern_crate() { - let ex_s = "extern crate foo;"; - let vitem = string_to_item(ex_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], ex_s); + with_globals(|| { + let ex_s = "extern crate foo;"; + let vitem = string_to_item(ex_s.to_string()).unwrap(); + let vitem_s = item_to_string(&vitem); + assert_eq!(&vitem_s[..], ex_s); - let ex_s = "extern crate foo as bar;"; - let vitem = string_to_item(ex_s.to_string()).unwrap(); - let vitem_s = item_to_string(&vitem); - assert_eq!(&vitem_s[..], ex_s); + let ex_s = "extern crate foo as bar;"; + let vitem = string_to_item(ex_s.to_string()).unwrap(); + let vitem_s = item_to_string(&vitem); + assert_eq!(&vitem_s[..], ex_s); + }) } fn get_spans_of_pat_idents(src: &str) -> Vec { @@ -988,31 +1011,36 @@ mod tests { } #[test] fn span_of_self_arg_pat_idents_are_correct() { + with_globals(|| { - let srcs = ["impl z { fn a (&self, &myarg: i32) {} }", - "impl z { fn a (&mut self, &myarg: i32) {} }", - "impl z { fn a (&'a self, &myarg: i32) {} }", - "impl z { fn a (self, &myarg: i32) {} }", - "impl z { fn a (self: Foo, &myarg: i32) {} }", - ]; + let srcs = ["impl z { fn a (&self, &myarg: i32) {} }", + "impl z { fn a (&mut self, &myarg: i32) {} }", + "impl z { fn a (&'a self, &myarg: i32) {} }", + "impl z { fn a (self, &myarg: i32) {} }", + "impl z { fn a (self: Foo, &myarg: i32) {} }", + ]; - for &src in &srcs { - let spans = get_spans_of_pat_idents(src); - let (lo, hi) = (spans[0].lo(), spans[0].hi()); - assert!("self" == &src[lo.to_usize()..hi.to_usize()], - "\"{}\" != \"self\". src=\"{}\"", - &src[lo.to_usize()..hi.to_usize()], src) - } + for &src in &srcs { + let spans = get_spans_of_pat_idents(src); + let (lo, hi) = (spans[0].lo(), spans[0].hi()); + assert!("self" == &src[lo.to_usize()..hi.to_usize()], + "\"{}\" != \"self\". src=\"{}\"", + &src[lo.to_usize()..hi.to_usize()], src) + } + }) } #[test] fn parse_exprs () { - // just make sure that they parse.... - string_to_expr("3 + 4".to_string()); - string_to_expr("a::z.froob(b,&(987+3))".to_string()); + with_globals(|| { + // just make sure that they parse.... + string_to_expr("3 + 4".to_string()); + string_to_expr("a::z.froob(b,&(987+3))".to_string()); + }) } #[test] fn attrs_fix_bug () { - string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) + with_globals(|| { + string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) -> Result, String> { #[cfg(windows)] fn wb() -> c_int { @@ -1024,49 +1052,54 @@ mod tests { let mut fflags: c_int = wb(); }".to_string()); + }) } #[test] fn crlf_doc_comments() { - let sess = ParseSess::new(FilePathMapping::empty()); + with_globals(|| { + let sess = ParseSess::new(FilePathMapping::empty()); - let name = FileName::Custom("source".to_string()); - let source = "/// doc comment\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name.clone(), source, &sess) - .unwrap().unwrap(); - let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); - assert_eq!(doc, "/// doc comment"); + let name = FileName::Custom("source".to_string()); + let source = "/// doc comment\r\nfn foo() {}".to_string(); + let item = parse_item_from_source_str(name.clone(), source, &sess) + .unwrap().unwrap(); + let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); + assert_eq!(doc, "/// doc comment"); - let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name.clone(), source, &sess) - .unwrap().unwrap(); - let docs = item.attrs.iter().filter(|a| a.path == "doc") - .map(|a| a.value_str().unwrap().to_string()).collect::>(); - let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()]; - assert_eq!(&docs[..], b); + let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string(); + let item = parse_item_from_source_str(name.clone(), source, &sess) + .unwrap().unwrap(); + let docs = item.attrs.iter().filter(|a| a.path == "doc") + .map(|a| a.value_str().unwrap().to_string()).collect::>(); + let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()]; + assert_eq!(&docs[..], b); - let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); - let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap(); - let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); - assert_eq!(doc, "/** doc comment\n * with CRLF */"); + let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string(); + let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap(); + let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap(); + assert_eq!(doc, "/** doc comment\n * with CRLF */"); + }); } #[test] fn ttdelim_span() { - let sess = ParseSess::new(FilePathMapping::empty()); - let expr = parse::parse_expr_from_source_str(PathBuf::from("foo").into(), - "foo!( fn main() { body } )".to_string(), &sess).unwrap(); + with_globals(|| { + let sess = ParseSess::new(FilePathMapping::empty()); + let expr = parse::parse_expr_from_source_str(PathBuf::from("foo").into(), + "foo!( fn main() { body } )".to_string(), &sess).unwrap(); - let tts: Vec<_> = match expr.node { - ast::ExprKind::Mac(ref mac) => mac.node.stream().trees().collect(), - _ => panic!("not a macro"), - }; + let tts: Vec<_> = match expr.node { + ast::ExprKind::Mac(ref mac) => mac.node.stream().trees().collect(), + _ => panic!("not a macro"), + }; - let span = tts.iter().rev().next().unwrap().span(); + let span = tts.iter().rev().next().unwrap().span(); - match sess.codemap().span_to_snippet(span) { - Ok(s) => assert_eq!(&s[..], "{ body }"), - Err(_) => panic!("could not get snippet"), - } + match sess.codemap().span_to_snippet(span) { + Ok(s) => assert_eq!(&s[..], "{ body }"), + Err(_) => panic!("could not get snippet"), + } + }); } // This tests that when parsing a string (rather than a file) we don't try @@ -1074,17 +1107,19 @@ mod tests { // See `recurse_into_file_modules` in the parser. #[test] fn out_of_line_mod() { - let sess = ParseSess::new(FilePathMapping::empty()); - let item = parse_item_from_source_str( - PathBuf::from("foo").into(), - "mod foo { struct S; mod this_does_not_exist; }".to_owned(), - &sess, - ).unwrap().unwrap(); + with_globals(|| { + let sess = ParseSess::new(FilePathMapping::empty()); + let item = parse_item_from_source_str( + PathBuf::from("foo").into(), + "mod foo { struct S; mod this_does_not_exist; }".to_owned(), + &sess, + ).unwrap().unwrap(); - if let ast::ItemKind::Mod(ref m) = item.node { - assert!(m.items.len() == 2); - } else { - panic!(); - } + if let ast::ItemKind::Mod(ref m) = item.node { + assert!(m.items.len() == 2); + } else { + panic!(); + } + }); } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 77afafbb4e00..1cf2b7a44bc1 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -3178,36 +3178,41 @@ mod tests { use ast; use codemap; use syntax_pos; + use with_globals; #[test] fn test_fun_to_string() { - let abba_ident = ast::Ident::from_str("abba"); + with_globals(|| { + let abba_ident = ast::Ident::from_str("abba"); - let decl = ast::FnDecl { - inputs: Vec::new(), - output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP), - variadic: false - }; - let generics = ast::Generics::default(); - assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal, - ast::Constness::NotConst, - abba_ident, &generics), - "fn abba()"); + let decl = ast::FnDecl { + inputs: Vec::new(), + output: ast::FunctionRetTy::Default(syntax_pos::DUMMY_SP), + variadic: false + }; + let generics = ast::Generics::default(); + assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal, + ast::Constness::NotConst, + abba_ident, &generics), + "fn abba()"); + }) } #[test] fn test_variant_to_string() { - let ident = ast::Ident::from_str("principal_skinner"); + with_globals(|| { + let ident = ast::Ident::from_str("principal_skinner"); - let var = codemap::respan(syntax_pos::DUMMY_SP, ast::Variant_ { - name: ident, - attrs: Vec::new(), - // making this up as I go.... ? - data: ast::VariantData::Unit(ast::DUMMY_NODE_ID), - disr_expr: None, - }); + let var = codemap::respan(syntax_pos::DUMMY_SP, ast::Variant_ { + name: ident, + attrs: Vec::new(), + // making this up as I go.... ? + data: ast::VariantData::Unit(ast::DUMMY_NODE_ID), + disr_expr: None, + }); - let varstr = variant_to_string(&var); - assert_eq!(varstr, "principal_skinner"); + let varstr = variant_to_string(&var); + assert_eq!(varstr, "principal_skinner"); + }) } } diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs index 772334e3ef13..81dcc1998edd 100644 --- a/src/libsyntax/test_snippet.rs +++ b/src/libsyntax/test_snippet.rs @@ -18,6 +18,7 @@ use std::str; use std::sync::{Arc, Mutex}; use std::path::Path; use syntax_pos::{BytePos, NO_EXPANSION, Span, MultiSpan}; +use with_globals; /// Identify a position in the text by the Nth occurrence of a string. struct Position { @@ -46,37 +47,39 @@ impl Write for Shared { } fn test_harness(file_text: &str, span_labels: Vec, expected_output: &str) { - let output = Arc::new(Mutex::new(Vec::new())); + with_globals(|| { + let output = Arc::new(Mutex::new(Vec::new())); - let code_map = Lrc::new(CodeMap::new(FilePathMapping::empty())); - code_map.new_filemap_and_lines(Path::new("test.rs"), &file_text); + let code_map = Lrc::new(CodeMap::new(FilePathMapping::empty())); + code_map.new_filemap_and_lines(Path::new("test.rs"), &file_text); - let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end); - let mut msp = MultiSpan::from_span(primary_span); - for span_label in span_labels { - let span = make_span(&file_text, &span_label.start, &span_label.end); - msp.push_span_label(span, span_label.label.to_string()); - println!("span: {:?} label: {:?}", span, span_label.label); - println!("text: {:?}", code_map.span_to_snippet(span)); - } + let primary_span = make_span(&file_text, &span_labels[0].start, &span_labels[0].end); + let mut msp = MultiSpan::from_span(primary_span); + for span_label in span_labels { + let span = make_span(&file_text, &span_label.start, &span_label.end); + msp.push_span_label(span, span_label.label.to_string()); + println!("span: {:?} label: {:?}", span, span_label.label); + println!("text: {:?}", code_map.span_to_snippet(span)); + } - let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }), - Some(code_map.clone()), - false, - false); - let handler = Handler::with_emitter(true, false, Box::new(emitter)); - handler.span_err(msp, "foo"); + let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }), + Some(code_map.clone()), + false, + false); + let handler = Handler::with_emitter(true, false, Box::new(emitter)); + handler.span_err(msp, "foo"); - assert!(expected_output.chars().next() == Some('\n'), - "expected output should begin with newline"); - let expected_output = &expected_output[1..]; + assert!(expected_output.chars().next() == Some('\n'), + "expected output should begin with newline"); + let expected_output = &expected_output[1..]; - let bytes = output.lock().unwrap(); - let actual_output = str::from_utf8(&bytes).unwrap(); - println!("expected output:\n------\n{}------", expected_output); - println!("actual output:\n------\n{}------", actual_output); + let bytes = output.lock().unwrap(); + let actual_output = str::from_utf8(&bytes).unwrap(); + println!("expected output:\n------\n{}------", expected_output); + println!("actual output:\n------\n{}------", actual_output); - assert!(expected_output == actual_output) + assert!(expected_output == actual_output) + }) } fn make_span(file_text: &str, start: &Position, end: &Position) -> Span { diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index ad04b6ab2b55..1219e909e121 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -599,6 +599,7 @@ impl Hash for ThinTokenStream { mod tests { use super::*; use syntax::ast::Ident; + use with_globals; use syntax_pos::{Span, BytePos, NO_EXPANSION}; use parse::token::Token; use util::parser_testing::string_to_stream; @@ -613,67 +614,83 @@ mod tests { #[test] fn test_concat() { - let test_res = string_to_ts("foo::bar::baz"); - let test_fst = string_to_ts("foo::bar"); - let test_snd = string_to_ts("::baz"); - let eq_res = TokenStream::concat(vec![test_fst, test_snd]); - assert_eq!(test_res.trees().count(), 5); - assert_eq!(eq_res.trees().count(), 5); - assert_eq!(test_res.eq_unspanned(&eq_res), true); + with_globals(|| { + let test_res = string_to_ts("foo::bar::baz"); + let test_fst = string_to_ts("foo::bar"); + let test_snd = string_to_ts("::baz"); + let eq_res = TokenStream::concat(vec![test_fst, test_snd]); + assert_eq!(test_res.trees().count(), 5); + assert_eq!(eq_res.trees().count(), 5); + assert_eq!(test_res.eq_unspanned(&eq_res), true); + }) } #[test] fn test_to_from_bijection() { - let test_start = string_to_ts("foo::bar(baz)"); - let test_end = test_start.trees().collect(); - assert_eq!(test_start, test_end) + with_globals(|| { + let test_start = string_to_ts("foo::bar(baz)"); + let test_end = test_start.trees().collect(); + assert_eq!(test_start, test_end) + }) } #[test] fn test_eq_0() { - let test_res = string_to_ts("foo"); - let test_eqs = string_to_ts("foo"); - assert_eq!(test_res, test_eqs) + with_globals(|| { + let test_res = string_to_ts("foo"); + let test_eqs = string_to_ts("foo"); + assert_eq!(test_res, test_eqs) + }) } #[test] fn test_eq_1() { - let test_res = string_to_ts("::bar::baz"); - let test_eqs = string_to_ts("::bar::baz"); - assert_eq!(test_res, test_eqs) + with_globals(|| { + let test_res = string_to_ts("::bar::baz"); + let test_eqs = string_to_ts("::bar::baz"); + assert_eq!(test_res, test_eqs) + }) } #[test] fn test_eq_3() { - let test_res = string_to_ts(""); - let test_eqs = string_to_ts(""); - assert_eq!(test_res, test_eqs) + with_globals(|| { + let test_res = string_to_ts(""); + let test_eqs = string_to_ts(""); + assert_eq!(test_res, test_eqs) + }) } #[test] fn test_diseq_0() { - let test_res = string_to_ts("::bar::baz"); - let test_eqs = string_to_ts("bar::baz"); - assert_eq!(test_res == test_eqs, false) + with_globals(|| { + let test_res = string_to_ts("::bar::baz"); + let test_eqs = string_to_ts("bar::baz"); + assert_eq!(test_res == test_eqs, false) + }) } #[test] fn test_diseq_1() { - let test_res = string_to_ts("(bar,baz)"); - let test_eqs = string_to_ts("bar,baz"); - assert_eq!(test_res == test_eqs, false) + with_globals(|| { + let test_res = string_to_ts("(bar,baz)"); + let test_eqs = string_to_ts("bar,baz"); + assert_eq!(test_res == test_eqs, false) + }) } #[test] fn test_is_empty() { - let test0: TokenStream = Vec::::new().into_iter().collect(); - let test1: TokenStream = - TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"))).into(); - let test2 = string_to_ts("foo(bar::baz)"); + with_globals(|| { + let test0: TokenStream = Vec::::new().into_iter().collect(); + let test1: TokenStream = + TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"))).into(); + let test2 = string_to_ts("foo(bar::baz)"); - assert_eq!(test0.is_empty(), true); - assert_eq!(test1.is_empty(), false); - assert_eq!(test2.is_empty(), false); + assert_eq!(test0.is_empty(), true); + assert_eq!(test1.is_empty(), false); + assert_eq!(test2.is_empty(), false); + }) } #[test] diff --git a/src/libsyntax_pos/Cargo.toml b/src/libsyntax_pos/Cargo.toml index aad2155157d8..b9637b1855ef 100644 --- a/src/libsyntax_pos/Cargo.toml +++ b/src/libsyntax_pos/Cargo.toml @@ -11,4 +11,5 @@ crate-type = ["dylib"] [dependencies] serialize = { path = "../libserialize" } rustc_data_structures = { path = "../librustc_data_structures" } +scoped-tls = { version = "0.1.1", features = ["nightly"] } unicode-width = "0.1.4" diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index b7fba9fe8dfb..85a2940ec442 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -15,11 +15,11 @@ //! and definition contexts*. J. Funct. Program. 22, 2 (March 2012), 181-216. //! DOI=10.1017/S0956796812000093 +use GLOBALS; use Span; use symbol::{Ident, Symbol}; use serialize::{Encodable, Decodable, Encoder, Decoder}; -use std::cell::RefCell; use std::collections::HashMap; use std::fmt; @@ -119,7 +119,7 @@ impl Mark { } } -struct HygieneData { +pub struct HygieneData { marks: Vec, syntax_contexts: Vec, markings: HashMap<(SyntaxContext, Mark), SyntaxContext>, @@ -127,7 +127,7 @@ struct HygieneData { } impl HygieneData { - fn new() -> Self { + pub fn new() -> Self { HygieneData { marks: vec![MarkData { parent: Mark::root(), @@ -145,10 +145,7 @@ impl HygieneData { } fn with T>(f: F) -> T { - thread_local! { - static HYGIENE_DATA: RefCell = RefCell::new(HygieneData::new()); - } - HYGIENE_DATA.with(|data| f(&mut *data.borrow_mut())) + GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut())) } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index ed9eb5d5c926..bec46ff3d797 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -35,10 +35,13 @@ use std::ops::{Add, Sub}; use std::path::PathBuf; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Lock}; extern crate rustc_data_structures; +#[macro_use] +extern crate scoped_tls; + use serialize::{Encodable, Decodable, Encoder, Decoder}; extern crate serialize; @@ -54,6 +57,24 @@ pub use span_encoding::{Span, DUMMY_SP}; pub mod symbol; +pub struct Globals { + symbol_interner: Lock, + span_interner: Lock, + hygiene_data: Lock, +} + +impl Globals { + pub fn new() -> Globals { + Globals { + symbol_interner: Lock::new(symbol::Interner::fresh()), + span_interner: Lock::new(span_encoding::SpanInterner::default()), + hygiene_data: Lock::new(hygiene::HygieneData::new()), + } + } +} + +scoped_thread_local!(pub static GLOBALS: Globals); + /// Differentiates between real files and common virtual files #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, RustcDecodable, RustcEncodable)] pub enum FileName { diff --git a/src/libsyntax_pos/span_encoding.rs b/src/libsyntax_pos/span_encoding.rs index bf9a832519ad..b55fe4bcb267 100644 --- a/src/libsyntax_pos/span_encoding.rs +++ b/src/libsyntax_pos/span_encoding.rs @@ -14,11 +14,11 @@ // The encoding format for inline spans were obtained by optimizing over crates in rustc/libstd. // See https://internals.rust-lang.org/t/rfc-compiler-refactoring-spans/1357/28 +use GLOBALS; use {BytePos, SpanData}; use hygiene::SyntaxContext; use rustc_data_structures::fx::FxHashMap; -use std::cell::RefCell; use std::hash::{Hash, Hasher}; /// A compressed span. @@ -133,7 +133,7 @@ fn decode(span: Span) -> SpanData { } #[derive(Default)] -struct SpanInterner { +pub struct SpanInterner { spans: FxHashMap, span_data: Vec, } @@ -156,11 +156,8 @@ impl SpanInterner { } } -// If an interner exists in TLS, return it. Otherwise, prepare a fresh one. +// If an interner exists, return it. Otherwise, prepare a fresh one. #[inline] fn with_span_interner T>(f: F) -> T { - thread_local!(static INTERNER: RefCell = { - RefCell::new(SpanInterner::default()) - }); - INTERNER.with(|interner| f(&mut *interner.borrow_mut())) + GLOBALS.with(|globals| f(&mut *globals.span_interner.lock())) } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index aafdd696b747..e95079f7c88d 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -13,9 +13,9 @@ //! type, and vice versa. use hygiene::SyntaxContext; +use GLOBALS; use serialize::{Decodable, Decoder, Encodable, Encoder}; -use std::cell::RefCell; use std::collections::HashMap; use std::fmt; @@ -247,7 +247,7 @@ macro_rules! declare_keywords {( } impl Interner { - fn fresh() -> Self { + pub fn fresh() -> Self { Interner::prefill(&[$($string,)*]) } } @@ -330,12 +330,10 @@ declare_keywords! { (60, Union, "union") } -// If an interner exists in TLS, return it. Otherwise, prepare a fresh one. +// If an interner exists, return it. Otherwise, prepare a fresh one. +#[inline] fn with_interner T>(f: F) -> T { - thread_local!(static INTERNER: RefCell = { - RefCell::new(Interner::fresh()) - }); - INTERNER.with(|interner| f(&mut *interner.borrow_mut())) + GLOBALS.with(|globals| f(&mut *globals.symbol_interner.lock())) } /// Represents a string stored in the thread-local interner. Because the @@ -422,6 +420,7 @@ impl Encodable for InternedString { #[cfg(test)] mod tests { use super::*; + use Globals; #[test] fn interner_tests() { @@ -444,7 +443,9 @@ mod tests { #[test] fn without_first_quote_test() { - let i = Ident::from_str("'break"); - assert_eq!(i.without_first_quote().name, keywords::Break.name()); + GLOBALS.set(&Globals::new(), || { + let i = Ident::from_str("'break"); + assert_eq!(i.without_first_quote().name, keywords::Break.name()); + }); } } diff --git a/src/test/run-fail-fulldeps/qquote.rs b/src/test/run-fail-fulldeps/qquote.rs index 27b9e27be438..c8c80b7759c9 100644 --- a/src/test/run-fail-fulldeps/qquote.rs +++ b/src/test/run-fail-fulldeps/qquote.rs @@ -24,6 +24,10 @@ use syntax::symbol::Symbol; use syntax_pos::DUMMY_SP; fn main() { + syntax::with_globals(|| run()); +} + +fn run() { let ps = syntax::parse::ParseSess::new(codemap::FilePathMapping::empty()); let mut resolver = syntax::ext::base::DummyResolver; let mut cx = syntax::ext::base::ExtCtxt::new( diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs index b4b29e15ce17..e0db2627d853 100644 --- a/src/test/run-make/issue-19371/foo.rs +++ b/src/test/run-make/issue-19371/foo.rs @@ -69,18 +69,20 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc, Box) { } fn compile(code: String, output: PathBuf, sysroot: PathBuf) { - let (sess, cstore, trans) = basic_sess(sysroot); - let control = CompileController::basic(); - let input = Input::Str { name: FileName::Anon, input: code }; - let _ = compile_input( - trans, - &sess, - &cstore, - &None, - &input, - &None, - &Some(output), - None, - &control - ); + syntax::with_globals(|| { + let (sess, cstore, trans) = basic_sess(sysroot); + let control = CompileController::basic(); + let input = Input::Str { name: FileName::Anon, input: code }; + let _ = compile_input( + trans, + &sess, + &cstore, + &None, + &input, + &None, + &Some(output), + None, + &control + ); + }); } diff --git a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs index 9f9ef4772242..f3f7777d8d40 100644 --- a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs +++ b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs @@ -115,6 +115,10 @@ fn reject_stmt_parse(es: &str) { } fn main() { + syntax::with_globals(|| run()); +} + +fn run() { let both = &["#[attr]", "#![attr]"]; let outer = &["#[attr]"]; let none = &[]; diff --git a/src/test/run-pass-fulldeps/issue-35829.rs b/src/test/run-pass-fulldeps/issue-35829.rs index 07d4bd2fe151..c42024332503 100644 --- a/src/test/run-pass-fulldeps/issue-35829.rs +++ b/src/test/run-pass-fulldeps/issue-35829.rs @@ -27,6 +27,10 @@ use syntax::ptr::P; use rustc_data_structures::sync::Lrc; fn main() { + syntax::with_globals(|| run()); +} + +fn run() { let parse_sess = ParseSess::new(FilePathMapping::empty()); let exp_cfg = ExpansionConfig::default("issue_35829".to_owned()); let mut resolver = DummyResolver; diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs index 10c44c8044b4..05fe274c49f3 100644 --- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs @@ -221,8 +221,11 @@ impl Folder for AddParens { } } - fn main() { + syntax::with_globals(|| run()); +} + +fn run() { let ps = ParseSess::new(FilePathMapping::empty()); iter_exprs(2, &mut |e| { diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index 949aa8a9518c..c597360c0426 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -21,6 +21,10 @@ use syntax::symbol::Symbol; use syntax_pos::DUMMY_SP; fn main() { + syntax::with_globals(|| run()); +} + +fn run() { let ps = syntax::parse::ParseSess::new(FilePathMapping::empty()); let mut resolver = syntax::ext::base::DummyResolver; let mut cx = syntax::ext::base::ExtCtxt::new( diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 76f5f98358c9..cdeb60156725 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -263,7 +263,10 @@ fn main() { *slot.borrow_mut() = Some((None, String::from("https://play.rust-lang.org/"))); }); let (format, dst) = parse_args(); - if let Err(e) = main_with_result(format, &dst) { + let result = syntax::with_globals(move || { + main_with_result(format, &dst) + }); + if let Err(e) = result { panic!("{}", e.description()); } } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 22c6af28ceae..63f40110225e 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -93,6 +93,7 @@ static WHITELIST: &'static [Crate] = &[ Crate("regex-syntax"), Crate("remove_dir_all"), Crate("rustc-demangle"), + Crate("scoped-tls"), Crate("smallvec"), Crate("stable_deref_trait"), Crate("tempdir"), From 1271f0bd2519d63b427ea36a752f7de32bc5a7a2 Mon Sep 17 00:00:00 2001 From: scalexm Date: Sat, 10 Mar 2018 12:44:33 +0100 Subject: [PATCH 195/830] Add MVP for chalkification --- src/librustc/dep_graph/dep_node.rs | 2 + src/librustc/ich/impls_ty.rs | 83 +++++++++++ src/librustc/traits/lowering.rs | 147 +++++++++++++++++++ src/librustc/traits/mod.rs | 56 ++++++++ src/librustc/traits/structural_impls.rs | 183 ++++++++++++++++++++++++ src/librustc/ty/maps/config.rs | 6 + src/librustc/ty/maps/mod.rs | 3 + src/librustc/ty/maps/plumbing.rs | 2 + src/librustc_driver/driver.rs | 2 + src/libsyntax/feature_gate.rs | 7 + src/test/ui/chalkify/lower_impl.rs | 20 +++ src/test/ui/chalkify/lower_impl.stderr | 8 ++ 12 files changed, 519 insertions(+) create mode 100644 src/librustc/traits/lowering.rs create mode 100644 src/test/ui/chalkify/lower_impl.rs create mode 100644 src/test/ui/chalkify/lower_impl.stderr diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 8d7fef90b754..744e3a5eaabc 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -648,6 +648,8 @@ define_dep_nodes!( <'tcx> [] GetSymbolExportLevel(DefId), [input] Features, + + [] ProgramClausesFor(DefId), ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 4eb4f0edafe4..868ce831d13e 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1286,3 +1286,86 @@ impl_stable_hash_for!(struct infer::canonical::QueryRegionConstraints<'tcx> { impl_stable_hash_for!(enum infer::canonical::Certainty { Proven, Ambiguous }); + +impl<'a, 'tcx> HashStable> for traits::WhereClauseAtom<'tcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + use traits::WhereClauseAtom::*; + + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + Implemented(ref trait_ref) => trait_ref.hash_stable(hcx, hasher), + ProjectionEq(ref projection) => projection.hash_stable(hcx, hasher), + } + } +} + +impl<'a, 'tcx> HashStable> for traits::DomainGoal<'tcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + use traits::DomainGoal::*; + + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + Holds(ref where_clause) | + WellFormed(ref where_clause) | + FromEnv(ref where_clause) => where_clause.hash_stable(hcx, hasher), + + WellFormedTy(ref ty) => ty.hash_stable(hcx, hasher), + FromEnvTy(ref ty) => ty.hash_stable(hcx, hasher), + RegionOutlives(ref predicate) => predicate.hash_stable(hcx, hasher), + TypeOutlives(ref predicate) => predicate.hash_stable(hcx, hasher), + } + } +} + +impl<'a, 'tcx> HashStable> for traits::LeafGoal<'tcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + use traits::LeafGoal::*; + + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + DomainGoal(ref domain_goal) => domain_goal.hash_stable(hcx, hasher), + } + } +} + +impl<'a, 'tcx> HashStable> for traits::Goal<'tcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + use traits::Goal::*; + + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + Implies(ref hypotheses, ref goal) => { + hypotheses.hash_stable(hcx, hasher); + goal.hash_stable(hcx, hasher); + }, + And(ref goal1, ref goal2) => { + goal1.hash_stable(hcx, hasher); + goal2.hash_stable(hcx, hasher); + } + Not(ref goal) => goal.hash_stable(hcx, hasher), + Leaf(ref leaf_goal) => leaf_goal.hash_stable(hcx, hasher), + Quantified(quantifier, ref goal) => { + quantifier.hash_stable(hcx, hasher); + goal.hash_stable(hcx, hasher); + }, + } + } +} + +impl_stable_hash_for!(enum traits::QuantifierKind { + Universal, + Existential +}); + +impl_stable_hash_for!(struct traits::ProgramClause<'tcx> { + consequence, + conditions +}); diff --git a/src/librustc/traits/lowering.rs b/src/librustc/traits/lowering.rs new file mode 100644 index 000000000000..4f7e66628d48 --- /dev/null +++ b/src/librustc/traits/lowering.rs @@ -0,0 +1,147 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use hir::{self, ImplPolarity}; +use hir::def_id::DefId; +use hir::intravisit::{self, NestedVisitorMap, Visitor}; +use ty::{self, PolyTraitPredicate, TraitPredicate, PolyProjectionPredicate, TyCtxt, Predicate}; +use super::{DomainGoal, ProgramClause, WhereClauseAtom}; +use rustc_data_structures::sync::Lrc; +use syntax::ast; + +trait Lower { + fn lower(&self) -> T; +} + +impl Lower> for Vec where T: Lower { + fn lower(&self) -> Vec { + self.iter().map(|item| item.lower()).collect() + } +} + +impl<'tcx> Lower> for PolyTraitPredicate<'tcx> { + fn lower(&self) -> WhereClauseAtom<'tcx> { + WhereClauseAtom::Implemented(*self) + } +} + +impl<'tcx> Lower> for PolyProjectionPredicate<'tcx> { + fn lower(&self) -> WhereClauseAtom<'tcx> { + WhereClauseAtom::ProjectionEq(*self) + } +} + +impl<'tcx, T> Lower> for T where T: Lower> { + fn lower(&self) -> DomainGoal<'tcx> { + DomainGoal::Holds(self.lower()) + } +} + +impl<'tcx> Lower> for Predicate<'tcx> { + fn lower(&self) -> DomainGoal<'tcx> { + use self::Predicate::*; + + match *self { + Trait(predicate) => predicate.lower(), + RegionOutlives(predicate) => DomainGoal::RegionOutlives(predicate), + TypeOutlives(predicate) => DomainGoal::TypeOutlives(predicate), + Projection(predicate) => predicate.lower(), + WellFormed(ty) => DomainGoal::WellFormedTy(ty), + ObjectSafe(..) | + ClosureKind(..) | + Subtype(..) | + ConstEvaluatable(..) => unimplemented!(), + + } + } +} + +pub fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) + -> Lrc>> +{ + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let item = tcx.hir.expect_item(node_id); + match item.node { + hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id), + _ => Lrc::new(vec![]), + } +} + +fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) + -> Lrc>> +{ + if let ImplPolarity::Negative = tcx.impl_polarity(def_id) { + return Lrc::new(vec![]); + } + + let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); + let trait_ref = ty::Binder(TraitPredicate { trait_ref }).lower(); + let where_clauses = tcx.predicates_of(def_id).predicates.lower(); + + let clause = ProgramClause { + consequence: trait_ref, + conditions: where_clauses.into_iter().map(|wc| wc.into()).collect(), + }; + + Lrc::new(vec![clause]) +} + +pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + if !tcx.features().rustc_attrs { + return; + } + + let mut visitor = ClauseDumper { tcx }; + tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); +} + +struct ClauseDumper<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, +} + +impl <'a, 'tcx> ClauseDumper<'a, 'tcx > { + fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) { + let def_id = self.tcx.hir.local_def_id(node_id); + for attr in attrs { + if attr.check_name("rustc_dump_program_clauses") { + let clauses = self.tcx.program_clauses_for(def_id); + for clause in &*clauses { + self.tcx.sess.struct_span_err(attr.span, &format!("{}", clause)).emit(); + } + } + } + } +} + +impl<'a, 'tcx> Visitor<'tcx> for ClauseDumper<'a, 'tcx> { + fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { + NestedVisitorMap::OnlyBodies(&self.tcx.hir) + } + + fn visit_item(&mut self, item: &'tcx hir::Item) { + self.process_attrs(item.id, &item.attrs); + intravisit::walk_item(self, item); + } + + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { + self.process_attrs(trait_item.id, &trait_item.attrs); + intravisit::walk_trait_item(self, trait_item); + } + + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { + self.process_attrs(impl_item.id, &impl_item.attrs); + intravisit::walk_impl_item(self, impl_item); + } + + fn visit_struct_field(&mut self, s: &'tcx hir::StructField) { + self.process_attrs(s.id, &s.attrs); + intravisit::walk_struct_field(self, s); + } +} diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index a2a5aa246cf7..8b2f96ce8755 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -29,6 +29,7 @@ use infer::{InferCtxt}; use rustc_data_structures::sync::Lrc; use std::rc::Rc; +use std::convert::From; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; @@ -62,6 +63,7 @@ mod specialize; mod structural_impls; pub mod trans; mod util; +mod lowering; pub mod query; @@ -244,6 +246,59 @@ pub type Obligations<'tcx, O> = Vec>; pub type PredicateObligations<'tcx> = Vec>; pub type TraitObligations<'tcx> = Vec>; +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum WhereClauseAtom<'tcx> { + Implemented(ty::PolyTraitPredicate<'tcx>), + ProjectionEq(ty::PolyProjectionPredicate<'tcx>), +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum DomainGoal<'tcx> { + Holds(WhereClauseAtom<'tcx>), + WellFormed(WhereClauseAtom<'tcx>), + FromEnv(WhereClauseAtom<'tcx>), + WellFormedTy(Ty<'tcx>), + FromEnvTy(Ty<'tcx>), + RegionOutlives(ty::PolyRegionOutlivesPredicate<'tcx>), + TypeOutlives(ty::PolyTypeOutlivesPredicate<'tcx>), +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum LeafGoal<'tcx> { + DomainGoal(DomainGoal<'tcx>), +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum QuantifierKind { + Universal, + Existential, +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub enum Goal<'tcx> { + Implies(Vec>, Box>), + And(Box>, Box>), + Not(Box>), + Leaf(LeafGoal<'tcx>), + Quantified(QuantifierKind, Box>>) +} + +impl<'tcx> From> for Goal<'tcx> { + fn from(domain_goal: DomainGoal<'tcx>) -> Self { + Goal::Leaf(LeafGoal::DomainGoal(domain_goal)) + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct ProgramClause<'tcx> { + pub consequence: DomainGoal<'tcx>, + pub conditions: Vec>, +} + +pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { + lowering::dump_program_clauses(tcx) +} + pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>; #[derive(Clone,Debug)] @@ -915,6 +970,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, trans_fulfill_obligation: trans::trans_fulfill_obligation, + program_clauses_for: lowering::program_clauses_for, vtable_methods, substitute_normalize_and_test_predicates, ..*providers diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index a2d98a456f49..62881013c4c5 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -425,3 +425,186 @@ BraceStructTypeFoldableImpl! { obligations } where T: TypeFoldable<'tcx> } + +impl<'tcx> fmt::Display for traits::WhereClauseAtom<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use traits::WhereClauseAtom::*; + match *self { + Implemented(ref trait_ref) => write!(fmt, "Implemented({})", trait_ref), + ProjectionEq(ref projection) => write!(fmt, "ProjectionEq({})", projection), + } + } +} + +impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use traits::DomainGoal::*; + use traits::WhereClauseAtom::*; + match *self { + Holds(wc) => write!(fmt, "{}", wc), + WellFormed(Implemented(ref trait_ref)) => write!(fmt, "WellFormed({})", trait_ref), + WellFormed(ProjectionEq(ref projection)) => write!(fmt, "WellFormed({})", projection), + FromEnv(Implemented(ref trait_ref)) => write!(fmt, "FromEnv({})", trait_ref), + FromEnv(ProjectionEq(ref projection)) => write!(fmt, "FromEnv({})", projection), + WellFormedTy(ref ty) => write!(fmt, "WellFormed({})", ty), + FromEnvTy(ref ty) => write!(fmt, "FromEnv({})", ty), + RegionOutlives(ref predicate) => write!(fmt, "RegionOutlives({})", predicate), + TypeOutlives(ref predicate) => write!(fmt, "TypeOutlives({})", predicate), + } + } +} + +impl fmt::Display for traits::QuantifierKind { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use traits::QuantifierKind::*; + match *self { + Universal => write!(fmt, "forall"), + Existential => write!(fmt, "exists"), + } + } +} + +impl<'tcx> fmt::Display for traits::LeafGoal<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use traits::LeafGoal::*; + match *self { + DomainGoal(ref domain_goal) => write!(fmt, "{}", domain_goal), + } + } +} + +impl<'tcx> fmt::Display for traits::Goal<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + use traits::Goal::*; + match *self { + Implies(ref hypotheses, ref goal) => { + write!(fmt, "if (")?; + for (index, hyp) in hypotheses.iter().enumerate() { + if index > 0 { + write!(fmt, ", ")?; + } + write!(fmt, "{}", hyp)?; + } + write!(fmt, ") {{ {} }}", goal) + } + And(ref goal1, ref goal2) => write!(fmt, "({}, {})", goal1, goal2), + Not(ref goal) => write!(fmt, "not {{ {} }}", goal), + Leaf(ref goal) => write!(fmt, "{}", goal), + Quantified(qkind, ref goal) => { + // FIXME: appropriate binder names + write!(fmt, "{}<> {{ {} }}", qkind, goal.skip_binder()) + } + } + } +} + +impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{}", self.consequence)?; + if self.conditions.is_empty() { + write!(fmt, ".")?; + } else { + write!(fmt, " :- ")?; + for (index, condition) in self.conditions.iter().enumerate() { + if index > 0 { + write!(fmt, ", ")?; + } + write!(fmt, "{}", condition)?; + } + } + Ok(()) + } +} + +impl<'tcx> TypeFoldable<'tcx> for traits::WhereClauseAtom<'tcx> { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + use traits::WhereClauseAtom::*; + match *self { + Implemented(ref trait_ref) => Implemented(trait_ref.fold_with(folder)), + ProjectionEq(ref projection) => ProjectionEq(projection.fold_with(folder)), + } + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + use traits::WhereClauseAtom::*; + match *self { + Implemented(ref trait_ref) => trait_ref.visit_with(visitor), + ProjectionEq(ref projection) => projection.visit_with(visitor), + } + } +} + +impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + use traits::DomainGoal::*; + match *self { + Holds(ref wc) => Holds(wc.fold_with(folder)), + WellFormed(ref wc) => WellFormed(wc.fold_with(folder)), + FromEnv(ref wc) => FromEnv(wc.fold_with(folder)), + WellFormedTy(ref ty) => WellFormedTy(ty.fold_with(folder)), + FromEnvTy(ref ty) => FromEnvTy(ty.fold_with(folder)), + RegionOutlives(ref predicate) => RegionOutlives(predicate.fold_with(folder)), + TypeOutlives(ref predicate) => TypeOutlives(predicate.fold_with(folder)), + } + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + use traits::DomainGoal::*; + match *self { + Holds(ref wc) | + WellFormed(ref wc) | + FromEnv(ref wc) => wc.visit_with(visitor), + WellFormedTy(ref ty) | + FromEnvTy(ref ty) => ty.visit_with(visitor), + RegionOutlives(ref predicate) => predicate.visit_with(visitor), + TypeOutlives(ref predicate) => predicate.visit_with(visitor), + } + } +} + +impl<'tcx> TypeFoldable<'tcx> for traits::LeafGoal<'tcx> { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + use traits::LeafGoal::*; + match *self { + DomainGoal(ref domain_goal) => DomainGoal(domain_goal.fold_with(folder)), + } + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + use traits::LeafGoal::*; + match *self { + DomainGoal(ref domain_goal) => domain_goal.visit_with(visitor), + } + } +} + +impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { + use traits::Goal::*; + match *self { + Implies(ref hypotheses, ref goal) => { + Implies( + hypotheses.iter().map(|hyp| hyp.fold_with(folder)).collect(), + goal.fold_with(folder) + ) + }, + And(ref goal1, ref goal2) => And(goal1.fold_with(folder), goal2.fold_with(folder)), + Not(ref goal) => Not(goal.fold_with(folder)), + Leaf(ref leaf_goal) => Leaf(leaf_goal.fold_with(folder)), + Quantified(qkind, ref goal) => Quantified(qkind, goal.fold_with(folder)), + } + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + use traits::Goal::*; + match *self { + Implies(ref hypotheses, ref goal) => { + hypotheses.iter().any(|hyp| hyp.visit_with(visitor)) || goal.visit_with(visitor) + } + And(ref goal1, ref goal2) => goal1.visit_with(visitor) || goal2.visit_with(visitor), + Not(ref goal) => goal.visit_with(visitor), + Leaf(ref leaf_goal) => leaf_goal.visit_with(visitor), + Quantified(_, ref goal) => goal.visit_with(visitor), + } + } +} diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index dbfe7770bbde..abda7a2cd09e 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -681,6 +681,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> { + fn describe(_tcx: TyCtxt, _: DefId) -> String { + format!("generating chalk-style clauses") + } +} + macro_rules! impl_disk_cacheable_query( ($query_name:ident, |$key:tt| $cond:expr) => { impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 7d726d2e3cd5..087c7d6d44df 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -38,6 +38,7 @@ use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal, NoSolution}; use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; use traits::query::normalize::NormalizationResult; use traits::specialization_graph; +use traits::ProgramClause; use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use ty::steal::Steal; use ty::subst::Substs; @@ -417,6 +418,8 @@ define_maps! { <'tcx> -> usize, [] fn features_query: features_node(CrateNum) -> Lrc, + + [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc>>, } ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index bc7186f781a8..dd65d4b41907 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -935,6 +935,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); } DepKind::Features => { force!(features_query, LOCAL_CRATE); } + + DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); } } true diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 542f818c3818..69257e3e1139 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1089,6 +1089,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, time(sess, "lint checking", || lint::check_crate(tcx)); + time(time_passes, "dumping chalk-like clauses", || traits::dump_program_clauses(tcx)); + return Ok(f(tcx, analysis, rx, tcx.sess.compile_status())); }) } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ec9a15d9f2b4..ea2d907331a6 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -831,6 +831,13 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG across crates and will never be stable", cfg_fn!(rustc_attrs))), + ("rustc_dump_program_clauses", Whitelisted, Gated(Stability::Unstable, + "rustc_attrs", + "the `#[rustc_dump_program_clauses]` \ + attribute is just used for rustc unit \ + tests and will never be stable", + cfg_fn!(rustc_attrs))), + // RFC #2094 ("nll", Whitelisted, Gated(Stability::Unstable, "nll", diff --git a/src/test/ui/chalkify/lower_impl.rs b/src/test/ui/chalkify/lower_impl.rs new file mode 100644 index 000000000000..2083ada6d2de --- /dev/null +++ b/src/test/ui/chalkify/lower_impl.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] + +trait Foo { } + +#[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :- +impl Foo for T where T: Iterator { } + +fn main() { + println!("hello"); +} diff --git a/src/test/ui/chalkify/lower_impl.stderr b/src/test/ui/chalkify/lower_impl.stderr new file mode 100644 index 000000000000..8645e4506efa --- /dev/null +++ b/src/test/ui/chalkify/lower_impl.stderr @@ -0,0 +1,8 @@ +error: Implemented(T: Foo) :- ProjectionEq(::Item == i32), TypeOutlives(T : 'static), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized) + --> $DIR/lower_impl.rs:15:1 + | +LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :- + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 04b228c3e26dab45c0f9d597b0424eda707c1515 Mon Sep 17 00:00:00 2001 From: scalexm Date: Wed, 14 Mar 2018 13:38:03 +0100 Subject: [PATCH 196/830] Address niko's nits --- src/librustc/ich/impls_ty.rs | 70 ++++----- src/librustc/traits/lowering.rs | 59 +++++--- src/librustc/traits/mod.rs | 32 ++-- src/librustc/traits/structural_impls.rs | 190 +++++++++--------------- src/librustc/ty/maps/mod.rs | 4 +- src/librustc/ty/mod.rs | 9 +- src/librustc_driver/driver.rs | 2 +- src/test/ui/chalkify/lower_impl.stderr | 2 +- 8 files changed, 173 insertions(+), 195 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 868ce831d13e..78407e33d98b 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1294,9 +1294,9 @@ impl<'a, 'tcx> HashStable> for traits::WhereClauseAtom< use traits::WhereClauseAtom::*; mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - Implemented(ref trait_ref) => trait_ref.hash_stable(hcx, hasher), - ProjectionEq(ref projection) => projection.hash_stable(hcx, hasher), + match self { + Implemented(trait_ref) => trait_ref.hash_stable(hcx, hasher), + ProjectionEq(projection) => projection.hash_stable(hcx, hasher), } } } @@ -1308,28 +1308,15 @@ impl<'a, 'tcx> HashStable> for traits::DomainGoal<'tcx> use traits::DomainGoal::*; mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - Holds(ref where_clause) | - WellFormed(ref where_clause) | - FromEnv(ref where_clause) => where_clause.hash_stable(hcx, hasher), + match self { + Holds(where_clause) | + WellFormed(where_clause) | + FromEnv(where_clause) => where_clause.hash_stable(hcx, hasher), - WellFormedTy(ref ty) => ty.hash_stable(hcx, hasher), - FromEnvTy(ref ty) => ty.hash_stable(hcx, hasher), - RegionOutlives(ref predicate) => predicate.hash_stable(hcx, hasher), - TypeOutlives(ref predicate) => predicate.hash_stable(hcx, hasher), - } - } -} - -impl<'a, 'tcx> HashStable> for traits::LeafGoal<'tcx> { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher) { - use traits::LeafGoal::*; - - mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - DomainGoal(ref domain_goal) => domain_goal.hash_stable(hcx, hasher), + WellFormedTy(ty) => ty.hash_stable(hcx, hasher), + FromEnvTy(ty) => ty.hash_stable(hcx, hasher), + RegionOutlives(predicate) => predicate.hash_stable(hcx, hasher), + TypeOutlives(predicate) => predicate.hash_stable(hcx, hasher), } } } @@ -1341,18 +1328,18 @@ impl<'a, 'tcx> HashStable> for traits::Goal<'tcx> { use traits::Goal::*; mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - Implies(ref hypotheses, ref goal) => { + match self { + Implies(hypotheses, goal) => { hypotheses.hash_stable(hcx, hasher); goal.hash_stable(hcx, hasher); }, - And(ref goal1, ref goal2) => { + And(goal1, goal2) => { goal1.hash_stable(hcx, hasher); goal2.hash_stable(hcx, hasher); } - Not(ref goal) => goal.hash_stable(hcx, hasher), - Leaf(ref leaf_goal) => leaf_goal.hash_stable(hcx, hasher), - Quantified(quantifier, ref goal) => { + Not(goal) => goal.hash_stable(hcx, hasher), + DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher), + Quantified(quantifier, goal) => { quantifier.hash_stable(hcx, hasher); goal.hash_stable(hcx, hasher); }, @@ -1360,12 +1347,25 @@ impl<'a, 'tcx> HashStable> for traits::Goal<'tcx> { } } +impl<'a, 'tcx> HashStable> for traits::Clause<'tcx> { + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a>, + hasher: &mut StableHasher) { + use traits::Clause::*; + + mem::discriminant(self).hash_stable(hcx, hasher); + match self { + Implies(hypotheses, goal) => { + hypotheses.hash_stable(hcx, hasher); + goal.hash_stable(hcx, hasher); + } + DomainGoal(domain_goal) => domain_goal.hash_stable(hcx, hasher), + ForAll(clause) => clause.hash_stable(hcx, hasher), + } + } +} + impl_stable_hash_for!(enum traits::QuantifierKind { Universal, Existential }); - -impl_stable_hash_for!(struct traits::ProgramClause<'tcx> { - consequence, - conditions -}); diff --git a/src/librustc/traits/lowering.rs b/src/librustc/traits/lowering.rs index 4f7e66628d48..f31e474963ee 100644 --- a/src/librustc/traits/lowering.rs +++ b/src/librustc/traits/lowering.rs @@ -11,8 +11,8 @@ use hir::{self, ImplPolarity}; use hir::def_id::DefId; use hir::intravisit::{self, NestedVisitorMap, Visitor}; -use ty::{self, PolyTraitPredicate, TraitPredicate, PolyProjectionPredicate, TyCtxt, Predicate}; -use super::{DomainGoal, ProgramClause, WhereClauseAtom}; +use ty::{self, TyCtxt}; +use super::{QuantifierKind, Goal, DomainGoal, Clause, WhereClauseAtom}; use rustc_data_structures::sync::Lrc; use syntax::ast; @@ -26,13 +26,13 @@ impl Lower> for Vec where T: Lower { } } -impl<'tcx> Lower> for PolyTraitPredicate<'tcx> { +impl<'tcx> Lower> for ty::TraitPredicate<'tcx> { fn lower(&self) -> WhereClauseAtom<'tcx> { WhereClauseAtom::Implemented(*self) } } -impl<'tcx> Lower> for PolyProjectionPredicate<'tcx> { +impl<'tcx> Lower> for ty::ProjectionPredicate<'tcx> { fn lower(&self) -> WhereClauseAtom<'tcx> { WhereClauseAtom::ProjectionEq(*self) } @@ -44,27 +44,52 @@ impl<'tcx, T> Lower> for T where T: Lower } } -impl<'tcx> Lower> for Predicate<'tcx> { +impl<'tcx> Lower> for ty::RegionOutlivesPredicate<'tcx> { fn lower(&self) -> DomainGoal<'tcx> { - use self::Predicate::*; + DomainGoal::RegionOutlives(*self) + } +} - match *self { +impl<'tcx> Lower> for ty::TypeOutlivesPredicate<'tcx> { + fn lower(&self) -> DomainGoal<'tcx> { + DomainGoal::TypeOutlives(*self) + } +} + +impl<'tcx, T> Lower> for ty::Binder + where T: Lower> + ty::fold::TypeFoldable<'tcx> + Copy +{ + fn lower(&self) -> Goal<'tcx> { + match self.no_late_bound_regions() { + Some(p) => p.lower().into(), + None => Goal::Quantified( + QuantifierKind::Universal, + Box::new(self.map_bound(|p| p.lower().into())) + ), + } + } +} + +impl<'tcx> Lower> for ty::Predicate<'tcx> { + fn lower(&self) -> Goal<'tcx> { + use ty::Predicate::*; + + match self { Trait(predicate) => predicate.lower(), - RegionOutlives(predicate) => DomainGoal::RegionOutlives(predicate), - TypeOutlives(predicate) => DomainGoal::TypeOutlives(predicate), + RegionOutlives(predicate) => predicate.lower(), + TypeOutlives(predicate) => predicate.lower(), Projection(predicate) => predicate.lower(), - WellFormed(ty) => DomainGoal::WellFormedTy(ty), + WellFormed(ty) => DomainGoal::WellFormedTy(*ty).into(), ObjectSafe(..) | ClosureKind(..) | Subtype(..) | ConstEvaluatable(..) => unimplemented!(), - } } } pub fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc>> + -> Lrc>> { let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let item = tcx.hir.expect_item(node_id); @@ -75,21 +100,17 @@ pub fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) } fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> Lrc>> + -> Lrc>> { if let ImplPolarity::Negative = tcx.impl_polarity(def_id) { return Lrc::new(vec![]); } let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); - let trait_ref = ty::Binder(TraitPredicate { trait_ref }).lower(); + let trait_ref = ty::TraitPredicate { trait_ref }.lower(); let where_clauses = tcx.predicates_of(def_id).predicates.lower(); - let clause = ProgramClause { - consequence: trait_ref, - conditions: where_clauses.into_iter().map(|wc| wc.into()).collect(), - }; - + let clause = Clause::Implies(where_clauses, trait_ref); Lrc::new(vec![clause]) } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 8b2f96ce8755..ea3db0c6e926 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -248,8 +248,8 @@ pub type TraitObligations<'tcx> = Vec>; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub enum WhereClauseAtom<'tcx> { - Implemented(ty::PolyTraitPredicate<'tcx>), - ProjectionEq(ty::PolyProjectionPredicate<'tcx>), + Implemented(ty::TraitPredicate<'tcx>), + ProjectionEq(ty::ProjectionPredicate<'tcx>), } #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] @@ -259,13 +259,8 @@ pub enum DomainGoal<'tcx> { FromEnv(WhereClauseAtom<'tcx>), WellFormedTy(Ty<'tcx>), FromEnvTy(Ty<'tcx>), - RegionOutlives(ty::PolyRegionOutlivesPredicate<'tcx>), - TypeOutlives(ty::PolyTypeOutlivesPredicate<'tcx>), -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -pub enum LeafGoal<'tcx> { - DomainGoal(DomainGoal<'tcx>), + RegionOutlives(ty::RegionOutlivesPredicate<'tcx>), + TypeOutlives(ty::TypeOutlivesPredicate<'tcx>), } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -276,23 +271,30 @@ pub enum QuantifierKind { #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum Goal<'tcx> { - Implies(Vec>, Box>), + Implies(Vec>, Box>), And(Box>, Box>), Not(Box>), - Leaf(LeafGoal<'tcx>), + DomainGoal(DomainGoal<'tcx>), Quantified(QuantifierKind, Box>>) } impl<'tcx> From> for Goal<'tcx> { fn from(domain_goal: DomainGoal<'tcx>) -> Self { - Goal::Leaf(LeafGoal::DomainGoal(domain_goal)) + Goal::DomainGoal(domain_goal) + } +} + +impl<'tcx> From> for Clause<'tcx> { + fn from(domain_goal: DomainGoal<'tcx>) -> Self { + Clause::DomainGoal(domain_goal) } } #[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct ProgramClause<'tcx> { - pub consequence: DomainGoal<'tcx>, - pub conditions: Vec>, +pub enum Clause<'tcx> { + Implies(Vec>, DomainGoal<'tcx>), + DomainGoal(DomainGoal<'tcx>), + ForAll(Box>>), } pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 62881013c4c5..d6e6f0e98adc 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -429,9 +429,10 @@ BraceStructTypeFoldableImpl! { impl<'tcx> fmt::Display for traits::WhereClauseAtom<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use traits::WhereClauseAtom::*; - match *self { - Implemented(ref trait_ref) => write!(fmt, "Implemented({})", trait_ref), - ProjectionEq(ref projection) => write!(fmt, "ProjectionEq({})", projection), + + match self { + Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref), + ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection), } } } @@ -440,16 +441,17 @@ impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use traits::DomainGoal::*; use traits::WhereClauseAtom::*; - match *self { + + match self { Holds(wc) => write!(fmt, "{}", wc), - WellFormed(Implemented(ref trait_ref)) => write!(fmt, "WellFormed({})", trait_ref), - WellFormed(ProjectionEq(ref projection)) => write!(fmt, "WellFormed({})", projection), - FromEnv(Implemented(ref trait_ref)) => write!(fmt, "FromEnv({})", trait_ref), - FromEnv(ProjectionEq(ref projection)) => write!(fmt, "FromEnv({})", projection), - WellFormedTy(ref ty) => write!(fmt, "WellFormed({})", ty), - FromEnvTy(ref ty) => write!(fmt, "FromEnv({})", ty), - RegionOutlives(ref predicate) => write!(fmt, "RegionOutlives({})", predicate), - TypeOutlives(ref predicate) => write!(fmt, "TypeOutlives({})", predicate), + WellFormed(Implemented(trait_ref)) => write!(fmt, "WellFormed({})", trait_ref), + WellFormed(ProjectionEq(projection)) => write!(fmt, "WellFormed({})", projection), + FromEnv(Implemented(trait_ref)) => write!(fmt, "FromEnv({})", trait_ref), + FromEnv(ProjectionEq(projection)) => write!(fmt, "FromEnv({})", projection), + WellFormedTy(ty) => write!(fmt, "WellFormed({})", ty), + FromEnvTy(ty) => write!(fmt, "FromEnv({})", ty), + RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate), + TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate), } } } @@ -457,27 +459,20 @@ impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> { impl fmt::Display for traits::QuantifierKind { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use traits::QuantifierKind::*; - match *self { + + match self { Universal => write!(fmt, "forall"), Existential => write!(fmt, "exists"), } } } -impl<'tcx> fmt::Display for traits::LeafGoal<'tcx> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - use traits::LeafGoal::*; - match *self { - DomainGoal(ref domain_goal) => write!(fmt, "{}", domain_goal), - } - } -} - impl<'tcx> fmt::Display for traits::Goal<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use traits::Goal::*; - match *self { - Implies(ref hypotheses, ref goal) => { + + match self { + Implies(hypotheses, goal) => { write!(fmt, "if (")?; for (index, hyp) in hypotheses.iter().enumerate() { if index > 0 { @@ -487,10 +482,10 @@ impl<'tcx> fmt::Display for traits::Goal<'tcx> { } write!(fmt, ") {{ {} }}", goal) } - And(ref goal1, ref goal2) => write!(fmt, "({}, {})", goal1, goal2), - Not(ref goal) => write!(fmt, "not {{ {} }}", goal), - Leaf(ref goal) => write!(fmt, "{}", goal), - Quantified(qkind, ref goal) => { + And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2), + Not(goal) => write!(fmt, "not {{ {} }}", goal), + DomainGoal(goal) => write!(fmt, "{}", goal), + Quantified(qkind, goal) => { // FIXME: appropriate binder names write!(fmt, "{}<> {{ {} }}", qkind, goal.skip_binder()) } @@ -498,113 +493,70 @@ impl<'tcx> fmt::Display for traits::Goal<'tcx> { } } -impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> { +impl<'tcx> fmt::Display for traits::Clause<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", self.consequence)?; - if self.conditions.is_empty() { - write!(fmt, ".")?; - } else { - write!(fmt, " :- ")?; - for (index, condition) in self.conditions.iter().enumerate() { - if index > 0 { - write!(fmt, ", ")?; + use traits::Clause::*; + + match self { + Implies(hypotheses, goal) => { + write!(fmt, "{}", goal)?; + if !hypotheses.is_empty() { + write!(fmt, " :- ")?; + for (index, condition) in hypotheses.iter().enumerate() { + if index > 0 { + write!(fmt, ", ")?; + } + write!(fmt, "{}", condition)?; + } } - write!(fmt, "{}", condition)?; + write!(fmt, ".") + } + DomainGoal(domain_goal) => write!(fmt, "{}.", domain_goal), + ForAll(clause) => { + // FIXME: appropriate binder names + write!(fmt, "forall<> {{ {} }}", clause.skip_binder()) } } - Ok(()) } } -impl<'tcx> TypeFoldable<'tcx> for traits::WhereClauseAtom<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use traits::WhereClauseAtom::*; - match *self { - Implemented(ref trait_ref) => Implemented(trait_ref.fold_with(folder)), - ProjectionEq(ref projection) => ProjectionEq(projection.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - use traits::WhereClauseAtom::*; - match *self { - Implemented(ref trait_ref) => trait_ref.visit_with(visitor), - ProjectionEq(ref projection) => projection.visit_with(visitor), - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for traits::WhereClauseAtom<'tcx> { + (traits::WhereClauseAtom::Implemented)(trait_ref), + (traits::WhereClauseAtom::ProjectionEq)(projection), } } -impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use traits::DomainGoal::*; - match *self { - Holds(ref wc) => Holds(wc.fold_with(folder)), - WellFormed(ref wc) => WellFormed(wc.fold_with(folder)), - FromEnv(ref wc) => FromEnv(wc.fold_with(folder)), - WellFormedTy(ref ty) => WellFormedTy(ty.fold_with(folder)), - FromEnvTy(ref ty) => FromEnvTy(ty.fold_with(folder)), - RegionOutlives(ref predicate) => RegionOutlives(predicate.fold_with(folder)), - TypeOutlives(ref predicate) => TypeOutlives(predicate.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - use traits::DomainGoal::*; - match *self { - Holds(ref wc) | - WellFormed(ref wc) | - FromEnv(ref wc) => wc.visit_with(visitor), - WellFormedTy(ref ty) | - FromEnvTy(ref ty) => ty.visit_with(visitor), - RegionOutlives(ref predicate) => predicate.visit_with(visitor), - TypeOutlives(ref predicate) => predicate.visit_with(visitor), - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> { + (traits::DomainGoal::Holds)(wc), + (traits::DomainGoal::WellFormed)(wc), + (traits::DomainGoal::FromEnv)(wc), + (traits::DomainGoal::WellFormedTy)(ty), + (traits::DomainGoal::FromEnvTy)(ty), + (traits::DomainGoal::RegionOutlives)(predicate), + (traits::DomainGoal::TypeOutlives)(predicate), } } -impl<'tcx> TypeFoldable<'tcx> for traits::LeafGoal<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use traits::LeafGoal::*; - match *self { - DomainGoal(ref domain_goal) => DomainGoal(domain_goal.fold_with(folder)), - } - } +CloneTypeFoldableImpls! { + traits::QuantifierKind, +} - fn super_visit_with>(&self, visitor: &mut V) -> bool { - use traits::LeafGoal::*; - match *self { - DomainGoal(ref domain_goal) => domain_goal.visit_with(visitor), - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> { + (traits::Goal::Implies)(hypotheses, goal), + (traits::Goal::And)(goal1, goal2), + (traits::Goal::Not)(goal), + (traits::Goal::DomainGoal)(domain_goal), + (traits::Goal::Quantified)(qkind, goal), } } -impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> { - fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { - use traits::Goal::*; - match *self { - Implies(ref hypotheses, ref goal) => { - Implies( - hypotheses.iter().map(|hyp| hyp.fold_with(folder)).collect(), - goal.fold_with(folder) - ) - }, - And(ref goal1, ref goal2) => And(goal1.fold_with(folder), goal2.fold_with(folder)), - Not(ref goal) => Not(goal.fold_with(folder)), - Leaf(ref leaf_goal) => Leaf(leaf_goal.fold_with(folder)), - Quantified(qkind, ref goal) => Quantified(qkind, goal.fold_with(folder)), - } - } - - fn super_visit_with>(&self, visitor: &mut V) -> bool { - use traits::Goal::*; - match *self { - Implies(ref hypotheses, ref goal) => { - hypotheses.iter().any(|hyp| hyp.visit_with(visitor)) || goal.visit_with(visitor) - } - And(ref goal1, ref goal2) => goal1.visit_with(visitor) || goal2.visit_with(visitor), - Not(ref goal) => goal.visit_with(visitor), - Leaf(ref leaf_goal) => leaf_goal.visit_with(visitor), - Quantified(_, ref goal) => goal.visit_with(visitor), - } +EnumTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for traits::Clause<'tcx> { + (traits::Clause::Implies)(hypotheses, goal), + (traits::Clause::DomainGoal)(domain_goal), + (traits::Clause::ForAll)(clause), } } diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 087c7d6d44df..50dfbeb9724c 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -38,7 +38,7 @@ use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal, NoSolution}; use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult}; use traits::query::normalize::NormalizationResult; use traits::specialization_graph; -use traits::ProgramClause; +use traits::Clause; use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt}; use ty::steal::Steal; use ty::subst::Substs; @@ -419,7 +419,7 @@ define_maps! { <'tcx> [] fn features_query: features_node(CrateNum) -> Lrc, - [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc>>, + [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc>>, } ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index fc1d26b0e091..ea116b4cd0a4 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1073,9 +1073,12 @@ impl<'tcx> PolyTraitPredicate<'tcx> { #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct OutlivesPredicate(pub A, pub B); // `A : B` pub type PolyOutlivesPredicate = ty::Binder>; -pub type PolyRegionOutlivesPredicate<'tcx> = PolyOutlivesPredicate, - ty::Region<'tcx>>; -pub type PolyTypeOutlivesPredicate<'tcx> = PolyOutlivesPredicate, ty::Region<'tcx>>; +pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, + ty::Region<'tcx>>; +pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, + ty::Region<'tcx>>; +pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder>; +pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder>; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct SubtypePredicate<'tcx> { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 69257e3e1139..68c9c946215d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1089,7 +1089,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, time(sess, "lint checking", || lint::check_crate(tcx)); - time(time_passes, "dumping chalk-like clauses", || traits::dump_program_clauses(tcx)); + time(sess, "dumping chalk-like clauses", || traits::dump_program_clauses(tcx)); return Ok(f(tcx, analysis, rx, tcx.sess.compile_status())); }) diff --git a/src/test/ui/chalkify/lower_impl.stderr b/src/test/ui/chalkify/lower_impl.stderr index 8645e4506efa..b5d791d640ad 100644 --- a/src/test/ui/chalkify/lower_impl.stderr +++ b/src/test/ui/chalkify/lower_impl.stderr @@ -1,4 +1,4 @@ -error: Implemented(T: Foo) :- ProjectionEq(::Item == i32), TypeOutlives(T : 'static), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized) +error: Implemented(T: Foo) :- ProjectionEq(::Item == i32), TypeOutlives(T : 'static), Implemented(T: std::iter::Iterator), Implemented(T: std::marker::Sized). --> $DIR/lower_impl.rs:15:1 | LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(T: Foo) :- From 2bbd16de13c6c9d67e3d94455b3740bbc9a81055 Mon Sep 17 00:00:00 2001 From: scalexm Date: Wed, 14 Mar 2018 14:45:30 +0100 Subject: [PATCH 197/830] Move code into librustc_traits --- src/librustc/traits/mod.rs | 6 ------ src/librustc_driver/driver.rs | 4 +++- src/librustc_traits/lib.rs | 2 ++ .../traits => librustc_traits}/lowering.rs | 16 ++++++++-------- 4 files changed, 13 insertions(+), 15 deletions(-) rename src/{librustc/traits => librustc_traits}/lowering.rs (93%) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index ea3db0c6e926..dce1a89d1426 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -63,7 +63,6 @@ mod specialize; mod structural_impls; pub mod trans; mod util; -mod lowering; pub mod query; @@ -297,10 +296,6 @@ pub enum Clause<'tcx> { ForAll(Box>>), } -pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - lowering::dump_program_clauses(tcx) -} - pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>; #[derive(Clone,Debug)] @@ -972,7 +967,6 @@ pub fn provide(providers: &mut ty::maps::Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, trans_fulfill_obligation: trans::trans_fulfill_obligation, - program_clauses_for: lowering::program_clauses_for, vtable_methods, substitute_normalize_and_test_predicates, ..*providers diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 68c9c946215d..61335391dab7 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1089,7 +1089,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, time(sess, "lint checking", || lint::check_crate(tcx)); - time(sess, "dumping chalk-like clauses", || traits::dump_program_clauses(tcx)); + time(sess, + "dumping chalk-like clauses", + || rustc_traits::lowering::dump_program_clauses(tcx)); return Ok(f(tcx, analysis, rx, tcx.sess.compile_status())); }) diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 45d23a2733a2..2a0f076cefde 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -29,6 +29,7 @@ mod dropck_outlives; mod normalize_projection_ty; mod normalize_erasing_regions; mod util; +pub mod lowering; use rustc::ty::maps::Providers; @@ -39,6 +40,7 @@ pub fn provide(p: &mut Providers) { normalize_projection_ty: normalize_projection_ty::normalize_projection_ty, normalize_ty_after_erasing_regions: normalize_erasing_regions::normalize_ty_after_erasing_regions, + program_clauses_for: lowering::program_clauses_for, ..*p }; } diff --git a/src/librustc/traits/lowering.rs b/src/librustc_traits/lowering.rs similarity index 93% rename from src/librustc/traits/lowering.rs rename to src/librustc_traits/lowering.rs index f31e474963ee..b69d97b67e83 100644 --- a/src/librustc/traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -8,13 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use hir::{self, ImplPolarity}; -use hir::def_id::DefId; -use hir::intravisit::{self, NestedVisitorMap, Visitor}; -use ty::{self, TyCtxt}; -use super::{QuantifierKind, Goal, DomainGoal, Clause, WhereClauseAtom}; -use rustc_data_structures::sync::Lrc; +use rustc::hir::{self, ImplPolarity}; +use rustc::hir::def_id::DefId; +use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; +use rustc::ty::{self, TyCtxt}; +use rustc::traits::{QuantifierKind, Goal, DomainGoal, Clause, WhereClauseAtom}; use syntax::ast; +use rustc_data_structures::sync::Lrc; trait Lower { fn lower(&self) -> T; @@ -72,7 +72,7 @@ impl<'tcx, T> Lower> for ty::Binder impl<'tcx> Lower> for ty::Predicate<'tcx> { fn lower(&self) -> Goal<'tcx> { - use ty::Predicate::*; + use rustc::ty::Predicate::*; match self { Trait(predicate) => predicate.lower(), @@ -88,7 +88,7 @@ impl<'tcx> Lower> for ty::Predicate<'tcx> { } } -pub fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) +crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Lrc>> { let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); From e8f3ed5db26981d2b5417a9de1d16f33770d8ff4 Mon Sep 17 00:00:00 2001 From: scalexm Date: Wed, 14 Mar 2018 15:19:17 +0100 Subject: [PATCH 198/830] Add documentation --- src/librustc/traits/mod.rs | 12 ++++++++++++ src/librustc_traits/lowering.rs | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index dce1a89d1426..8c5c36c36998 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -245,6 +245,14 @@ pub type Obligations<'tcx, O> = Vec>; pub type PredicateObligations<'tcx> = Vec>; pub type TraitObligations<'tcx> = Vec>; +/// The following types: +/// * `WhereClauseAtom` +/// * `DomainGoal` +/// * `Goal` +/// * `Clause` +/// are used for representing the trait system in the form of +/// logic programming clauses. They are part of the interface +/// for the chalk SLG solver. #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub enum WhereClauseAtom<'tcx> { Implemented(ty::TraitPredicate<'tcx>), @@ -270,6 +278,7 @@ pub enum QuantifierKind { #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum Goal<'tcx> { + // FIXME: use interned refs instead of `Box` Implies(Vec>, Box>), And(Box>, Box>), Not(Box>), @@ -289,8 +298,11 @@ impl<'tcx> From> for Clause<'tcx> { } } +/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary +/// Harrop Formulas". #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub enum Clause<'tcx> { + // FIXME: again, use interned refs instead of `Box` Implies(Vec>, DomainGoal<'tcx>), DomainGoal(DomainGoal<'tcx>), ForAll(Box>>), diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index b69d97b67e83..296ad18c480b 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -17,6 +17,7 @@ use syntax::ast; use rustc_data_structures::sync::Lrc; trait Lower { + /// Lower a rustc construction (e.g. `ty::TraitPredicate`) to a chalk-like type. fn lower(&self) -> T; } @@ -56,6 +57,15 @@ impl<'tcx> Lower> for ty::TypeOutlivesPredicate<'tcx> { } } +/// `ty::Binder` is used for wrapping a rustc construction possibly containing generic +/// lifetimes, e.g. `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things +/// in that leaf-form (i.e. `Holds(Implemented(Binder))` in the previous +/// example), we model them with quantified goals, e.g. as for the previous example: +/// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like +/// `Binder`. +/// +/// Also, if `self` does not contain generic lifetimes, we can safely drop the binder and we +/// can directly lower to a leaf goal instead of a quantified goal. impl<'tcx, T> Lower> for ty::Binder where T: Lower> + ty::fold::TypeFoldable<'tcx> + Copy { @@ -95,6 +105,8 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI let item = tcx.hir.expect_item(node_id); match item.node { hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id), + + // FIXME: other constructions e.g. traits, associated types... _ => Lrc::new(vec![]), } } From f83618b9dac3b92b554d3751dcdea9aeefc6e72a Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Wed, 14 Mar 2018 14:31:23 +0000 Subject: [PATCH 199/830] Update RELEASES.md --- RELEASES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 1b2097144d71..e6f6e0440839 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -60,6 +60,8 @@ Cargo Misc ---- +- [Rust by example is now shipped with new releases][46196] + Compatibility Notes ------------------- - [Deprecated `net::lookup_host`.][47510] @@ -90,6 +92,7 @@ Compatibility Notes [46830]: https://github.com/rust-lang/rust/pull/46830 [46095]: https://github.com/rust-lang/rust/pull/46095 [46666]: https://github.com/rust-lang/rust/pull/46666 +[46196]: https://github.com/rust-lang/rust/pull/46196 [cargo/5013]: https://github.com/rust-lang/cargo/pull/5013 [cargo/5029]: https://github.com/rust-lang/cargo/pull/5029 [RFC 1358]: https://github.com/rust-lang/rfcs/pull/1358 From c21480233e49d0e98f6cbd4d333e6be0a008082a Mon Sep 17 00:00:00 2001 From: Boris-Chengbiao Zhou Date: Wed, 14 Mar 2018 15:03:42 +0100 Subject: [PATCH 200/830] Update RLS --- src/Cargo.lock | 55 ++++++++++++++++++++++++++++++++++++++++++-------- src/tools/rls | 2 +- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index e34983e23c02..fe0069dac233 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -244,6 +244,18 @@ dependencies = [ "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cargo_metadata" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -322,7 +334,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.0.186" +version = "0.0.187" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1583,8 +1595,8 @@ name = "rls" version = "0.126.0" dependencies = [ "cargo 0.27.0", - "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.186 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.187 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1595,13 +1607,13 @@ dependencies = [ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-analysis 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-rustc 0.2.2 (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.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 0.3.8", + "rustfmt-nightly 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1610,7 +1622,7 @@ dependencies = [ [[package]] name = "rls-analysis" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2200,6 +2212,31 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustfmt-nightly" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.15 (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.39 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.2.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 = "same-file" version = "1.0.2" @@ -2851,11 +2888,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20d6fb2b5574726329c85cdba0df0347fddfec3cf9c8b588f9931708280f5643" +"checksum cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5caae26de3704081ef638f87f05a6891b04f2b7d5ce9429a3de21095528ae22" "checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" -"checksum clippy_lints 0.0.186 (registry+https://github.com/rust-lang/crates.io-index)" = "a3864104a4e6092e644b985dd7543e5f24e99aa7262f5ee400bcb17cfeec1bf5" +"checksum clippy_lints 0.0.187 (registry+https://github.com/rust-lang/crates.io-index)" = "f2227eeb80d00b3e6f67d27953224b2087a65e40597e3253b2a25493aac63859" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" @@ -2977,7 +3015,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48d7391e7e90e06eaf3aefbe4652464153ecfec64806f3bf77ffc59638a63e77" "checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" -"checksum rls-analysis 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39461c31c9ec26c2f15821d6aaa349216bf71e24e69550d9f8eeded78dc435e1" +"checksum rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4b9a3a3f2345854e39768e6425d1c893855da217183d1c0b3ff6f1664b6b6d" "checksum rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56fb7b8e4850b988fbcf277fbdb1eff36879070d02fc1ca243b559273866973d" "checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510" "checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea" @@ -2991,6 +3029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0" "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum rustfmt-nightly 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "554256054eae37ead2f799ffa9cf8be8249496c6c3cf005c28b7cfa55f4efaa5" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4" "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" diff --git a/src/tools/rls b/src/tools/rls index d4f0b29d0ce0..b6c524434249 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit d4f0b29d0ce01f0716d3b147d68125d520b63ae5 +Subproject commit b6c52443424977bd92cf7ed127f7771fe9c285da From 017bfc361170d43fb9f93e6fed535e1719a680b4 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Mon, 5 Mar 2018 16:05:38 -0600 Subject: [PATCH 201/830] expose #[target_feature] attributes in rustdoc --- src/librustdoc/clean/cfg.rs | 40 +++++++++++++++++++++++++++++++++++-- src/librustdoc/clean/mod.rs | 13 ++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 5cac2d1bbe7e..c228f54217d3 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -138,7 +138,7 @@ impl Cfg { /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { - let mut msg = Html(self).to_string(); + let mut msg = ShortHtml(self).to_string(); if self.should_capitalize_first_letter() { if let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) { msg[i .. i+1].make_ascii_uppercase(); @@ -149,7 +149,13 @@ impl Cfg { /// Renders the configuration for long display, as a long HTML description. pub(crate) fn render_long_html(&self) -> String { - let mut msg = format!("This is supported on {}", Html(self)); + let on = if self.should_use_with_in_description() { + "with" + } else { + "on" + }; + + let mut msg = format!("This is supported {} {}", on, Html(self)); if self.should_append_only_to_description() { msg.push_str(" only"); } @@ -180,6 +186,13 @@ impl Cfg { } } } + + fn should_use_with_in_description(&self) -> bool { + match *self { + Cfg::Cfg(ref name, _) if name == &"target_feature" => true, + _ => false, + } + } } impl ops::Not for Cfg { @@ -376,6 +389,8 @@ impl<'a> fmt::Display for Html<'a> { }, ("target_endian", Some(endian)) => return write!(fmt, "{}-endian", endian), ("target_pointer_width", Some(bits)) => return write!(fmt, "{}-bit", bits), + ("target_feature", Some(feat)) => + return write!(fmt, "target feature {}", feat), _ => "", }; if !human_readable.is_empty() { @@ -390,6 +405,19 @@ impl<'a> fmt::Display for Html<'a> { } } +struct ShortHtml<'a>(&'a Cfg); + +impl<'a> fmt::Display for ShortHtml<'a> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + Cfg::Cfg(ref name, Some(ref vendor)) if name == &"target_feature" => { + write!(fmt, "{}", vendor) + }, + ref cfg => write!(fmt, "{}", Html(cfg)), + } + } +} + #[cfg(test)] mod test { use super::Cfg; @@ -824,6 +852,10 @@ mod test { ).render_short_html(), "(Debug-assertions enabled or Windows) and Unix" ); + assert_eq!( + name_value_cfg("target_feature", "sse2").render_short_html(), + "sse2" + ); }) } @@ -898,6 +930,10 @@ mod test { "This is supported on (debug-assertions enabled or Windows) and Unix\ only." ); + assert_eq!( + name_value_cfg("target_feature", "sse2").render_long_html(), + "This is supported with target feature sse2 only." + ); }) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ff281a53ab7e..d6897617d556 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -828,6 +828,19 @@ impl Attributes { }) }).collect(); + // treat #[target_feature(enable = "feat")] attributes as if they were + // #[doc(cfg(target_feature = "feat"))] attributes as well + for attr in attrs.lists("target_feature") { + if attr.check_name("enable") { + if let Some(feat) = attr.value_str() { + let meta = attr::mk_name_value_item_str("target_feature".into(), feat); + if let Ok(feat_cfg) = Cfg::parse(&meta) { + cfg &= feat_cfg; + } + } + } + } + Attributes { doc_strings, other_attrs, From 07ce659dd03523b526cb4804b9ef882f31e9ecf3 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 14 Mar 2018 17:22:40 +0100 Subject: [PATCH 202/830] expose ordered/unordered/nanless intirnsics --- src/librustc_trans/builder.rs | 18 + src/librustc_trans/intrinsic.rs | 316 +++++++----------- src/librustc_typeck/check/intrinsic.rs | 7 +- src/rustllvm/RustWrapper.cpp | 2 + .../simd-intrinsic-generic-reduction.rs | 104 +++--- 5 files changed, 210 insertions(+), 237 deletions(-) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 2c38197d68ec..371f53013b90 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -958,6 +958,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fadd_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fadd_fast"); unsafe { + // FIXME: add a non-fast math version once + // https://bugs.llvm.org/show_bug.cgi?id=36732 + // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr @@ -966,6 +969,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmul_fast(&self, acc: ValueRef, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmul_fast"); unsafe { + // FIXME: add a non-fast math version once + // https://bugs.llvm.org/show_bug.cgi?id=36732 + // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr @@ -1001,6 +1007,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) } } + pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmin"); + unsafe { + llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true) + } + } + pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef { + self.count_insn("vector.reduce.fmax"); + unsafe { + llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true) + } + } pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin_fast"); unsafe { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 011273f02e11..8b62a1be80c3 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1150,210 +1150,134 @@ fn generic_simd_intrinsic<'a, 'tcx>( return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) } - if name == "simd_reduce_add" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_add(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_add(args[0].immediate())) - }, - ty::TyFloat(f) => { - // undef as accumulator makes the reduction unordered: - let acc = match f.bit_width() { - 32 => C_undef(Type::f32(bx.cx)), - 64 => C_undef(Type::f64(bx.cx)), - v => { - return_error!( - "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", - "simd_reduce_add", in_ty, in_elem, v, ret_ty) + macro_rules! arith_red { + ($name:tt : $integer_reduce:ident, $float_reduce:ident, $ordered:expr) => { + if name == $name { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_) | ty::TyUint(_) => { + let r = bx.$integer_reduce(args[0].immediate()); + if $ordered { + // if overflow occurs, the result is the + // mathematical result modulo 2^n: + if name.contains("mul") { + Ok(bx.mul(args[1].immediate(), r)) + } else { + Ok(bx.add(args[1].immediate(), r)) + } + } else { + Ok(bx.$integer_reduce(args[0].immediate())) + } + }, + ty::TyFloat(f) => { + // ordered arithmetic reductions take an accumulator + let acc = if $ordered { + args[1].immediate() + } else { + // unordered arithmetic reductions do not: + match f.bit_width() { + 32 => C_undef(Type::f32(bx.cx)), + 64 => C_undef(Type::f64(bx.cx)), + v => { + return_error!( + "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", + $name, in_ty, in_elem, v, ret_ty + ) + } + } + + }; + Ok(bx.$float_reduce(acc, args[0].immediate())) } - }; - Ok(bx.vector_reduce_fadd_fast(acc, args[0].immediate())) - } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_add", in_ty, in_elem, ret_ty) - }, - } - } - - if name == "simd_reduce_mul" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_mul(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_mul(args[0].immediate())) - }, - ty::TyFloat(f) => { - // undef as accumulator makes the reduction unordered: - let acc = match f.bit_width() { - 32 => C_undef(Type::f32(bx.cx)), - 64 => C_undef(Type::f64(bx.cx)), - v => { + _ => { return_error!( - "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", - "simd_reduce_mul", in_ty, in_elem, v, ret_ty) + "unsupported {} from `{}` with element `{}` to `{}`", + $name, in_ty, in_elem, ret_ty + ) + }, + } + } + } + } + + arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd_fast, true); + arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul_fast, true); + arith_red!("simd_reduce_add_unordered": vector_reduce_add, vector_reduce_fadd_fast, false); + arith_red!("simd_reduce_mul_unordered": vector_reduce_mul, vector_reduce_fmul_fast, false); + + macro_rules! minmax_red { + ($name:tt: $int_red:ident, $float_red:ident) => { + if name == $name { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + return match in_elem.sty { + ty::TyInt(_i) => { + Ok(bx.$int_red(args[0].immediate(), true)) + }, + ty::TyUint(_u) => { + Ok(bx.$int_red(args[0].immediate(), false)) + }, + ty::TyFloat(_f) => { + Ok(bx.$float_red(args[0].immediate())) } + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + $name, in_ty, in_elem, ret_ty) + }, + } + } + + } + } + + minmax_red!("simd_reduce_min": vector_reduce_min, vector_reduce_fmin); + minmax_red!("simd_reduce_max": vector_reduce_max, vector_reduce_fmax); + + minmax_red!("simd_reduce_min_nanless": vector_reduce_min, vector_reduce_fmin_fast); + minmax_red!("simd_reduce_max_nanless": vector_reduce_max, vector_reduce_fmax_fast); + + macro_rules! bitwise_red { + ($name:tt : $red:ident, $boolean:expr) => { + if name == $name { + let input = if !$boolean { + require!(ret_ty == in_elem, + "expected return type `{}` (element of input `{}`), found `{}`", + in_elem, in_ty, ret_ty); + args[0].immediate() + } else { + // boolean reductions operate on vectors of i1s: + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, in_len as u64); + bx.trunc(args[0].immediate(), i1xn) }; - Ok(bx.vector_reduce_fmul_fast(acc, args[0].immediate())) + return match in_elem.sty { + ty::TyInt(_) | ty::TyUint(_) => { + let r = bx.$red(input); + Ok( + if !$boolean { + r + } else { + bx.zext(r, Type::bool(bx.cx)) + } + ) + }, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + $name, in_ty, in_elem, ret_ty) + }, + } } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_mul", in_ty, in_elem, ret_ty) - }, } } - if name == "simd_reduce_min" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_min(args[0].immediate(), true)) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_min(args[0].immediate(), false)) - }, - ty::TyFloat(_f) => { - Ok(bx.vector_reduce_fmin_fast(args[0].immediate())) - } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_min", in_ty, in_elem, ret_ty) - }, - } - } - - if name == "simd_reduce_max" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_max(args[0].immediate(), true)) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_max(args[0].immediate(), false)) - }, - ty::TyFloat(_f) => { - Ok(bx.vector_reduce_fmax_fast(args[0].immediate())) - } - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_max", in_ty, in_elem, ret_ty) - }, - } - } - - if name == "simd_reduce_and" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_and(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_and(args[0].immediate())) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_and", in_ty, in_elem, ret_ty) - }, - } - } - - if name == "simd_reduce_or" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_or(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_or(args[0].immediate())) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_or", in_ty, in_elem, ret_ty) - }, - } - } - - if name == "simd_reduce_xor" { - require!(ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, in_ty, ret_ty); - return match in_elem.sty { - ty::TyInt(_i) => { - Ok(bx.vector_reduce_xor(args[0].immediate())) - }, - ty::TyUint(_u) => { - Ok(bx.vector_reduce_xor(args[0].immediate())) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_xor", in_ty, in_elem, ret_ty) - }, - } - } - - if name == "simd_reduce_all" { - //require!(ret_ty == in_elem, - // "expected return type `{}` (element of input `{}`), found `{}`", - // in_elem, in_ty, ret_ty); - let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, in_len as u64); - let v = bx.trunc(args[0].immediate(), i1xn); - - let red = match in_elem.sty { - ty::TyInt(_i) => { - bx.vector_reduce_and(v) - }, - ty::TyUint(_u) => { - bx.vector_reduce_and(v) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_and", in_ty, in_elem, ret_ty) - }, - }; - return Ok(bx.zext(red, Type::bool(bx.cx))); - } - - if name == "simd_reduce_any" { - //require!(ret_ty == in_elem, - // "expected return type `{}` (element of input `{}`), found `{}`", - // in_elem, in_ty, ret_ty); - let i1 = Type::i1(bx.cx); - let i1xn = Type::vector(&i1, in_len as u64); - let v = bx.trunc(args[0].immediate(), i1xn); - - let red = match in_elem.sty { - ty::TyInt(_i) => { - bx.vector_reduce_or(v) - }, - ty::TyUint(_u) => { - bx.vector_reduce_or(v) - }, - _ => { - return_error!("unsupported {} from `{}` with element `{}` to `{}`", - "simd_reduce_and", in_ty, in_elem, ret_ty) - }, - }; - return Ok(bx.zext(red, Type::bool(bx.cx))); - } - + bitwise_red!("simd_reduce_and": vector_reduce_and, false); + bitwise_red!("simd_reduce_or": vector_reduce_or, false); + bitwise_red!("simd_reduce_xor": vector_reduce_xor, false); + bitwise_red!("simd_reduce_all": vector_reduce_and, true); + bitwise_red!("simd_reduce_any": vector_reduce_or, true); if name == "simd_cast" { require_simd!(ret_ty, "return"); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index f2d01c57f298..b87b8aa0bdb6 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -362,9 +362,12 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), - "simd_reduce_add" | "simd_reduce_mul" | + "simd_reduce_add_ordered" | "simd_reduce_mul_ordered" + => (2, vec![param(0), param(1)], param(1)), + "simd_reduce_add_unordered" | "simd_reduce_mul_unordered" | "simd_reduce_and" | "simd_reduce_or" | "simd_reduce_xor" | - "simd_reduce_min" | "simd_reduce_max" + "simd_reduce_min" | "simd_reduce_max" | + "simd_reduce_min_nanless" | "simd_reduce_max_nanless" => (2, vec![param(0)], param(1)), name if name.starts_with("simd_shuffle") => { match name["simd_shuffle".len()..].parse() { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index e749549201e6..9d5f9042f187 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1397,6 +1397,7 @@ LLVMRustModuleCost(LLVMModuleRef M) { } // Vector reductions: +#if LLVM_VERSION_GE(6, 0) extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); @@ -1441,3 +1442,4 @@ extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); } +#endif diff --git a/src/test/run-pass/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd-intrinsic-generic-reduction.rs index 15b291ae179c..6755c92961b1 100644 --- a/src/test/run-pass/simd-intrinsic-generic-reduction.rs +++ b/src/test/run-pass/simd-intrinsic-generic-reduction.rs @@ -39,10 +39,14 @@ struct b8x16( ); extern "platform-intrinsic" { - fn simd_reduce_add(x: T) -> U; - fn simd_reduce_mul(x: T) -> U; + fn simd_reduce_add_unordered(x: T) -> U; + fn simd_reduce_mul_unordered(x: T) -> U; + fn simd_reduce_add_ordered(x: T, acc: U) -> U; + fn simd_reduce_mul_ordered(x: T, acc: U) -> U; fn simd_reduce_min(x: T) -> U; fn simd_reduce_max(x: T) -> U; + fn simd_reduce_min_nanless(x: T) -> U; + fn simd_reduce_max_nanless(x: T) -> U; fn simd_reduce_and(x: T) -> U; fn simd_reduce_or(x: T) -> U; fn simd_reduce_xor(x: T) -> U; @@ -53,91 +57,113 @@ extern "platform-intrinsic" { fn main() { unsafe { let x = i32x4(1, -2, 3, 4); - let r: i32 = simd_reduce_add(x); - assert!(r == 6_i32); - let r: i32 = simd_reduce_mul(x); - assert!(r == -24_i32); + let r: i32 = simd_reduce_add_unordered(x); + assert_eq!(r, 6_i32); + let r: i32 = simd_reduce_mul_unordered(x); + assert_eq!(r, -24_i32); + let r: i32 = simd_reduce_add_ordered(x, -1); + assert_eq!(r, 5_i32); + let r: i32 = simd_reduce_mul_ordered(x, -1); + assert_eq!(r, 24_i32); + let r: i32 = simd_reduce_min(x); - assert!(r == -21_i32); + assert_eq!(r, -2_i32); let r: i32 = simd_reduce_max(x); - assert!(r == 4_i32); + assert_eq!(r, 4_i32); let x = i32x4(-1, -1, -1, -1); let r: i32 = simd_reduce_and(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); let r: i32 = simd_reduce_or(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); let r: i32 = simd_reduce_xor(x); - assert!(r == 0_i32); + assert_eq!(r, 0_i32); let x = i32x4(-1, -1, 0, -1); let r: i32 = simd_reduce_and(x); - assert!(r == 0_i32); + assert_eq!(r, 0_i32); let r: i32 = simd_reduce_or(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); let r: i32 = simd_reduce_xor(x); - assert!(r == -1_i32); + assert_eq!(r, -1_i32); } unsafe { let x = u32x4(1, 2, 3, 4); - let r: u32 = simd_reduce_add(x); - assert!(r == 10_u32); - let r: u32 = simd_reduce_mul(x); - assert!(r == 24_u32); + let r: u32 = simd_reduce_add_unordered(x); + assert_eq!(r, 10_u32); + let r: u32 = simd_reduce_mul_unordered(x); + assert_eq!(r, 24_u32); + let r: u32 = simd_reduce_add_ordered(x, 1); + assert_eq!(r, 11_u32); + let r: u32 = simd_reduce_mul_ordered(x, 2); + assert_eq!(r, 48_u32); + let r: u32 = simd_reduce_min(x); - assert!(r == 1_u32); + assert_eq!(r, 1_u32); let r: u32 = simd_reduce_max(x); - assert!(r == 4_u32); + assert_eq!(r, 4_u32); let t = u32::max_value(); let x = u32x4(t, t, t, t); let r: u32 = simd_reduce_and(x); - assert!(r == t); + assert_eq!(r, t); let r: u32 = simd_reduce_or(x); - assert!(r == t); + assert_eq!(r, t); let r: u32 = simd_reduce_xor(x); - assert!(r == 0_u32); + assert_eq!(r, 0_u32); let x = u32x4(t, t, 0, t); let r: u32 = simd_reduce_and(x); - assert!(r == 0_u32); + assert_eq!(r, 0_u32); let r: u32 = simd_reduce_or(x); - assert!(r == t); + assert_eq!(r, t); let r: u32 = simd_reduce_xor(x); - assert!(r == t); + assert_eq!(r, t); } unsafe { let x = f32x4(1., -2., 3., 4.); - let r: f32 = simd_reduce_add(x); - assert!(r == 6_f32); - let r: f32 = simd_reduce_mul(x); - assert!(r == -24_f32); + let r: f32 = simd_reduce_add_unordered(x); + assert_eq!(r, 6_f32); + let r: f32 = simd_reduce_mul_unordered(x); + assert_eq!(r, -24_f32); + // FIXME: only works correctly for accumulator, 0: + // https://bugs.llvm.org/show_bug.cgi?id=36734 + let r: f32 = simd_reduce_add_ordered(x, 0.); + assert_eq!(r, 6_f32); + // FIXME: only works correctly for accumulator, 1: + // https://bugs.llvm.org/show_bug.cgi?id=36734 + let r: f32 = simd_reduce_mul_ordered(x, 1.); + assert_eq!(r, -24_f32); + let r: f32 = simd_reduce_min(x); - assert!(r == -2_f32); + assert_eq!(r, -2_f32); let r: f32 = simd_reduce_max(x); - assert!(r == 4_f32); + assert_eq!(r, 4_f32); + let r: f32 = simd_reduce_min_nanless(x); + assert_eq!(r, -2_f32); + let r: f32 = simd_reduce_max_nanless(x); + assert_eq!(r, 4_f32); } unsafe { let x = b8x4(!0, !0, !0, !0); let r: bool = simd_reduce_all(x); - //let r: bool = foobar(x); - assert!(r); + assert_eq!(r, true); let r: bool = simd_reduce_any(x); - assert!(r); + assert_eq!(r, true); let x = b8x4(!0, !0, 0, !0); let r: bool = simd_reduce_all(x); - assert!(!r); + assert_eq!(r, false); let r: bool = simd_reduce_any(x); - assert!(r); + assert_eq!(r, true); let x = b8x4(0, 0, 0, 0); let r: bool = simd_reduce_all(x); - assert!(!r); + assert_eq!(r, false); let r: bool = simd_reduce_any(x); - assert!(!r); + assert_eq!(r, false); } } From b4b7ccbd1ce1d794f4f9718ec0182b15591b73fa Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 3 Mar 2018 12:26:18 -0800 Subject: [PATCH 203/830] Add crate name to "main function not found" error message. Fixes #44798 and rust-lang/cargo#4948. --- src/librustc/middle/entry.rs | 11 +++++++---- src/librustc_driver/driver.rs | 2 +- src/test/ui/error-codes/E0522.stderr | 2 +- src/test/ui/feature-gate-i128_type2.stderr | 2 +- .../feature-gate/issue-43106-gating-of-bench.stderr | 2 +- .../feature-gate/issue-43106-gating-of-inline.stderr | 2 +- .../issue-43106-gating-of-macro_escape.stderr | 2 +- .../issue-43106-gating-of-proc_macro_derive.stderr | 2 +- .../issue-43106-gating-of-rustc_deprecated.stderr | 2 +- .../feature-gate/issue-43106-gating-of-stable.stderr | 2 +- .../ui/feature-gate/issue-43106-gating-of-test.stderr | 2 +- .../issue-43106-gating-of-unstable.stderr | 2 +- src/test/ui/generator/yield-in-const.stderr | 2 +- src/test/ui/generator/yield-in-static.stderr | 2 +- src/test/ui/imports/macro-paths.stderr | 2 +- src/test/ui/imports/macros.stderr | 2 +- .../in-band-lifetimes/mismatched_trait_impl-2.stderr | 2 +- src/test/ui/issue-47706-trait.stderr | 2 +- src/test/ui/main-wrong-location.stderr | 2 +- src/test/ui/missing-items/m2.stderr | 2 +- src/test/ui/resolve/issue-14254.stderr | 2 +- src/test/ui/resolve/issue-21221-2.stderr | 2 +- .../suggest-path-instead-of-mod-dot-item.stderr | 2 +- src/test/ui/span/issue-35987.stderr | 2 +- src/test/ui/token/issue-10636-2.stderr | 2 +- src/test/ui/token/issue-41155.stderr | 2 +- 26 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 8b4b9aaeac84..3473923c411f 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -55,7 +55,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> { } } -pub fn find_entry_point(session: &Session, hir_map: &hir_map::Map) { +pub fn find_entry_point(session: &Session, + hir_map: &hir_map::Map, + crate_name: &str) { let any_exe = session.crate_types.borrow().iter().any(|ty| { *ty == config::CrateTypeExecutable }); @@ -81,7 +83,7 @@ pub fn find_entry_point(session: &Session, hir_map: &hir_map::Map) { hir_map.krate().visit_all_item_likes(&mut ctxt); - configure_main(&mut ctxt); + configure_main(&mut ctxt, crate_name); } // Beware, this is duplicated in libsyntax/entry.rs, make sure to keep @@ -150,7 +152,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) { } } -fn configure_main(this: &mut EntryContext) { +fn configure_main(this: &mut EntryContext, crate_name: &str) { if this.start_fn.is_some() { *this.session.entry_fn.borrow_mut() = this.start_fn; this.session.entry_type.set(Some(config::EntryStart)); @@ -162,7 +164,8 @@ fn configure_main(this: &mut EntryContext) { this.session.entry_type.set(Some(config::EntryMain)); } else { // No main function - let mut err = struct_err!(this.session, E0601, "main function not found"); + let mut err = struct_err!(this.session, E0601, + "main function not found in crate {}", crate_name); if !this.non_main_fns.is_empty() { // There were some functions named 'main' though. Try to give the user a hint. err.note("the main function must be defined at the crate level \ diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 542f818c3818..e52575f02b2f 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -979,7 +979,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(trans: &TransCrate, time(sess, "looking for entry point", - || middle::entry::find_entry_point(sess, &hir_map)); + || middle::entry::find_entry_point(sess, &hir_map, name)); sess.plugin_registrar_fn.set(time(sess, "looking for plugin registrar", || { plugin::build::find_plugin_registrar(sess.diagnostic(), &hir_map) diff --git a/src/test/ui/error-codes/E0522.stderr b/src/test/ui/error-codes/E0522.stderr index 5a6331bca0bd..31898312133e 100644 --- a/src/test/ui/error-codes/E0522.stderr +++ b/src/test/ui/error-codes/E0522.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate E0522 error[E0522]: definition of an unknown language item: `cookie` --> $DIR/E0522.rs:13:1 diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr index 2348e7fe2c5b..89b17ddbf001 100644 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ b/src/test/ui/feature-gate-i128_type2.stderr @@ -30,7 +30,7 @@ LL | let x: u128 = 0; //~ ERROR 128-bit type is unstable | = help: add #![feature(i128_type)] to the crate attributes to enable -error[E0601]: main function not found +error[E0601]: main function not found in crate feature_gate_i128_type2 error[E0658]: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:30:1 diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr index f9f1cce91f1c..27bf9c99652b 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_bench error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr index 36320be1dc81..68f3099ff7e1 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_inline error[E0518]: attribute should be applied to function --> $DIR/issue-43106-gating-of-inline.rs:21:1 diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index d1d37720a55d..f8c1d9204af4 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -6,7 +6,7 @@ LL | #![macro_escape] | = help: consider an outer attribute, #[macro_use] mod ... -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_macro_escape error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr index c7654a3f258c..de4ef084e4f2 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr @@ -34,7 +34,7 @@ error: the `#[proc_macro_derive]` attribute may only be used on bare functions LL | #[proc_macro_derive = "2500"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_proc_macro_derive error: aborting due to 7 previous errors diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr index 5a1dd706ff3c..af1e659d48c8 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_rustc_deprecated error: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:17:1 diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr index bee9b8e96820..ebdaecc08782 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_stable error: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:17:1 diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr index f9f1cce91f1c..0d35be76d924 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_test error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr index 970cc2f2a349..3da5f0cec92b 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_43106_gating_of_unstable error: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:17:1 diff --git a/src/test/ui/generator/yield-in-const.stderr b/src/test/ui/generator/yield-in-const.stderr index 41a20893f5c4..f37a881a451f 100644 --- a/src/test/ui/generator/yield-in-const.stderr +++ b/src/test/ui/generator/yield-in-const.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate yield_in_const error[E0627]: yield statement outside of generator literal --> $DIR/yield-in-const.rs:13:17 diff --git a/src/test/ui/generator/yield-in-static.stderr b/src/test/ui/generator/yield-in-static.stderr index 71ebc189035a..0ade7a20cac8 100644 --- a/src/test/ui/generator/yield-in-static.stderr +++ b/src/test/ui/generator/yield-in-static.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate yield_in_static error[E0627]: yield statement outside of generator literal --> $DIR/yield-in-static.rs:13:18 diff --git a/src/test/ui/imports/macro-paths.stderr b/src/test/ui/imports/macro-paths.stderr index 1422fb0904d0..bf33bfaaf1fa 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -36,7 +36,7 @@ LL | | } | |_^ = note: macro-expanded items do not shadow when used in a macro invocation path -error[E0601]: main function not found +error[E0601]: main function not found in crate macro_paths error: aborting due to 3 previous errors diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr index d74020ecab29..c7a89df2a97a 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -51,7 +51,7 @@ LL | use two_macros::m; | ^^^^^^^^^^^^^ = note: macro-expanded macro imports do not shadow -error[E0601]: main function not found +error[E0601]: main function not found in crate macros error: aborting due to 4 previous errors diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr index a3d05e72ed9f..816a27086cce 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate mismatched_trait_impl_2 error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements --> $DIR/mismatched_trait_impl-2.rs:18:5 diff --git a/src/test/ui/issue-47706-trait.stderr b/src/test/ui/issue-47706-trait.stderr index 542ba5017806..069ae9994a1a 100644 --- a/src/test/ui/issue-47706-trait.stderr +++ b/src/test/ui/issue-47706-trait.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_47706_trait error[E0593]: function is expected to take a single 0-tuple as argument, but it takes 2 distinct arguments --> $DIR/issue-47706-trait.rs:13:20 diff --git a/src/test/ui/main-wrong-location.stderr b/src/test/ui/main-wrong-location.stderr index aad68de9ec79..c5affade5e21 100644 --- a/src/test/ui/main-wrong-location.stderr +++ b/src/test/ui/main-wrong-location.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate main_wrong_location | = note: the main function must be defined at the crate level but you have one or more functions named 'main' that are not defined at the crate level. Either move the definition or attach the `#[main]` attribute to override this behavior. note: here is a function named 'main' diff --git a/src/test/ui/missing-items/m2.stderr b/src/test/ui/missing-items/m2.stderr index 1e4b47b44fab..3b611518283b 100644 --- a/src/test/ui/missing-items/m2.stderr +++ b/src/test/ui/missing-items/m2.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found +error[E0601]: main function not found in crate m2 error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `method` --> $DIR/m2.rs:19:1 diff --git a/src/test/ui/resolve/issue-14254.stderr b/src/test/ui/resolve/issue-14254.stderr index 325e88508452..395ca412f351 100644 --- a/src/test/ui/resolve/issue-14254.stderr +++ b/src/test/ui/resolve/issue-14254.stderr @@ -142,7 +142,7 @@ error[E0425]: cannot find value `bah` in this scope LL | bah; | ^^^ help: try: `Self::bah` -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_14254 error: aborting due to 25 previous errors diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index 50781d437927..fdafb509268a 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -8,7 +8,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use foo::bar::T; | -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_21221_2 error: cannot continue compilation due to previous error diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index 263319f2ffa9..e1a205e7b3eb 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -72,7 +72,7 @@ LL | a::b() | | | did you mean `I`? -error[E0601]: main function not found +error[E0601]: main function not found in crate suggest_path_instead_of_mod_dot_item error: aborting due to 10 previous errors diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index d3267d0cc157..09d34f3d1afd 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -8,7 +8,7 @@ help: possible better candidate is found in another module, you can import it in LL | use std::ops::Add; | -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_35987 error: cannot continue compilation due to previous error diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr index 4b672f31d385..273cabb0474e 100644 --- a/src/test/ui/token/issue-10636-2.stderr +++ b/src/test/ui/token/issue-10636-2.stderr @@ -22,7 +22,7 @@ error: expected expression, found `)` LL | } //~ ERROR: incorrect close delimiter | ^ expected expression -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_10636_2 error: aborting due to 4 previous errors diff --git a/src/test/ui/token/issue-41155.stderr b/src/test/ui/token/issue-41155.stderr index 00155cc28734..80a4d43116f5 100644 --- a/src/test/ui/token/issue-41155.stderr +++ b/src/test/ui/token/issue-41155.stderr @@ -12,7 +12,7 @@ error[E0412]: cannot find type `S` in this scope LL | impl S { //~ ERROR cannot find type | ^ not found in this scope -error[E0601]: main function not found +error[E0601]: main function not found in crate issue_41155 error: aborting due to 3 previous errors From 51832c36b73107fcee63728dee5a5f3798ea4059 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 14 Mar 2018 20:14:47 +0100 Subject: [PATCH 204/830] fix style --- src/librustc_trans/intrinsic.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 8b62a1be80c3..72c619a3b0ca 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1181,8 +1181,8 @@ fn generic_simd_intrinsic<'a, 'tcx>( 32 => C_undef(Type::f32(bx.cx)), 64 => C_undef(Type::f64(bx.cx)), v => { - return_error!( - "unsupported {} from `{}` with element `{}` of size `{}` to `{}`", + return_error!(r#" +unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, $name, in_ty, in_elem, v, ret_ty ) } From 19b5113c8d948f7324b4ef8826d1833e84ba8b49 Mon Sep 17 00:00:00 2001 From: "dragan.mladjenovic" Date: Wed, 14 Mar 2018 19:24:01 +0100 Subject: [PATCH 205/830] rustc_trans: fix small aggregate returns for big-endian mips64 FFI Current model of threating small aggregate returns as smallest encompassing integer works only for little-endian mips64. The patch forces small aggregate return values to be viewed as one or two i64 chunks leaving to the casting implementation to handle endianes differences. --- src/librustc_trans/cabi_mips64.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/librustc_trans/cabi_mips64.rs b/src/librustc_trans/cabi_mips64.rs index 94bf53cee1ed..231fe4c6edb6 100644 --- a/src/librustc_trans/cabi_mips64.rs +++ b/src/librustc_trans/cabi_mips64.rs @@ -28,18 +28,6 @@ fn extend_integer_width_mips(arg: &mut ArgType, bits: u64) { arg.extend_integer_width_to(bits); } -fn bits_to_int_reg(bits: u64) -> Reg { - if bits <= 8 { - Reg::i8() - } else if bits <= 16 { - Reg::i16() - } else if bits <= 32 { - Reg::i32() - } else { - Reg::i64() - } -} - fn float_reg<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &ArgType<'tcx>, i: usize) -> Option { match ret.layout.field(cx, i).abi { layout::Abi::Scalar(ref scalar) => match scalar.value { @@ -82,7 +70,7 @@ fn classify_ret_ty<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>) // Cast to a uniform int structure ret.cast_to(Uniform { - unit: bits_to_int_reg(bits), + unit: Reg::i64(), total: size }); } else { From 6aa4dcb9cf615ca4dd01b5f732d171103028c78b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 12 Mar 2018 13:21:43 -0700 Subject: [PATCH 206/830] Add empty main() to tests where it is missing. --- src/test/ui/error-codes/E0522.rs | 2 ++ src/test/ui/error-codes/E0522.stderr | 7 ++----- src/test/ui/feature-gate-i128_type2.rs | 2 ++ src/test/ui/feature-gate-i128_type2.stderr | 7 ++----- src/test/ui/feature-gate/issue-43106-gating-of-inline.rs | 2 ++ .../ui/feature-gate/issue-43106-gating-of-inline.stderr | 7 ++----- .../ui/feature-gate/issue-43106-gating-of-macro_escape.rs | 4 ++++ .../feature-gate/issue-43106-gating-of-macro_escape.stderr | 7 +------ .../issue-43106-gating-of-proc_macro_derive.rs | 2 ++ .../issue-43106-gating-of-proc_macro_derive.stderr | 5 +---- .../feature-gate/issue-43106-gating-of-rustc_deprecated.rs | 1 + .../issue-43106-gating-of-rustc_deprecated.stderr | 5 +---- src/test/ui/feature-gate/issue-43106-gating-of-stable.rs | 2 ++ .../ui/feature-gate/issue-43106-gating-of-stable.stderr | 5 +---- src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs | 2 ++ .../ui/feature-gate/issue-43106-gating-of-unstable.stderr | 5 +---- src/test/ui/generator/yield-in-const.rs | 2 ++ src/test/ui/generator/yield-in-const.stderr | 7 ++----- src/test/ui/generator/yield-in-static.rs | 2 ++ src/test/ui/generator/yield-in-static.stderr | 7 ++----- src/test/ui/imports/macro-paths.rs | 2 ++ src/test/ui/imports/macro-paths.stderr | 7 ++----- src/test/ui/imports/macros.rs | 2 ++ src/test/ui/imports/macros.stderr | 7 ++----- src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs | 2 ++ .../ui/in-band-lifetimes/mismatched_trait_impl-2.stderr | 7 ++----- src/test/ui/issue-47706-trait.rs | 2 ++ src/test/ui/issue-47706-trait.stderr | 7 ++----- src/test/ui/missing-items/m2.rs | 2 ++ src/test/ui/missing-items/m2.stderr | 7 ++----- src/test/ui/resolve/issue-14254.rs | 2 ++ src/test/ui/resolve/issue-14254.stderr | 7 ++----- src/test/ui/resolve/issue-21221-2.rs | 2 ++ src/test/ui/resolve/issue-21221-2.stderr | 2 -- .../ui/resolve/suggest-path-instead-of-mod-dot-item.rs | 2 ++ .../ui/resolve/suggest-path-instead-of-mod-dot-item.stderr | 7 ++----- src/test/ui/span/issue-35987.rs | 2 ++ src/test/ui/span/issue-35987.stderr | 2 -- src/test/ui/token/issue-10636-2.rs | 2 ++ src/test/ui/token/issue-10636-2.stderr | 5 +---- src/test/ui/token/issue-41155.rs | 2 ++ src/test/ui/token/issue-41155.stderr | 7 ++----- 42 files changed, 75 insertions(+), 95 deletions(-) diff --git a/src/test/ui/error-codes/E0522.rs b/src/test/ui/error-codes/E0522.rs index 3d4377853464..c50cb759e05c 100644 --- a/src/test/ui/error-codes/E0522.rs +++ b/src/test/ui/error-codes/E0522.rs @@ -15,3 +15,5 @@ fn cookie() -> ! { //~^^ ERROR definition of an unknown language item: `cookie` [E0522] loop {} } + +fn main() {} diff --git a/src/test/ui/error-codes/E0522.stderr b/src/test/ui/error-codes/E0522.stderr index 31898312133e..9f3f8968d734 100644 --- a/src/test/ui/error-codes/E0522.stderr +++ b/src/test/ui/error-codes/E0522.stderr @@ -1,12 +1,9 @@ -error[E0601]: main function not found in crate E0522 - error[E0522]: definition of an unknown language item: `cookie` --> $DIR/E0522.rs:13:1 | LL | #[lang = "cookie"] | ^^^^^^^^^^^^^^^^^^ definition of unknown language item `cookie` -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0522, E0601. -For more information about an error, try `rustc --explain E0522`. +For more information about this error, try `rustc --explain E0522`. diff --git a/src/test/ui/feature-gate-i128_type2.rs b/src/test/ui/feature-gate-i128_type2.rs index d3bd810ceb2b..8a7d316ed838 100644 --- a/src/test/ui/feature-gate-i128_type2.rs +++ b/src/test/ui/feature-gate-i128_type2.rs @@ -30,3 +30,5 @@ fn test3_2() { enum A { //~ ERROR 128-bit type is unstable A(u64) } + +fn main() {} diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr index 89b17ddbf001..23d4d6c98d90 100644 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ b/src/test/ui/feature-gate-i128_type2.stderr @@ -30,8 +30,6 @@ LL | let x: u128 = 0; //~ ERROR 128-bit type is unstable | = help: add #![feature(i128_type)] to the crate attributes to enable -error[E0601]: main function not found in crate feature_gate_i128_type2 - error[E0658]: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:30:1 | @@ -42,7 +40,6 @@ LL | | } | = help: add #![feature(repr128)] to the crate attributes to enable -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors occurred: E0601, E0658. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs b/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs index 24e77bf60a8d..410f960e655f 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-inline.rs @@ -35,3 +35,5 @@ mod inline { #[inline = "2100"] impl S { } //~^ ERROR attribute should be applied to function } + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr index 68f3099ff7e1..d67d78e31a9d 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-inline.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found in crate issue_43106_gating_of_inline - error[E0518]: attribute should be applied to function --> $DIR/issue-43106-gating-of-inline.rs:21:1 | @@ -39,7 +37,6 @@ error[E0518]: attribute should be applied to function LL | #[inline = "2100"] impl S { } | ^^^^^^^^^^^^^^^^^^ ---------- not a function -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors -Some errors occurred: E0518, E0601. -For more information about an error, try `rustc --explain E0518`. +For more information about this error, try `rustc --explain E0518`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs index 3b2dbdefebad..ec3c97beab0f 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs @@ -13,5 +13,9 @@ // `#![macro_escape]` is incompatible with crate-level `#![macro_use]` // already present in issue-43106-gating-of-builtin-attrs. +// must-compile-successfully + #![macro_escape] //~^ WARN macro_escape is a deprecated synonym for macro_use + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index f8c1d9204af4..d19720397e66 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -1,13 +1,8 @@ warning: macro_escape is a deprecated synonym for macro_use - --> $DIR/issue-43106-gating-of-macro_escape.rs:16:1 + --> $DIR/issue-43106-gating-of-macro_escape.rs:18:1 | LL | #![macro_escape] | ^^^^^^^^^^^^^^^^ | = help: consider an outer attribute, #[macro_use] mod ... -error[E0601]: main function not found in crate issue_43106_gating_of_macro_escape - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs index 133f70e0f3b1..5bb8bb024ed5 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.rs @@ -40,3 +40,5 @@ mod proc_macro_derive2 { #[proc_macro_derive = "2500"] impl S { } //~^ ERROR the `#[proc_macro_derive]` attribute may only be used on bare functions } + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr index de4ef084e4f2..419efb6825a9 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-proc_macro_derive.stderr @@ -34,8 +34,5 @@ error: the `#[proc_macro_derive]` attribute may only be used on bare functions LL | #[proc_macro_derive = "2500"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0601]: main function not found in crate issue_43106_gating_of_proc_macro_derive +error: aborting due to 6 previous errors -error: aborting due to 7 previous errors - -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs index 10c139863492..0c6cfb5da565 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.rs @@ -36,3 +36,4 @@ mod rustc_deprecated { //~^ ERROR stability attributes may not be used outside of the standard library } +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr index af1e659d48c8..35c15cb6b1ea 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-rustc_deprecated.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found in crate issue_43106_gating_of_rustc_deprecated - error: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-rustc_deprecated.rs:17:1 | @@ -42,6 +40,5 @@ error: stability attributes may not be used outside of the standard library LL | #[rustc_deprecated = "1500"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs b/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs index a6eaabf7a383..6415243d0873 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-stable.rs @@ -35,3 +35,5 @@ mod stable { #[stable = "1300"] impl S { } //~^ ERROR stability attributes may not be used outside of the standard library } + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr index ebdaecc08782..21543d1b20af 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-stable.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found in crate issue_43106_gating_of_stable - error: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-stable.rs:17:1 | @@ -42,6 +40,5 @@ error: stability attributes may not be used outside of the standard library LL | #[stable = "1300"] impl S { } | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs index ff0600deb193..140474d82c88 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.rs @@ -35,3 +35,5 @@ mod unstable { #[unstable = "1200"] impl S { } //~^ ERROR stability attributes may not be used outside of the standard library } + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr index 3da5f0cec92b..6124e16f4180 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-unstable.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found in crate issue_43106_gating_of_unstable - error: stability attributes may not be used outside of the standard library --> $DIR/issue-43106-gating-of-unstable.rs:17:1 | @@ -42,6 +40,5 @@ error: stability attributes may not be used outside of the standard library LL | #[unstable = "1200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/generator/yield-in-const.rs b/src/test/ui/generator/yield-in-const.rs index e166d2651597..8636a66ae00a 100644 --- a/src/test/ui/generator/yield-in-const.rs +++ b/src/test/ui/generator/yield-in-const.rs @@ -12,3 +12,5 @@ const A: u8 = { yield 3u8; 3u8}; //~^ ERROR yield statement outside + +fn main() {} diff --git a/src/test/ui/generator/yield-in-const.stderr b/src/test/ui/generator/yield-in-const.stderr index f37a881a451f..874edce59316 100644 --- a/src/test/ui/generator/yield-in-const.stderr +++ b/src/test/ui/generator/yield-in-const.stderr @@ -1,12 +1,9 @@ -error[E0601]: main function not found in crate yield_in_const - error[E0627]: yield statement outside of generator literal --> $DIR/yield-in-const.rs:13:17 | LL | const A: u8 = { yield 3u8; 3u8}; | ^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0601, E0627. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0627`. diff --git a/src/test/ui/generator/yield-in-static.rs b/src/test/ui/generator/yield-in-static.rs index 823a2aa425e2..21601f47f677 100644 --- a/src/test/ui/generator/yield-in-static.rs +++ b/src/test/ui/generator/yield-in-static.rs @@ -12,3 +12,5 @@ static B: u8 = { yield 3u8; 3u8}; //~^ ERROR yield statement outside + +fn main() {} diff --git a/src/test/ui/generator/yield-in-static.stderr b/src/test/ui/generator/yield-in-static.stderr index 0ade7a20cac8..35d1ebaabdc1 100644 --- a/src/test/ui/generator/yield-in-static.stderr +++ b/src/test/ui/generator/yield-in-static.stderr @@ -1,12 +1,9 @@ -error[E0601]: main function not found in crate yield_in_static - error[E0627]: yield statement outside of generator literal --> $DIR/yield-in-static.rs:13:18 | LL | static B: u8 = { yield 3u8; 3u8}; | ^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0601, E0627. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0627`. diff --git a/src/test/ui/imports/macro-paths.rs b/src/test/ui/imports/macro-paths.rs index 88a6e1c0d92e..e709eeee14a8 100644 --- a/src/test/ui/imports/macro-paths.rs +++ b/src/test/ui/imports/macro-paths.rs @@ -36,3 +36,5 @@ fn g() { mod baz { pub use two_macros::m; } } } + +fn main() {} diff --git a/src/test/ui/imports/macro-paths.stderr b/src/test/ui/imports/macro-paths.stderr index bf33bfaaf1fa..799e7f972464 100644 --- a/src/test/ui/imports/macro-paths.stderr +++ b/src/test/ui/imports/macro-paths.stderr @@ -36,9 +36,6 @@ LL | | } | |_^ = note: macro-expanded items do not shadow when used in a macro invocation path -error[E0601]: main function not found in crate macro_paths +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors occurred: E0601, E0659. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/imports/macros.rs b/src/test/ui/imports/macros.rs index 98577d73ee0f..5d6a11913849 100644 --- a/src/test/ui/imports/macros.rs +++ b/src/test/ui/imports/macros.rs @@ -49,3 +49,5 @@ mod m4 { use two_macros::m; m!(); //~ ERROR ambiguous } + +fn main() {} diff --git a/src/test/ui/imports/macros.stderr b/src/test/ui/imports/macros.stderr index c7a89df2a97a..f91987cd9f34 100644 --- a/src/test/ui/imports/macros.stderr +++ b/src/test/ui/imports/macros.stderr @@ -51,9 +51,6 @@ LL | use two_macros::m; | ^^^^^^^^^^^^^ = note: macro-expanded macro imports do not shadow -error[E0601]: main function not found in crate macros +error: aborting due to 3 previous errors -error: aborting due to 4 previous errors - -Some errors occurred: E0601, E0659. -For more information about an error, try `rustc --explain E0601`. +For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs index f845762cefd8..ff04cfe99c0b 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs @@ -20,3 +20,5 @@ impl Deref for Struct { } } //~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter + +fn main() {} diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr index 816a27086cce..37b586e1e3bd 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found in crate mismatched_trait_impl_2 - error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements --> $DIR/mismatched_trait_impl-2.rs:18:5 | @@ -18,7 +16,6 @@ LL | | } expected fn(&Struct) -> &Trait + 'static found fn(&Struct) -> &Trait -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0495, E0601. -For more information about an error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/issue-47706-trait.rs b/src/test/ui/issue-47706-trait.rs index 86a9da49a054..4ce653547da0 100644 --- a/src/test/ui/issue-47706-trait.rs +++ b/src/test/ui/issue-47706-trait.rs @@ -14,3 +14,5 @@ trait T { } //~^^ ERROR function is expected to take a single 0-tuple as argument } + +fn main() {} diff --git a/src/test/ui/issue-47706-trait.stderr b/src/test/ui/issue-47706-trait.stderr index 069ae9994a1a..717b3eb0b562 100644 --- a/src/test/ui/issue-47706-trait.stderr +++ b/src/test/ui/issue-47706-trait.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found in crate issue_47706_trait - error[E0593]: function is expected to take a single 0-tuple as argument, but it takes 2 distinct arguments --> $DIR/issue-47706-trait.rs:13:20 | @@ -8,7 +6,6 @@ LL | fn f(&self, _: ()) { LL | None::<()>.map(Self::f); | ^^^ expected function that takes a single 0-tuple as argument -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0593, E0601. -For more information about an error, try `rustc --explain E0593`. +For more information about this error, try `rustc --explain E0593`. diff --git a/src/test/ui/missing-items/m2.rs b/src/test/ui/missing-items/m2.rs index 9f1954526916..f655047f6f5a 100644 --- a/src/test/ui/missing-items/m2.rs +++ b/src/test/ui/missing-items/m2.rs @@ -18,3 +18,5 @@ struct X { impl m1::X for X { //~ ERROR not all trait items implemented } + +fn main() {} diff --git a/src/test/ui/missing-items/m2.stderr b/src/test/ui/missing-items/m2.stderr index 3b611518283b..3f7a4039eb76 100644 --- a/src/test/ui/missing-items/m2.stderr +++ b/src/test/ui/missing-items/m2.stderr @@ -1,5 +1,3 @@ -error[E0601]: main function not found in crate m2 - error[E0046]: not all trait items implemented, missing: `CONSTANT`, `Type`, `method` --> $DIR/m2.rs:19:1 | @@ -10,7 +8,6 @@ LL | impl m1::X for X { //~ ERROR not all trait items implemented = note: `Type` from trait: `type Type;` = note: `method` from trait: `fn(&Self, std::string::String) -> ::Type` -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0046, E0601. -For more information about an error, try `rustc --explain E0046`. +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/resolve/issue-14254.rs b/src/test/ui/resolve/issue-14254.rs index 896085329ab9..eab500de2556 100644 --- a/src/test/ui/resolve/issue-14254.rs +++ b/src/test/ui/resolve/issue-14254.rs @@ -111,3 +111,5 @@ impl Foo for Box { //~^ ERROR cannot find value `bah` } } + +fn main() {} diff --git a/src/test/ui/resolve/issue-14254.stderr b/src/test/ui/resolve/issue-14254.stderr index 395ca412f351..055cbb2d5791 100644 --- a/src/test/ui/resolve/issue-14254.stderr +++ b/src/test/ui/resolve/issue-14254.stderr @@ -142,9 +142,6 @@ error[E0425]: cannot find value `bah` in this scope LL | bah; | ^^^ help: try: `Self::bah` -error[E0601]: main function not found in crate issue_14254 +error: aborting due to 24 previous errors -error: aborting due to 25 previous errors - -Some errors occurred: E0425, E0601. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/resolve/issue-21221-2.rs b/src/test/ui/resolve/issue-21221-2.rs index 4ddb4d669fcd..361e8caf7442 100644 --- a/src/test/ui/resolve/issue-21221-2.rs +++ b/src/test/ui/resolve/issue-21221-2.rs @@ -27,3 +27,5 @@ pub mod baz { struct Foo; impl T for Foo { } //~^ ERROR cannot find trait `T` + +fn main() {} diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index fdafb509268a..c61ffe3b33e8 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -8,7 +8,5 @@ help: possible candidate is found in another module, you can import it into scop LL | use foo::bar::T; | -error[E0601]: main function not found in crate issue_21221_2 - error: cannot continue compilation due to previous error diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs index 981a853a0405..d24fced5d313 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.rs @@ -65,3 +65,5 @@ fn h8() -> i32 { a::b() //~^ ERROR expected function, found module `a::b` } + +fn main() {} diff --git a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr index e1a205e7b3eb..9216c0b32192 100644 --- a/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr +++ b/src/test/ui/resolve/suggest-path-instead-of-mod-dot-item.stderr @@ -72,9 +72,6 @@ LL | a::b() | | | did you mean `I`? -error[E0601]: main function not found in crate suggest_path_instead_of_mod_dot_item +error: aborting due to 9 previous errors -error: aborting due to 10 previous errors - -Some errors occurred: E0423, E0601. -For more information about an error, try `rustc --explain E0423`. +For more information about this error, try `rustc --explain E0423`. diff --git a/src/test/ui/span/issue-35987.rs b/src/test/ui/span/issue-35987.rs index fa0410686c26..19e05f33825f 100644 --- a/src/test/ui/span/issue-35987.rs +++ b/src/test/ui/span/issue-35987.rs @@ -20,3 +20,5 @@ impl Add for Foo { unimplemented!(); } } + +fn main() {} diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 09d34f3d1afd..2d4a7cc72f5f 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -8,7 +8,5 @@ help: possible better candidate is found in another module, you can import it in LL | use std::ops::Add; | -error[E0601]: main function not found in crate issue_35987 - error: cannot continue compilation due to previous error diff --git a/src/test/ui/token/issue-10636-2.rs b/src/test/ui/token/issue-10636-2.rs index 4aa412701937..711803754408 100644 --- a/src/test/ui/token/issue-10636-2.rs +++ b/src/test/ui/token/issue-10636-2.rs @@ -17,3 +17,5 @@ pub fn trace_option(option: Option) { } //~ ERROR: incorrect close delimiter //~^ ERROR: expected expression, found `)` + +fn main() {} diff --git a/src/test/ui/token/issue-10636-2.stderr b/src/test/ui/token/issue-10636-2.stderr index 273cabb0474e..56a30423171d 100644 --- a/src/test/ui/token/issue-10636-2.stderr +++ b/src/test/ui/token/issue-10636-2.stderr @@ -22,8 +22,5 @@ error: expected expression, found `)` LL | } //~ ERROR: incorrect close delimiter | ^ expected expression -error[E0601]: main function not found in crate issue_10636_2 +error: aborting due to 3 previous errors -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/token/issue-41155.rs b/src/test/ui/token/issue-41155.rs index 550a90fc6af2..7bd8506af90b 100644 --- a/src/test/ui/token/issue-41155.rs +++ b/src/test/ui/token/issue-41155.rs @@ -11,3 +11,5 @@ impl S { //~ ERROR cannot find type pub } //~ ERROR expected one of + +fn main() {} diff --git a/src/test/ui/token/issue-41155.stderr b/src/test/ui/token/issue-41155.stderr index 80a4d43116f5..b56b95a8aafd 100644 --- a/src/test/ui/token/issue-41155.stderr +++ b/src/test/ui/token/issue-41155.stderr @@ -12,9 +12,6 @@ error[E0412]: cannot find type `S` in this scope LL | impl S { //~ ERROR cannot find type | ^ not found in this scope -error[E0601]: main function not found in crate issue_41155 +error: aborting due to 2 previous errors -error: aborting due to 3 previous errors - -Some errors occurred: E0412, E0601. -For more information about an error, try `rustc --explain E0412`. +For more information about this error, try `rustc --explain E0412`. From b08e6d305f8366c8fa7e08d829bb0c6939124759 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 12 Mar 2018 13:23:12 -0700 Subject: [PATCH 207/830] Add suggestion where to add main function. --- src/librustc/middle/entry.rs | 3 +++ src/test/ui/error-codes/E0601.rs | 11 +++++++++++ src/test/ui/error-codes/E0601.stderr | 7 +++++++ .../feature-gate/issue-43106-gating-of-bench.stderr | 2 ++ .../ui/feature-gate/issue-43106-gating-of-test.stderr | 2 ++ 5 files changed, 25 insertions(+) create mode 100644 src/test/ui/error-codes/E0601.rs create mode 100644 src/test/ui/error-codes/E0601.stderr diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 3473923c411f..8193aad76273 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -178,6 +178,9 @@ fn configure_main(this: &mut EntryContext, crate_name: &str) { err.emit(); this.session.abort_if_errors(); } else { + if let Some(ref filename) = this.session.local_crate_source_file { + err.note(&format!("consider adding a main function to {}", filename.display())); + } if this.session.teach(&err.get_code().unwrap()) { err.note("If you don't know the basics of Rust, you can go look to the Rust Book \ to get started: https://doc.rust-lang.org/book/"); diff --git a/src/test/ui/error-codes/E0601.rs b/src/test/ui/error-codes/E0601.rs new file mode 100644 index 000000000000..37b3f523475f --- /dev/null +++ b/src/test/ui/error-codes/E0601.rs @@ -0,0 +1,11 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test for main function not found. diff --git a/src/test/ui/error-codes/E0601.stderr b/src/test/ui/error-codes/E0601.stderr new file mode 100644 index 000000000000..eff0a3299020 --- /dev/null +++ b/src/test/ui/error-codes/E0601.stderr @@ -0,0 +1,7 @@ +error[E0601]: main function not found in crate E0601 + | + = note: consider adding a main function to $DIR/E0601.rs + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0601" diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr index 27bf9c99652b..32ee8026197b 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr @@ -1,4 +1,6 @@ error[E0601]: main function not found in crate issue_43106_gating_of_bench + | + = note: consider adding a main function to $DIR/issue-43106-gating-of-bench.rs error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr index 0d35be76d924..b86dd834d9a0 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr @@ -1,4 +1,6 @@ error[E0601]: main function not found in crate issue_43106_gating_of_test + | + = note: consider adding a main function to $DIR/issue-43106-gating-of-test.rs error: aborting due to previous error From 2f1b34cc15d9ce8daecfb7855957a36e6e10f2e5 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 13 Mar 2018 11:22:43 -0700 Subject: [PATCH 208/830] Add backticks to `main` not found errors. --- src/librustc/middle/entry.rs | 4 ++-- src/test/compile-fail/cfg-attr-cfg-2.rs | 2 +- src/test/compile-fail/cfg-in-crate-1.rs | 2 +- src/test/compile-fail/elided-test.rs | 2 +- src/test/compile-fail/missing-main.rs | 2 +- src/test/ui/error-codes/E0601.stderr | 4 ++-- src/test/ui/feature-gate/issue-43106-gating-of-bench.rs | 2 +- src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr | 4 ++-- src/test/ui/feature-gate/issue-43106-gating-of-test.rs | 2 +- src/test/ui/feature-gate/issue-43106-gating-of-test.stderr | 4 ++-- src/test/ui/main-wrong-location.stderr | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 8193aad76273..37d79f408f3f 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -165,7 +165,7 @@ fn configure_main(this: &mut EntryContext, crate_name: &str) { } else { // No main function let mut err = struct_err!(this.session, E0601, - "main function not found in crate {}", crate_name); + "`main` function not found in crate `{}`", crate_name); if !this.non_main_fns.is_empty() { // There were some functions named 'main' though. Try to give the user a hint. err.note("the main function must be defined at the crate level \ @@ -179,7 +179,7 @@ fn configure_main(this: &mut EntryContext, crate_name: &str) { this.session.abort_if_errors(); } else { if let Some(ref filename) = this.session.local_crate_source_file { - err.note(&format!("consider adding a main function to {}", filename.display())); + err.note(&format!("consider adding a `main` function to `{}`", filename.display())); } if this.session.teach(&err.get_code().unwrap()) { err.note("If you don't know the basics of Rust, you can go look to the Rust Book \ diff --git a/src/test/compile-fail/cfg-attr-cfg-2.rs b/src/test/compile-fail/cfg-attr-cfg-2.rs index b71a3be5dcea..58a62d45ea5d 100644 --- a/src/test/compile-fail/cfg-attr-cfg-2.rs +++ b/src/test/compile-fail/cfg-attr-cfg-2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. // -// error-pattern: main function not found +// error-pattern: `main` function not found // compile-flags: --cfg foo // main is conditionally compiled, but the conditional compilation diff --git a/src/test/compile-fail/cfg-in-crate-1.rs b/src/test/compile-fail/cfg-in-crate-1.rs index 94ae8d89b4fc..bbccf2bcd0f8 100644 --- a/src/test/compile-fail/cfg-in-crate-1.rs +++ b/src/test/compile-fail/cfg-in-crate-1.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:main function not found +// error-pattern: `main` function not found #![cfg(bar)] diff --git a/src/test/compile-fail/elided-test.rs b/src/test/compile-fail/elided-test.rs index b62214b12f9a..0cdd0010a745 100644 --- a/src/test/compile-fail/elided-test.rs +++ b/src/test/compile-fail/elided-test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: main function not found +// error-pattern: `main` function not found // Since we're not compiling a test runner this function should be elided // and the build will fail because main doesn't exist diff --git a/src/test/compile-fail/missing-main.rs b/src/test/compile-fail/missing-main.rs index 4bfdaf69480e..2788a5c2d585 100644 --- a/src/test/compile-fail/missing-main.rs +++ b/src/test/compile-fail/missing-main.rs @@ -8,5 +8,5 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:main function not found +// error-pattern: `main` function not found fn mian() { } diff --git a/src/test/ui/error-codes/E0601.stderr b/src/test/ui/error-codes/E0601.stderr index eff0a3299020..6fe05d2dc8e0 100644 --- a/src/test/ui/error-codes/E0601.stderr +++ b/src/test/ui/error-codes/E0601.stderr @@ -1,6 +1,6 @@ -error[E0601]: main function not found in crate E0601 +error[E0601]: `main` function not found in crate `E0601` | - = note: consider adding a main function to $DIR/E0601.rs + = note: consider adding a `main` function to `$DIR/E0601.rs` error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs b/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs index a34f98f03559..6c2267993387 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: main function not found +// error-pattern: `main` function not found // At time of authorship, a crate-level #![bench] with no `--test` // will cause compilation to error unconditionally with "main function diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr index 32ee8026197b..503ef020d960 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-bench.stderr @@ -1,6 +1,6 @@ -error[E0601]: main function not found in crate issue_43106_gating_of_bench +error[E0601]: `main` function not found in crate `issue_43106_gating_of_bench` | - = note: consider adding a main function to $DIR/issue-43106-gating-of-bench.rs + = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-bench.rs` error: aborting due to previous error diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.rs b/src/test/ui/feature-gate/issue-43106-gating-of-test.rs index adcbfe77280b..06632396249a 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: main function not found +// error-pattern: `main` function not found // At time of authorship, crate-level #[test] attribute with no // `--test` signals unconditional error complaining of missing main diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr index b86dd834d9a0..2ab35be43c57 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-test.stderr @@ -1,6 +1,6 @@ -error[E0601]: main function not found in crate issue_43106_gating_of_test +error[E0601]: `main` function not found in crate `issue_43106_gating_of_test` | - = note: consider adding a main function to $DIR/issue-43106-gating-of-test.rs + = note: consider adding a `main` function to `$DIR/issue-43106-gating-of-test.rs` error: aborting due to previous error diff --git a/src/test/ui/main-wrong-location.stderr b/src/test/ui/main-wrong-location.stderr index c5affade5e21..a5ef92f14bbc 100644 --- a/src/test/ui/main-wrong-location.stderr +++ b/src/test/ui/main-wrong-location.stderr @@ -1,4 +1,4 @@ -error[E0601]: main function not found in crate main_wrong_location +error[E0601]: `main` function not found in crate `main_wrong_location` | = note: the main function must be defined at the crate level but you have one or more functions named 'main' that are not defined at the crate level. Either move the definition or attach the `#[main]` attribute to override this behavior. note: here is a function named 'main' From 16d424f1471988ed4f7601b8eca42c72a23ca38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Mar 2018 22:58:45 -0700 Subject: [PATCH 209/830] Some tweaks to "type parameters from outer function" diagnostic Follow up to #47574. --- src/librustc_resolve/lib.rs | 30 +++++++++++++++++----------- src/libsyntax/codemap.rs | 22 +++++++++++++------- src/test/ui/error-codes/E0401.rs | 4 ++-- src/test/ui/error-codes/E0401.stderr | 13 ++++++------ 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a6b776125ae9..c84caee13e82 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -41,7 +41,7 @@ use rustc::ty; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; -use syntax::codemap::{dummy_spanned, respan, CodeMap}; +use syntax::codemap::{dummy_spanned, respan, BytePos, CodeMap}; use syntax::ext::hygiene::{Mark, MarkKind, SyntaxContext}; use syntax::ast::{self, Name, NodeId, Ident, SpannedIdent, FloatTy, IntTy, UintTy}; use syntax::ext::base::SyntaxExtension; @@ -179,11 +179,12 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, E0401, "can't use type parameters from outer function"); err.span_label(span, "use of type variable from outer function"); + + let cm = resolver.session.codemap(); match outer_def { Def::SelfTy(_, maybe_impl_defid) => { if let Some(impl_span) = maybe_impl_defid.map_or(None, |def_id| resolver.definitions.opt_span(def_id)) { - let cm = resolver.session.codemap(); err.span_label(reduce_impl_span_to_impl_keyword(cm, impl_span), "`Self` type implicitely declared here, on the `impl`"); } @@ -206,12 +207,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver, // Try to retrieve the span of the function signature and generate a new message with // a local type parameter let sugg_msg = "try using a local type parameter instead"; - if let Some((sugg_span, new_snippet)) = generate_local_type_param_snippet( - resolver.session.codemap(), span) { + if let Some((sugg_span, new_snippet)) = generate_local_type_param_snippet(cm, span) { // Suggest the modification to the user err.span_suggestion(sugg_span, sugg_msg, new_snippet); + } else if let Some(sp) = generate_fn_name_span(cm, span) { + err.span_label(sp, "try adding a local type parameter in this method instead"); } else { err.help("try using a local type parameter instead"); } @@ -407,6 +409,15 @@ fn reduce_impl_span_to_impl_keyword(cm: &CodeMap, impl_span: Span) -> Span { impl_span } +fn generate_fn_name_span(cm: &CodeMap, span: Span) -> Option { + let prev_span = cm.span_extend_to_prev_str(span, "fn", true); + cm.span_to_snippet(prev_span).map(|snippet| { + let len = snippet.find(|c: char| !c.is_alphanumeric() && c != '_') + .expect("no label after fn"); + prev_span.with_hi(BytePos(prev_span.lo().0 + len as u32)) + }).ok() +} + /// Take the span of a type parameter in a function signature and try to generate a span for the /// function name (with generics) and a new snippet for this span with the pointed type parameter as /// a new local type parameter. @@ -428,17 +439,12 @@ fn reduce_impl_span_to_impl_keyword(cm: &CodeMap, impl_span: Span) -> Span { fn generate_local_type_param_snippet(cm: &CodeMap, span: Span) -> Option<(Span, String)> { // Try to extend the span to the previous "fn" keyword to retrieve the function // signature - let sugg_span = cm.span_extend_to_prev_str(span, "fn"); + let sugg_span = cm.span_extend_to_prev_str(span, "fn", false); if sugg_span != span { if let Ok(snippet) = cm.span_to_snippet(sugg_span) { - use syntax::codemap::BytePos; - // Consume the function name - let mut offset = 0; - for c in snippet.chars().take_while(|c| c.is_ascii_alphanumeric() || - *c == '_') { - offset += c.len_utf8(); - } + let mut offset = snippet.find(|c: char| !c.is_alphanumeric() && c != '_') + .expect("no label after fn"); // Consume the generics part of the function signature let mut bracket_counter = 0; diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index c340f1b8c8ab..951f8a871ca6 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -622,13 +622,21 @@ impl CodeMap { sp } - /// Extend the given `Span` to just after the previous occurrence of `pat`. Return the same span - /// if no character could be found or if an error occurred while retrieving the code snippet. - pub fn span_extend_to_prev_str(&self, sp: Span, pat: &str) -> Span { - if let Ok(prev_source) = self.span_to_prev_source(sp) { - let prev_source = prev_source.rsplit(pat).nth(0).unwrap_or("").trim_left(); - if !prev_source.is_empty() && !prev_source.contains('\n') { - return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32)); + /// Extend the given `Span` to just after the previous occurrence of `pat` when surrounded by + /// whitespace. Return the same span if no character could be found or if an error occurred + /// while retrieving the code snippet. + pub fn span_extend_to_prev_str(&self, sp: Span, pat: &str, accept_newlines: bool) -> Span { + // assure that the pattern is delimited, to avoid the following + // fn my_fn() + // ^^^^ returned span without the check + // ---------- correct span + for ws in &[" ", "\t", "\n"] { + let pat = pat.to_owned() + ws; + if let Ok(prev_source) = self.span_to_prev_source(sp) { + let prev_source = prev_source.rsplit(&pat).nth(0).unwrap_or("").trim_left(); + if !prev_source.is_empty() && (!prev_source.contains('\n') || accept_newlines) { + return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32)); + } } } diff --git a/src/test/ui/error-codes/E0401.rs b/src/test/ui/error-codes/E0401.rs index 15b946625778..4fc74f5ef221 100644 --- a/src/test/ui/error-codes/E0401.rs +++ b/src/test/ui/error-codes/E0401.rs @@ -11,14 +11,14 @@ trait Baz {} fn foo(x: T) { - fn bar, W: Fn()>(y: T) { //~ ERROR E0401 + fn bfnr, W: Fn()>(y: T) { //~ ERROR E0401 } fn baz, W: Fn()> (y: T) { //~ ERROR E0401 } - bar(x); + bfnr(x); } diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr index c306ff4a04f6..e5a2be4dfb02 100644 --- a/src/test/ui/error-codes/E0401.stderr +++ b/src/test/ui/error-codes/E0401.stderr @@ -1,12 +1,12 @@ error[E0401]: can't use type parameters from outer function - --> $DIR/E0401.rs:14:38 + --> $DIR/E0401.rs:14:39 | LL | fn foo(x: T) { | - type variable from outer function -LL | fn bar, W: Fn()>(y: T) { //~ ERROR E0401 - | -------------------------- ^ use of type variable from outer function +LL | fn bfnr, W: Fn()>(y: T) { //~ ERROR E0401 + | --------------------------- ^ use of type variable from outer function | | - | help: try using a local type parameter instead: `bar, W: Fn(), T>` + | help: try using a local type parameter instead: `bfnr, W: Fn(), T>` error[E0401]: can't use type parameters from outer function --> $DIR/E0401.rs:19:16 @@ -14,10 +14,11 @@ error[E0401]: can't use type parameters from outer function LL | fn foo(x: T) { | - type variable from outer function ... +LL | fn baz $DIR/E0401.rs:32:25 From 525727529492f30ef9d68467d5b8a7f18f65d743 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 14 Mar 2018 13:04:24 -0700 Subject: [PATCH 210/830] Update E0601 test for new message format. --- src/test/ui/error-codes/E0601.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/error-codes/E0601.stderr b/src/test/ui/error-codes/E0601.stderr index 6fe05d2dc8e0..cbc20db35da7 100644 --- a/src/test/ui/error-codes/E0601.stderr +++ b/src/test/ui/error-codes/E0601.stderr @@ -4,4 +4,4 @@ error[E0601]: `main` function not found in crate `E0601` error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0601" +For more information about this error, try `rustc --explain E0601`. From 0f96e145fbe8c635e7a58fb17c8c46bc4e42d454 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 15:32:25 -0500 Subject: [PATCH 211/830] talk about doc(cfg) --- src/doc/rustdoc/src/unstable-features.md | 52 ++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 08cceff0e701..245d53e8b796 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -76,3 +76,55 @@ For more details, check out [the RFC][RFC 1946], and see [the tracking issue][43 information about what parts of the feature are available. [43466]: https://github.com/rust-lang/rust/issues/43466 + +## Documenting platform-/feature-specific information + +Because of the way Rustdoc documents a crate, the documentation it creates is specific to the target +rustc compiles for. Anything that's specific to any other target is dropped via `#[cfg]` attribute +processing early in the compilation process. However, Rustdoc has a trick up its sleeve to handle +platform-specific code if it *does* receive it. + +Because Rustdoc doesn't need to fully compile a crate to binary, it replaces function bodies with +`loop {}` to prevent having to process more than necessary. This means that any code within a +function that requires platform-specific pieces is ignored. Combined with a special attribute, +`#[doc(cfg(...))]`, you can tell Rustdoc exactly which platform something is supposed to run on, +ensuring that doctests are only run on the appropriate platforms. + +The `#[doc(cfg(...))]` attribute has another effect: When Rustdoc renders documentation for that +item, it will be accompanied by a banner explaining that the item is only available on certain +platforms. + +As mentioned earlier, getting the items to Rustdoc requires some extra preparation. The standard +library adds a `--cfg dox` flag to every Rustdoc command, but the same thing can be accomplished by +adding a feature to your Cargo.toml and adding `--feature dox` (or whatever you choose to name the +feature) to your `cargo doc` calls. + +Either way, once you create an environment for the documentation, you can start to augment your +`#[cfg]` attributes to allow both the target platform *and* the documentation configuration to leave +the item in. For example, `#[cfg(any(windows, feature = "dox"))]` will preserve the item either on +Windows or during the documentation process. Then, adding a new attribute `#[doc(cfg(windows))]` +will tell Rustdoc that the item is supposed to be used on Windows. For example: + +```rust +#![feature(doc_cfg)] + +/// Token struct that can only be used on Windows. +#[cfg(any(windows, feature = "dox"))] +#[doc(cfg(windows))] +pub struct WindowsToken; + +/// Token struct that can only be used on Unix. +#[cfg(any(unix, feature = "dox"))] +#[doc(cfg(unix))] +pub struct UnixToken; +``` + +In this sample, the tokens will only appear on their respective platforms, but they will both appear +in documentation. + +`#[doc(cfg(...))]` was introduced to be used by the standard library and is currently controlled by +a feature gate. For more information, see [its chapter in the Unstable Book][unstable-doc-cfg] and +[its tracking issue][issue-doc-cfg]. + +[unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html +[issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 From 23a1da4d637648ae37090f88be695de3a63cd507 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 16:06:53 -0500 Subject: [PATCH 212/830] talk about doc(spotlight) --- src/doc/rustdoc/src/unstable-features.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 245d53e8b796..167022395244 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -128,3 +128,23 @@ a feature gate. For more information, see [its chapter in the Unstable Book][uns [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 + +## Adding your trait to the "Important Traits" dialog + +Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when +implemented on it. These traits are intended to be the primary interface for their types, and are +often the only thing available to be documented on their types. For this reason, Rustdoc will track +when a given type implements one of these traits and call special attention to it when a function +returns one of these types. This is the "Important Traits" dialog, visible as a circle-i button next +to the function, which, when clicked, shows the dialog. + +In the standard library, the traits that qualify for inclusion are `Iterator`, `io::Read`, and +`io::Write`. However, rather than being implemented as a hard-coded list, these traits have a +special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this +attribute to your own trait to include it in the "Important Traits" dialog in documentation. + +The `#[doc(spotlight)]` attribute is controlled by a feature gate. For more information, see [its +chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue-spotlight]. + +[unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html +[issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 From c990fa0d880586d85e191b0691a415f9180f4e61 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 14 Mar 2018 22:12:38 +0100 Subject: [PATCH 213/830] add dummy symbols for LLVM<6 --- src/rustllvm/RustWrapper.cpp | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 9d5f9042f187..c647218c1aca 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1442,4 +1442,51 @@ extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Src), NoNaN)); } + +#else + +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef Src) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} +extern "C" LLVMValueRef +LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + return Src; +} #endif From 82bd146d60425c3cd0c99892742f1454f5eb8191 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 16:40:28 -0500 Subject: [PATCH 214/830] talk about doc(masked) --- src/doc/rustdoc/src/unstable-features.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 167022395244..9f0476d4eef7 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -148,3 +148,23 @@ chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue [unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html [issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 + +## Exclude certain dependencies from documentation + +The standard library uses several dependencies which, in turn, use several types and traits from the +standard library. In addition, there are several compiler-internal crates that are not considered to +be part of the official standard library, and thus would be a distraction to include in +documentation. It's not enough to exclude their crate documentation, since information about trait +implementations appears on the pages for both the type and the trait, which can be in different +crates! + +To prevent internal types from being included in documentation, the standard library adds an +attribute to their `extern crate` declarations: `#[doc(masked)]`. This causes Rustdoc to "mask out" +types from these crates when building lists of trait implementations. + +The `#[doc(masked)]` attribute is intended to be used internally, and is governed by a feature gate. +For more information, see [its chapter in the Unstable Book][unstable-masked] and [its tracking +issue][issue-masked]. + +[unstable-masked]: ../unstable-book/language-features/doc-masked.html +[issue-masked]: https://github.com/rust-lang/rust/issues/44027 From 067553d5a1d867c7f8404153ce37a4008489b82a Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 17:13:52 -0500 Subject: [PATCH 215/830] talk about doc(include) --- src/doc/rustdoc/src/unstable-features.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 9f0476d4eef7..62112fbf293c 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -162,9 +162,25 @@ To prevent internal types from being included in documentation, the standard lib attribute to their `extern crate` declarations: `#[doc(masked)]`. This causes Rustdoc to "mask out" types from these crates when building lists of trait implementations. -The `#[doc(masked)]` attribute is intended to be used internally, and is governed by a feature gate. -For more information, see [its chapter in the Unstable Book][unstable-masked] and [its tracking -issue][issue-masked]. +The `#[doc(masked)]` attribute is intended to be used internally, and is controlled by a feature +gate. For more information, see [its chapter in the Unstable Book][unstable-masked] and [its +tracking issue][issue-masked]. [unstable-masked]: ../unstable-book/language-features/doc-masked.html [issue-masked]: https://github.com/rust-lang/rust/issues/44027 + +## Include external files as API documentation + +As designed in [RFC 1990], Rustdoc can read an external file to use as a type's documentation. This +is useful if certain documentation is so long that it would break the flow of reading the source. +Instead of writing it all inline, writing `#[doc(include = "sometype.md")]` (where `sometype.md` is +a file adjacent to the `lib.rs` for the crate) will ask Rustdoc to instead read that file and use it +as if it were written inline. + +[RFC 1990]: https://github.com/rust-lang/rfcs/pull/1990 + +`#[doc(include = "...")]` is currently controlled by a feature gate. For more information, see [its +chapter in the Unstable Book][unstable-include] and [its tracking issue][issue-include]. + +[unstable-include]: ../unstable-book/language-features/external-doc.html +[issue-include]: https://github.com/rust-lang/rust/issues/44732 From 3d90b4d73880f7f7146a31544ac414e85014ca6f Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 14 Mar 2018 17:22:15 -0500 Subject: [PATCH 216/830] add headings to categorize the features --- src/doc/rustdoc/src/unstable-features.md | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 62112fbf293c..5f9978c61b6e 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -9,7 +9,14 @@ there as necessary. [Unstable Book]: ../unstable-book/ -## Error numbers for `compile-fail` doctests +## Nightly-gated functionality + +These features just require a nightly build to operate. Unlike the other features on this page, +these don't need to be "turned on" with a command-line flag or a `#![feature(...)]` attribute in +your crate. This can give them some subtle fallback modes when used on a stable release, so be +careful! + +### Error numbers for `compile-fail` doctests As detailed in [the chapter on documentation tests][doctest-attributes], you can add a `compile_fail` attribute to a doctest to state that the test should fail to compile. However, on @@ -32,7 +39,7 @@ future. Attempting to use these error numbers on stable will result in the code sample being interpreted as plain text. -## Linking to items by type +### Linking to items by type As designed in [RFC 1946], Rustdoc can parse paths to items when you use them as links. To resolve these type names, it uses the items currently in-scope, either by declaration or by `use` statement. @@ -77,7 +84,12 @@ information about what parts of the feature are available. [43466]: https://github.com/rust-lang/rust/issues/43466 -## Documenting platform-/feature-specific information +## Extensions to the `#[doc]` attribute + +These features operate by extending the `#[doc]` attribute, and thus can be caught by the compiler +and enabled with a `#![feature(...)]` attribute in your crate. + +### Documenting platform-/feature-specific information Because of the way Rustdoc documents a crate, the documentation it creates is specific to the target rustc compiles for. Anything that's specific to any other target is dropped via `#[cfg]` attribute @@ -129,7 +141,7 @@ a feature gate. For more information, see [its chapter in the Unstable Book][uns [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 -## Adding your trait to the "Important Traits" dialog +### Adding your trait to the "Important Traits" dialog Rustdoc keeps a list of a few traits that are believed to be "fundamental" to a given type when implemented on it. These traits are intended to be the primary interface for their types, and are @@ -149,7 +161,7 @@ chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue [unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html [issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 -## Exclude certain dependencies from documentation +### Exclude certain dependencies from documentation The standard library uses several dependencies which, in turn, use several types and traits from the standard library. In addition, there are several compiler-internal crates that are not considered to @@ -169,7 +181,7 @@ tracking issue][issue-masked]. [unstable-masked]: ../unstable-book/language-features/doc-masked.html [issue-masked]: https://github.com/rust-lang/rust/issues/44027 -## Include external files as API documentation +### Include external files as API documentation As designed in [RFC 1990], Rustdoc can read an external file to use as a type's documentation. This is useful if certain documentation is so long that it would break the flow of reading the source. From 918ef671b04398560d8860363736ba120825e6fe Mon Sep 17 00:00:00 2001 From: boats Date: Wed, 14 Mar 2018 15:57:25 -0700 Subject: [PATCH 217/830] Pin and Unpin in libcore. --- src/libcore/marker.rs | 10 ++++ src/libcore/mem.rs | 111 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 98e0f71eb935..7b67404db5d9 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -565,3 +565,13 @@ unsafe impl Freeze for *const T {} unsafe impl Freeze for *mut T {} unsafe impl<'a, T: ?Sized> Freeze for &'a T {} unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {} + +/// Types which can be moved out of a `Pin`. +/// +/// The `Unpin` trait is used to control the behavior of the [`Pin`] type. If a +/// type implements `Unpin`, it is safe to move a value of that type out of the +/// `Pin` pointer. +/// +/// This trait is automatically implemented for almost every type. +#[unstable(feature = "pin", issue = "0")] +pub unsafe auto trait Unpin {} diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 21a0beccbf64..792d71732e66 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -20,9 +20,9 @@ use cmp; use fmt; use hash; use intrinsics; -use marker::{Copy, PhantomData, Sized}; +use marker::{Copy, PhantomData, Sized, Unpin, Unsize}; use ptr; -use ops::{Deref, DerefMut}; +use ops::{Deref, DerefMut, CoerceUnsized}; #[stable(feature = "rust1", since = "1.0.0")] pub use intrinsics::transmute; @@ -1105,3 +1105,110 @@ impl ::hash::Hash for ManuallyDrop { pub unsafe fn unreachable() -> ! { intrinsics::unreachable() } + +/// A pinned reference. +/// +/// A pinned reference is a lot like a mutable reference, except that it is not +/// safe to move a value out of a pinned reference unless the type of that +/// value implements the `Unpin` trait. +#[unstable(feature = "pin", issue = "0")] +pub struct Pin<'a, T: ?Sized + 'a> { + inner: &'a mut T, +} + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: ?Sized + Unpin> Pin<'a, T> { + /// Construct a new `Pin` around a reference to some data of a type that + /// implements `Unpin`. + #[unstable(feature = "pin", issue = "0")] + pub fn new(reference: &'a mut T) -> Pin<'a, T> { + Pin { inner: reference } + } +} + + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: ?Sized> Pin<'a, T> { + /// Construct a new `Pin` around a reference to some data of a type that + /// may or may not implement `Unpin`. + /// + /// This constructor is unsafe because we do not know what will happen with + /// that data after the reference ends. If you cannot guarantee that the + /// data will never move again, calling this constructor is invalid. + #[unstable(feature = "pin", issue = "0")] + pub unsafe fn new_unchecked(reference: &'a mut T) -> Pin<'a, T> { + Pin { inner: reference } + } + + /// Borrow a Pin for a shorter lifetime than it already has. + #[unstable(feature = "pin", issue = "0")] + pub fn borrow<'b>(this: &'b mut Pin<'a, T>) -> Pin<'b, T> { + Pin { inner: this.inner } + } + + /// Get a mutable reference to the data inside of this `Pin`. + /// + /// This function is unsafe. You must guarantee that you will never move + /// the data out of the mutable reference you receive when you call this + /// function. + #[unstable(feature = "pin", issue = "0")] + pub unsafe fn get_mut<'b>(this: &'b mut Pin<'a, T>) -> &'b mut T { + this.inner + } + + /// Construct a new pin by mapping the interior value. + /// + /// For example, if you wanted to get a `Pin` of a field of something, you + /// could use this to get access to that field in one line of code. + /// + /// This function is unsafe. You must guarantee that the data you return + /// will not move so long as the argument value does not move (for example, + /// because it is one of the fields of that value), and also that you do + /// not move out of the argument you receive to the interior function. + #[unstable(feature = "pin", issue = "0")] + pub unsafe fn map<'b, U, F>(this: &'b mut Pin<'a, T>, f: F) -> Pin<'b, U> where + F: FnOnce(&mut T) -> &mut U + { + Pin { inner: f(this.inner) } + } +} + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: ?Sized> Deref for Pin<'a, T> { + type Target = T; + + fn deref(&self) -> &T { + &*self.inner + } +} + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: ?Sized + Unpin> DerefMut for Pin<'a, T> { + fn deref_mut(&mut self) -> &mut T { + self.inner + } +} + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for Pin<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: fmt::Display + ?Sized> fmt::Display for Pin<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: ?Sized> fmt::Pointer for Pin<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&(&*self.inner as *const T), f) + } +} + +#[unstable(feature = "pin", issue = "0")] +impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for Pin<'a, T> {} From f9bf8270556ea7f89df32c40bd536a26457f8818 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 12 Mar 2018 16:31:34 -0400 Subject: [PATCH 218/830] resolve `'_` in `dyn Trait` just like ordinary elision cc #48468 --- src/librustc/middle/resolve_lifetime.rs | 25 ++++++++++++--- .../dyn-trait-underscore.rs | 32 +++++++++++++++++++ .../dyn-trait-underscore.stderr | 27 ++++++++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/underscore-lifetime/dyn-trait-underscore.rs create mode 100644 src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index f8fb2e5a1c82..0aa750aba066 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -19,6 +19,7 @@ use hir::map::Map; use hir::def::Def; use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use hir::ItemLocalId; +use hir::LifetimeName; use ty::{self, TyCtxt}; use std::cell::Cell; @@ -569,10 +570,26 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { for bound in bounds { self.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); } - if lifetime.is_elided() { - self.resolve_object_lifetime_default(lifetime) - } else { - self.visit_lifetime(lifetime); + match lifetime.name { + LifetimeName::Implicit => { + // If the user does not write *anything*, we + // use the object lifetime defaulting + // rules. So e.g. `Box` becomes + // `Box`. + self.resolve_object_lifetime_default(lifetime) + } + LifetimeName::Underscore => { + // If the user writes `'_`, we use the *ordinary* elision + // rules. So the `'_` in e.g. `Box` will be + // resolved the same as the `'_` in `&'_ Foo`. + // + // cc #48468 + self.resolve_elided_lifetimes(slice::from_ref(lifetime), false) + } + LifetimeName::Static | LifetimeName::Name(_) => { + // If the user wrote an explicit name, use that. + self.visit_lifetime(lifetime); + } } } hir::TyRptr(ref lifetime_ref, ref mt) => { diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs new file mode 100644 index 000000000000..c24762201004 --- /dev/null +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs @@ -0,0 +1,32 @@ +// Copyright 2015 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. + +// Check that the `'_` in `dyn Trait + '_` acts like ordinary elision, +// and not like an object lifetime default. +// +// cc #48468 + +#![feature(dyn_trait)] +#![feature(underscore_lifetimes)] + +fn a(items: &[T]) -> Box> { + // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` + Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime +} + +fn b(items: &[T]) -> Box + '_> { + Box::new(items.iter()) // OK, equivalent to c +} + +fn c<'a, T>(items: &'a [T]) -> Box + 'a> { + Box::new(items.iter()) // OK, equivalent to b +} + +fn main() { } diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr new file mode 100644 index 000000000000..cb3035f42a04 --- /dev/null +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -0,0 +1,27 @@ +error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements + --> $DIR/dyn-trait-underscore.rs:21:20 + | +LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime + | ^^^^ + | +note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 19:1... + --> $DIR/dyn-trait-underscore.rs:19:1 + | +LL | / fn a(items: &[T]) -> Box> { +LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` +LL | | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime +LL | | } + | |_^ +note: ...so that reference does not outlive borrowed content + --> $DIR/dyn-trait-underscore.rs:21:14 + | +LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime + | ^^^^^ + = note: but, the lifetime must be valid for the static lifetime... + = note: ...so that the expression is assignable: + expected std::boxed::Box + 'static> + found std::boxed::Box> + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0495`. From 26fe97f1f90f71613b648e822e663ec52832c51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 3 Mar 2018 06:21:27 +0100 Subject: [PATCH 219/830] Require a thread-safe file loader --- src/librustc_driver/lib.rs | 4 ++-- src/libsyntax/codemap.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 04513bfa53d0..36dda8793a1b 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -444,7 +444,7 @@ fn get_trans_sysroot(backend_name: &str) -> fn() -> Box { // The FileLoader provides a way to load files from sources other than the file system. pub fn run_compiler<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>, - file_loader: Option>, + file_loader: Option>, emitter_dest: Option>) -> (CompileResult, Option) { @@ -455,7 +455,7 @@ pub fn run_compiler<'a>(args: &[String], fn run_compiler_impl<'a>(args: &[String], callbacks: &mut CompilerCalls<'a>, - file_loader: Option>, + file_loader: Option>, emitter_dest: Option>) -> (CompileResult, Option) { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index c340f1b8c8ab..6a5a180fc0a7 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -127,7 +127,7 @@ impl StableFilemapId { pub struct CodeMap { pub(super) files: RefCell>>, - file_loader: Box, + file_loader: Box, // This is used to apply the file path remapping as specified via // --remap-path-prefix to all FileMaps allocated within this CodeMap. path_mapping: FilePathMapping, @@ -157,7 +157,7 @@ impl CodeMap { } - pub fn with_file_loader(file_loader: Box, + pub fn with_file_loader(file_loader: Box, path_mapping: FilePathMapping) -> CodeMap { CodeMap { From 426c51d6ea567170e237a66b49d512fab24cd32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 10 Mar 2018 06:40:17 +0100 Subject: [PATCH 220/830] Make FileMap thread-safe --- src/librustc/ich/impls_syntax.rs | 33 +++++++++------- src/libsyntax_pos/lib.rs | 67 ++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 52f43fbed7b0..289bc753d7fe 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -417,24 +417,27 @@ impl<'a> HashStable> for FileMap { src_hash.hash_stable(hcx, hasher); // We only hash the relative position within this filemap - let lines = lines.borrow(); - lines.len().hash_stable(hcx, hasher); - for &line in lines.iter() { - stable_byte_pos(line, start_pos).hash_stable(hcx, hasher); - } + lines.with_lock(|lines| { + lines.len().hash_stable(hcx, hasher); + for &line in lines.iter() { + stable_byte_pos(line, start_pos).hash_stable(hcx, hasher); + } + }); // We only hash the relative position within this filemap - let multibyte_chars = multibyte_chars.borrow(); - multibyte_chars.len().hash_stable(hcx, hasher); - for &char_pos in multibyte_chars.iter() { - stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher); - } + multibyte_chars.with_lock(|multibyte_chars| { + multibyte_chars.len().hash_stable(hcx, hasher); + for &char_pos in multibyte_chars.iter() { + stable_multibyte_char(char_pos, start_pos).hash_stable(hcx, hasher); + } + }); - let non_narrow_chars = non_narrow_chars.borrow(); - non_narrow_chars.len().hash_stable(hcx, hasher); - for &char_pos in non_narrow_chars.iter() { - stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher); - } + non_narrow_chars.with_lock(|non_narrow_chars| { + non_narrow_chars.len().hash_stable(hcx, hasher); + for &char_pos in non_narrow_chars.iter() { + stable_non_narrow_char(char_pos, start_pos).hash_stable(hcx, hasher); + } + }); } } diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index bec46ff3d797..4711d43bfab1 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -27,7 +27,7 @@ #![feature(specialization)] use std::borrow::Cow; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::cmp::{self, Ordering}; use std::fmt; use std::hash::{Hasher, Hash}; @@ -699,17 +699,17 @@ pub struct FileMap { pub src_hash: u128, /// The external source code (used for external crates, which will have a `None` /// value as `self.src`. - pub external_src: RefCell, + pub external_src: Lock, /// The start position of this source in the CodeMap pub start_pos: BytePos, /// The end position of this source in the CodeMap pub end_pos: BytePos, /// Locations of lines beginnings in the source code - pub lines: RefCell>, + pub lines: Lock>, /// Locations of multi-byte characters in the source code - pub multibyte_chars: RefCell>, + pub multibyte_chars: Lock>, /// Width of characters that are not narrow in the source code - pub non_narrow_chars: RefCell>, + pub non_narrow_chars: Lock>, /// A hash of the filename, used for speeding up the incr. comp. hashing. pub name_hash: u128, } @@ -839,10 +839,10 @@ impl Decodable for FileMap { end_pos, src: None, src_hash, - external_src: RefCell::new(ExternalSource::AbsentOk), - lines: RefCell::new(lines), - multibyte_chars: RefCell::new(multibyte_chars), - non_narrow_chars: RefCell::new(non_narrow_chars), + external_src: Lock::new(ExternalSource::AbsentOk), + lines: Lock::new(lines), + multibyte_chars: Lock::new(multibyte_chars), + non_narrow_chars: Lock::new(non_narrow_chars), name_hash, }) }) @@ -882,12 +882,12 @@ impl FileMap { crate_of_origin: 0, src: Some(Lrc::new(src)), src_hash, - external_src: RefCell::new(ExternalSource::Unneeded), + external_src: Lock::new(ExternalSource::Unneeded), start_pos, end_pos: Pos::from_usize(end_pos), - lines: RefCell::new(Vec::new()), - multibyte_chars: RefCell::new(Vec::new()), - non_narrow_chars: RefCell::new(Vec::new()), + lines: Lock::new(Vec::new()), + multibyte_chars: Lock::new(Vec::new()), + non_narrow_chars: Lock::new(Vec::new()), name_hash, } } @@ -919,19 +919,24 @@ impl FileMap { if *self.external_src.borrow() == ExternalSource::AbsentOk { let src = get_src(); let mut external_src = self.external_src.borrow_mut(); - if let Some(src) = src { - let mut hasher: StableHasher = StableHasher::new(); - hasher.write(src.as_bytes()); + // Check that no-one else have provided the source while we were getting it + if *external_src == ExternalSource::AbsentOk { + if let Some(src) = src { + let mut hasher: StableHasher = StableHasher::new(); + hasher.write(src.as_bytes()); - if hasher.finish() == self.src_hash { - *external_src = ExternalSource::Present(src); - return true; + if hasher.finish() == self.src_hash { + *external_src = ExternalSource::Present(src); + return true; + } + } else { + *external_src = ExternalSource::AbsentErr; } - } else { - *external_src = ExternalSource::AbsentErr; - } - false + false + } else { + self.src.is_some() || external_src.get_source().is_some() + } } else { self.src.is_some() || self.external_src.borrow().get_source().is_some() } @@ -951,14 +956,16 @@ impl FileMap { } } - let lines = self.lines.borrow(); - let line = if let Some(line) = lines.get(line_number) { - line - } else { - return None; + let begin = { + let lines = self.lines.borrow(); + let line = if let Some(line) = lines.get(line_number) { + line + } else { + return None; + }; + let begin: BytePos = *line - self.start_pos; + begin.to_usize() }; - let begin: BytePos = *line - self.start_pos; - let begin = begin.to_usize(); if let Some(ref src) = self.src { Some(Cow::from(get_until_newline(src, begin))) From a857e6003e3f1ee1023bb8ec50cf652164bf5e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 10 Mar 2018 06:40:25 +0100 Subject: [PATCH 221/830] Make CodeMap thread-safe --- src/libsyntax/codemap.rs | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 6a5a180fc0a7..829ba386d352 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -24,8 +24,7 @@ pub use self::ExpnFormat::*; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_data_structures::sync::Lrc; -use std::cell::{RefCell, Ref}; +use rustc_data_structures::sync::{Lrc, Lock, LockGuard}; use std::cmp; use std::hash::Hash; use std::path::{Path, PathBuf}; @@ -126,12 +125,12 @@ impl StableFilemapId { // pub struct CodeMap { - pub(super) files: RefCell>>, + pub(super) files: Lock>>, file_loader: Box, // This is used to apply the file path remapping as specified via // --remap-path-prefix to all FileMaps allocated within this CodeMap. path_mapping: FilePathMapping, - stable_id_to_filemap: RefCell>>, + stable_id_to_filemap: Lock>>, /// In case we are in a doctest, replace all file names with the PathBuf, /// and add the given offsets to the line info doctest_offset: Option<(FileName, isize)>, @@ -140,10 +139,10 @@ pub struct CodeMap { impl CodeMap { pub fn new(path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: RefCell::new(Vec::new()), + files: Lock::new(Vec::new()), file_loader: Box::new(RealFileLoader), path_mapping, - stable_id_to_filemap: RefCell::new(FxHashMap()), + stable_id_to_filemap: Lock::new(FxHashMap()), doctest_offset: None, } } @@ -161,10 +160,10 @@ impl CodeMap { path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: RefCell::new(Vec::new()), - file_loader, + files: Lock::new(Vec::new()), + file_loader: file_loader, path_mapping, - stable_id_to_filemap: RefCell::new(FxHashMap()), + stable_id_to_filemap: Lock::new(FxHashMap()), doctest_offset: None, } } @@ -187,7 +186,7 @@ impl CodeMap { Ok(self.new_filemap(filename, src)) } - pub fn files(&self) -> Ref>> { + pub fn files(&self) -> LockGuard>> { self.files.borrow() } @@ -209,7 +208,6 @@ impl CodeMap { /// intend to set the line information yourself, you should use new_filemap_and_lines. pub fn new_filemap(&self, filename: FileName, src: String) -> Lrc { let start_pos = self.next_start_pos(); - let mut files = self.files.borrow_mut(); // The path is used to determine the directory for loading submodules and // include files, so it must be before remapping. @@ -233,7 +231,7 @@ impl CodeMap { Pos::from_usize(start_pos), )); - files.push(filemap.clone()); + self.files.borrow_mut().push(filemap.clone()); self.stable_id_to_filemap .borrow_mut() @@ -273,7 +271,6 @@ impl CodeMap { mut file_local_non_narrow_chars: Vec) -> Lrc { let start_pos = self.next_start_pos(); - let mut files = self.files.borrow_mut(); let end_pos = Pos::from_usize(start_pos + source_len); let start_pos = Pos::from_usize(start_pos); @@ -297,16 +294,16 @@ impl CodeMap { crate_of_origin, src: None, src_hash, - external_src: RefCell::new(ExternalSource::AbsentOk), + external_src: Lock::new(ExternalSource::AbsentOk), start_pos, end_pos, - lines: RefCell::new(file_local_lines), - multibyte_chars: RefCell::new(file_local_multibyte_chars), - non_narrow_chars: RefCell::new(file_local_non_narrow_chars), + lines: Lock::new(file_local_lines), + multibyte_chars: Lock::new(file_local_multibyte_chars), + non_narrow_chars: Lock::new(file_local_non_narrow_chars), name_hash, }); - files.push(filemap.clone()); + self.files.borrow_mut().push(filemap.clone()); self.stable_id_to_filemap .borrow_mut() @@ -401,8 +398,7 @@ impl CodeMap { pub fn lookup_line(&self, pos: BytePos) -> Result> { let idx = self.lookup_filemap_idx(pos); - let files = self.files.borrow(); - let f = (*files)[idx].clone(); + let f = (*self.files.borrow())[idx].clone(); match f.lookup_line(pos) { Some(line) => Ok(FileMapAndLine { fm: f, line: line }), @@ -810,8 +806,7 @@ impl CodeMap { /// Converts an absolute BytePos to a CharPos relative to the filemap. pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos { let idx = self.lookup_filemap_idx(bpos); - let files = self.files.borrow(); - let map = &(*files)[idx]; + let map = &(*self.files.borrow())[idx]; // The number of extra bytes due to multibyte chars in the FileMap let mut total_extra_bytes = 0; From 8395ce9451c901a4b5ce3afd916bd20785e6db7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 3 Mar 2018 06:26:02 +0100 Subject: [PATCH 222/830] Require the code mapper to be thread-safe --- src/librustc_errors/emitter.rs | 12 +++++------- src/librustc_errors/lib.rs | 11 +++++++---- src/libsyntax/json.rs | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 3b6e6db7f46c..ca5d3f55a0fe 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -12,7 +12,7 @@ use self::Destination::*; use syntax_pos::{DUMMY_SP, FileMap, Span, MultiSpan}; -use {Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic, CodeMapper, DiagnosticId}; +use {Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic, CodeMapperDyn, DiagnosticId}; use snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style}; use styled_buffer::StyledBuffer; @@ -120,7 +120,7 @@ impl ColorConfig { pub struct EmitterWriter { dst: Destination, - cm: Option>, + cm: Option>, short_message: bool, teach: bool, ui_testing: bool, @@ -134,7 +134,7 @@ struct FileWithAnnotatedLines { impl EmitterWriter { pub fn stderr(color_config: ColorConfig, - code_map: Option>, + code_map: Option>, short_message: bool, teach: bool) -> EmitterWriter { @@ -149,7 +149,7 @@ impl EmitterWriter { } pub fn new(dst: Box, - code_map: Option>, + code_map: Option>, short_message: bool, teach: bool) -> EmitterWriter { @@ -1195,8 +1195,6 @@ impl EmitterWriter { level: &Level, max_line_num_len: usize) -> io::Result<()> { - use std::borrow::Borrow; - if let Some(ref cm) = self.cm { let mut buffer = StyledBuffer::new(); @@ -1213,7 +1211,7 @@ impl EmitterWriter { Some(Style::HeaderMsg)); // Render the replacements for each suggestion - let suggestions = suggestion.splice_lines(cm.borrow()); + let suggestions = suggestion.splice_lines(&**cm); let mut row_num = 2; for &(ref complete, ref parts) in suggestions.iter().take(MAX_SUGGESTIONS) { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7148969191f2..a25c3668bb13 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -36,7 +36,7 @@ use self::Level::*; use emitter::{Emitter, EmitterWriter}; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{self, Lrc}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stable_hasher::StableHasher; @@ -106,6 +106,8 @@ pub struct SubstitutionPart { pub snippet: String, } +pub type CodeMapperDyn = CodeMapper + sync::Send + sync::Sync; + pub trait CodeMapper { fn lookup_char_pos(&self, pos: BytePos) -> Loc; fn span_to_lines(&self, sp: Span) -> FileLinesResult; @@ -119,7 +121,8 @@ pub trait CodeMapper { impl CodeSuggestion { /// Returns the assembled code suggestions and whether they should be shown with an underline. - pub fn splice_lines(&self, cm: &CodeMapper) -> Vec<(String, Vec)> { + pub fn splice_lines(&self, cm: &CodeMapperDyn) + -> Vec<(String, Vec)> { use syntax_pos::{CharPos, Loc, Pos}; fn push_trailing(buf: &mut String, @@ -290,7 +293,7 @@ impl Handler { pub fn with_tty_emitter(color_config: ColorConfig, can_emit_warnings: bool, treat_err_as_bug: bool, - cm: Option>) + cm: Option>) -> Handler { Handler::with_tty_emitter_and_flags( color_config, @@ -303,7 +306,7 @@ impl Handler { } pub fn with_tty_emitter_and_flags(color_config: ColorConfig, - cm: Option>, + cm: Option>, flags: HandlerFlags) -> Handler { let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false, false)); diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index eed3c6914054..b4f34fb12e36 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -26,7 +26,7 @@ use errors::{DiagnosticBuilder, SubDiagnostic, CodeSuggestion, CodeMapper}; use errors::DiagnosticId; use errors::emitter::{Emitter, EmitterWriter}; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{self, Lrc}; use std::io::{self, Write}; use std::vec; use std::sync::{Arc, Mutex}; @@ -36,7 +36,7 @@ use rustc_serialize::json::{as_json, as_pretty_json}; pub struct JsonEmitter { dst: Box, registry: Option, - cm: Lrc, + cm: Lrc, pretty: bool, /// Whether "approximate suggestions" are enabled in the config approximate_suggestions: bool, From 65b49902538b319f9fb07532beff9d02efd3197f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 18:11:37 +0100 Subject: [PATCH 223/830] Use a single Lock for CodeMap.stable_id_to_filemap and CodeMap.files --- src/libsyntax/codemap.rs | 55 ++++++++++++++++++-------------- src/libsyntax/parse/lexer/mod.rs | 2 +- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 829ba386d352..7027fdfa2fe3 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -124,13 +124,17 @@ impl StableFilemapId { // CodeMap // +pub(super) struct CodeMapFiles { + pub(super) file_maps: Vec>, + stable_id_to_filemap: FxHashMap> +} + pub struct CodeMap { - pub(super) files: Lock>>, + pub(super) files: Lock, file_loader: Box, // This is used to apply the file path remapping as specified via // --remap-path-prefix to all FileMaps allocated within this CodeMap. path_mapping: FilePathMapping, - stable_id_to_filemap: Lock>>, /// In case we are in a doctest, replace all file names with the PathBuf, /// and add the given offsets to the line info doctest_offset: Option<(FileName, isize)>, @@ -139,10 +143,12 @@ pub struct CodeMap { impl CodeMap { pub fn new(path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: Lock::new(Vec::new()), + files: Lock::new(CodeMapFiles { + file_maps: Vec::new(), + stable_id_to_filemap: FxHashMap(), + }), file_loader: Box::new(RealFileLoader), path_mapping, - stable_id_to_filemap: Lock::new(FxHashMap()), doctest_offset: None, } } @@ -160,10 +166,12 @@ impl CodeMap { path_mapping: FilePathMapping) -> CodeMap { CodeMap { - files: Lock::new(Vec::new()), + files: Lock::new(CodeMapFiles { + file_maps: Vec::new(), + stable_id_to_filemap: FxHashMap(), + }), file_loader: file_loader, path_mapping, - stable_id_to_filemap: Lock::new(FxHashMap()), doctest_offset: None, } } @@ -187,16 +195,15 @@ impl CodeMap { } pub fn files(&self) -> LockGuard>> { - self.files.borrow() + LockGuard::map(self.files.borrow(), |files| &mut files.file_maps) } pub fn filemap_by_stable_id(&self, stable_id: StableFilemapId) -> Option> { - self.stable_id_to_filemap.borrow().get(&stable_id).map(|fm| fm.clone()) + self.files.borrow().stable_id_to_filemap.get(&stable_id).map(|fm| fm.clone()) } fn next_start_pos(&self) -> usize { - let files = self.files.borrow(); - match files.last() { + match self.files.borrow().file_maps.last() { None => 0, // Add one so there is some space between files. This lets us distinguish // positions in the codemap, even in the presence of zero-length files. @@ -206,6 +213,7 @@ impl CodeMap { /// Creates a new filemap without setting its line information. If you don't /// intend to set the line information yourself, you should use new_filemap_and_lines. + /// This does not ensure that only one FileMap exists per file name. pub fn new_filemap(&self, filename: FileName, src: String) -> Lrc { let start_pos = self.next_start_pos(); @@ -231,16 +239,16 @@ impl CodeMap { Pos::from_usize(start_pos), )); - self.files.borrow_mut().push(filemap.clone()); + let mut files = self.files.borrow_mut(); - self.stable_id_to_filemap - .borrow_mut() - .insert(StableFilemapId::new(&filemap), filemap.clone()); + files.file_maps.push(filemap.clone()); + files.stable_id_to_filemap.insert(StableFilemapId::new(&filemap), filemap.clone()); filemap } /// Creates a new filemap and sets its line information. + /// This does not ensure that only one FileMap exists per file name. pub fn new_filemap_and_lines(&self, filename: &Path, src: &str) -> Lrc { let fm = self.new_filemap(filename.to_owned().into(), src.to_owned()); let mut byte_pos: u32 = fm.start_pos.0; @@ -303,11 +311,10 @@ impl CodeMap { name_hash, }); - self.files.borrow_mut().push(filemap.clone()); + let mut files = self.files.borrow_mut(); - self.stable_id_to_filemap - .borrow_mut() - .insert(StableFilemapId::new(&filemap), filemap.clone()); + files.file_maps.push(filemap.clone()); + files.stable_id_to_filemap.insert(StableFilemapId::new(&filemap), filemap.clone()); filemap } @@ -398,7 +405,7 @@ impl CodeMap { pub fn lookup_line(&self, pos: BytePos) -> Result> { let idx = self.lookup_filemap_idx(pos); - let f = (*self.files.borrow())[idx].clone(); + let f = (*self.files.borrow().file_maps)[idx].clone(); match f.lookup_line(pos) { Some(line) => Ok(FileMapAndLine { fm: f, line: line }), @@ -452,7 +459,7 @@ impl CodeMap { } pub fn span_to_string(&self, sp: Span) -> String { - if self.files.borrow().is_empty() && sp.source_equal(&DUMMY_SP) { + if self.files.borrow().file_maps.is_empty() && sp.source_equal(&DUMMY_SP) { return "no-location".to_string(); } @@ -787,7 +794,7 @@ impl CodeMap { } pub fn get_filemap(&self, filename: &FileName) -> Option> { - for fm in self.files.borrow().iter() { + for fm in self.files.borrow().file_maps.iter() { if *filename == fm.name { return Some(fm.clone()); } @@ -798,7 +805,7 @@ impl CodeMap { /// For a global BytePos compute the local offset within the containing FileMap pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos { let idx = self.lookup_filemap_idx(bpos); - let fm = (*self.files.borrow())[idx].clone(); + let fm = (*self.files.borrow().file_maps)[idx].clone(); let offset = bpos - fm.start_pos; FileMapAndBytePos {fm: fm, pos: offset} } @@ -806,7 +813,7 @@ impl CodeMap { /// Converts an absolute BytePos to a CharPos relative to the filemap. pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos { let idx = self.lookup_filemap_idx(bpos); - let map = &(*self.files.borrow())[idx]; + let map = &(*self.files.borrow().file_maps)[idx]; // The number of extra bytes due to multibyte chars in the FileMap let mut total_extra_bytes = 0; @@ -832,7 +839,7 @@ impl CodeMap { // Return the index of the filemap (in self.files) which contains pos. pub fn lookup_filemap_idx(&self, pos: BytePos) -> usize { let files = self.files.borrow(); - let files = &*files; + let files = &files.file_maps; let count = files.len(); // Binary search for the filemap. diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index d0075c896567..815ba49a60a7 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -611,7 +611,7 @@ impl<'a> StringReader<'a> { // I guess this is the only way to figure out if // we're at the beginning of the file... let cmap = CodeMap::new(FilePathMapping::empty()); - cmap.files.borrow_mut().push(self.filemap.clone()); + cmap.files.borrow_mut().file_maps.push(self.filemap.clone()); let loc = cmap.lookup_char_pos_adj(self.pos); debug!("Skipping a shebang"); if loc.line == 1 && loc.col == CharPos(0) { From 5766e71fa7b3378d0b30d026eae23293e8e8bb32 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Tue, 13 Mar 2018 21:36:49 -0400 Subject: [PATCH 224/830] Cache the specialization_graph query Fixes #48987 --- src/librustc/traits/specialize/specialization_graph.rs | 2 ++ src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/maps/config.rs | 1 + src/librustc/ty/maps/on_disk_cache.rs | 1 + src/librustc/ty/maps/plumbing.rs | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index f8b895177f38..e0d662657b7d 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -36,6 +36,7 @@ use util::nodemap::{DefIdMap, FxHashMap}; /// parents of a given specializing impl, which is needed for extracting /// default items amongst other things. In the simple "chain" rule, every impl /// has at most one parent. +#[derive(RustcEncodable, RustcDecodable)] pub struct Graph { // all impls have a parent; the "root" impls have as their parent the def_id // of the trait @@ -47,6 +48,7 @@ pub struct Graph { /// Children of a given impl, grouped into blanket/non-blanket varieties as is /// done in `TraitDef`. +#[derive(RustcEncodable, RustcDecodable)] struct Children { // Impls of a trait (or specializations of a given impl). To allow for // quicker lookup, the impls are indexed by a simplified version of their diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 93d8a4d979de..889648a46be1 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -28,7 +28,7 @@ pub type SimplifiedType = SimplifiedTypeGen; /// because we sometimes need to use SimplifiedTypeGen values as stable sorting /// keys (in which case we use a DefPathHash as id-type) but in the general case /// the non-stable but fast to construct DefId-version is the better choice. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, RustcEncodable, RustcDecodable)] pub enum SimplifiedTypeGen where D: Copy + Debug + Ord + Eq + Hash { diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 11675f542873..008e3b7d8596 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -721,3 +721,4 @@ impl_disk_cacheable_query!(type_of, |def_id| def_id.is_local()); impl_disk_cacheable_query!(predicates_of, |def_id| def_id.is_local()); impl_disk_cacheable_query!(used_trait_imports, |def_id| def_id.is_local()); impl_disk_cacheable_query!(trans_fn_attrs, |_| true); +impl_disk_cacheable_query!(specialization_graph_of, |_| true); diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 35e874b74d9a..e7dd4c82254c 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -221,6 +221,7 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; + encode_query_results::(tcx, enc, qri)?; // const eval is special, it only encodes successfully evaluated constants use ty::maps::plumbing::GetCacheInternal; diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index bc7186f781a8..0bff13a71e39 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -1001,4 +1001,5 @@ impl_load_from_cache!( PredicatesOfItem => predicates_of, UsedTraitImports => used_trait_imports, TransFnAttrs => trans_fn_attrs, + SpecializationGraph => specialization_graph_of, ); From 6d8a1739805fa81b6baa8c86efc3e79920ecb306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 10 Feb 2018 21:01:49 -0800 Subject: [PATCH 225/830] Reword E0044 and message for `!Send` types - Reword E0044 help. - Change error message for types that don't implement `Send` --- src/libcore/marker.rs | 5 ++++- src/librustc_typeck/check/mod.rs | 7 ++++--- .../builtin-superkinds-double-superkind.rs | 6 ++++-- src/test/compile-fail/closure-bounds-subtype.rs | 2 +- src/test/compile-fail/extern-types-not-sync-send.rs | 2 +- src/test/compile-fail/issue-16538.rs | 2 +- src/test/compile-fail/issue-17718-static-sync.rs | 2 +- src/test/compile-fail/issue-43733-2.rs | 4 ++-- src/test/compile-fail/issue-7364.rs | 2 +- src/test/compile-fail/kindck-send-object.rs | 2 +- src/test/compile-fail/kindck-send-object1.rs | 2 +- src/test/compile-fail/kindck-send-object2.rs | 3 ++- src/test/compile-fail/mutable-enum-indirect.rs | 3 ++- src/test/compile-fail/mutexguard-sync.rs | 3 ++- src/test/compile-fail/no_share-enum.rs | 2 +- src/test/compile-fail/no_share-struct.rs | 2 +- src/test/compile-fail/not-sync.rs | 12 ++++++------ src/test/compile-fail/phantom-oibit.rs | 6 ++++-- .../typeck-default-trait-impl-negation-sync.rs | 6 +++--- src/test/compile-fail/typeck-unsafe-always-share.rs | 8 ++++---- src/test/ui/error-codes/E0044.rs | 8 ++++++-- src/test/ui/error-codes/E0044.stderr | 12 ++++-------- src/test/ui/fmt/send-sync.rs | 4 ++-- src/test/ui/fmt/send-sync.stderr | 8 ++++---- src/test/ui/generator/not-send-sync.rs | 4 ++-- src/test/ui/generator/not-send-sync.stderr | 4 ++-- 26 files changed, 66 insertions(+), 55 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 98e0f71eb935..fd57491fcc76 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -343,7 +343,10 @@ pub trait Copy : Clone { /// [transmute]: ../../std/mem/fn.transmute.html #[stable(feature = "rust1", since = "1.0.0")] #[lang = "sync"] -#[rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely"] +#[rustc_on_unimplemented( + message="`{Self}` cannot be shared between threads safely", + label="`{Self}` cannot be shared between threads safely" +)] pub unsafe auto trait Sync { // Empty } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 19085ff039ec..92c6e3ffed2d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1222,9 +1222,10 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item if !generics.types.is_empty() { let mut err = struct_span_err!(tcx.sess, item.span, E0044, "foreign items may not have type parameters"); - span_help!(&mut err, item.span, - "consider using specialization instead of \ - type parameters"); + // FIXME: once we start storing spans for type arguments, turn this into a + // suggestion. + err.help("use specialization instead of type parameters by replacing them \ + with concrete types like `u32`"); err.emit(); } diff --git a/src/test/compile-fail/builtin-superkinds-double-superkind.rs b/src/test/compile-fail/builtin-superkinds-double-superkind.rs index 8d5d8e8dc9b7..261881d880bf 100644 --- a/src/test/compile-fail/builtin-superkinds-double-superkind.rs +++ b/src/test/compile-fail/builtin-superkinds-double-superkind.rs @@ -13,9 +13,11 @@ trait Foo : Send+Sync { } -impl Foo for (T,) { } //~ ERROR `T: std::marker::Send` is not satisfied +impl Foo for (T,) { } +//~^ ERROR the trait bound `T: std::marker::Send` is not satisfied in `(T,)` [E0277] -impl Foo for (T,T) { } //~ ERROR `T: std::marker::Sync` is not satisfied +impl Foo for (T,T) { } +//~^ ERROR `T` cannot be shared between threads safely [E0277] impl Foo for (T,T,T) { } // (ok) diff --git a/src/test/compile-fail/closure-bounds-subtype.rs b/src/test/compile-fail/closure-bounds-subtype.rs index d3339c4845ab..db26535b004a 100644 --- a/src/test/compile-fail/closure-bounds-subtype.rs +++ b/src/test/compile-fail/closure-bounds-subtype.rs @@ -21,7 +21,7 @@ fn give_any(f: F) where F: FnOnce() { fn give_owned(f: F) where F: FnOnce() + Send { take_any(f); - take_const_owned(f); //~ ERROR `F: std::marker::Sync` is not satisfied + take_const_owned(f); //~ ERROR `F` cannot be shared between threads safely [E0277] } fn main() {} diff --git a/src/test/compile-fail/extern-types-not-sync-send.rs b/src/test/compile-fail/extern-types-not-sync-send.rs index 2f00cf812e47..6a7a515ba5fb 100644 --- a/src/test/compile-fail/extern-types-not-sync-send.rs +++ b/src/test/compile-fail/extern-types-not-sync-send.rs @@ -21,7 +21,7 @@ fn assert_send() { } fn main() { assert_sync::(); - //~^ ERROR the trait bound `A: std::marker::Sync` is not satisfied + //~^ ERROR `A` cannot be shared between threads safely [E0277] assert_send::(); //~^ ERROR the trait bound `A: std::marker::Send` is not satisfied diff --git a/src/test/compile-fail/issue-16538.rs b/src/test/compile-fail/issue-16538.rs index 08c3f7a7c154..7df445c676c9 100644 --- a/src/test/compile-fail/issue-16538.rs +++ b/src/test/compile-fail/issue-16538.rs @@ -21,7 +21,7 @@ mod Y { } static foo: *const Y::X = Y::foo(Y::x as *const Y::X); -//~^ ERROR `*const usize: std::marker::Sync` is not satisfied +//~^ ERROR `*const usize` cannot be shared between threads safely [E0277] //~| ERROR cannot refer to other statics by value, use the address-of operator or a constant instead //~| ERROR E0015 diff --git a/src/test/compile-fail/issue-17718-static-sync.rs b/src/test/compile-fail/issue-17718-static-sync.rs index 790329cd2e42..c5349d4e82b4 100644 --- a/src/test/compile-fail/issue-17718-static-sync.rs +++ b/src/test/compile-fail/issue-17718-static-sync.rs @@ -17,6 +17,6 @@ impl !Sync for Foo {} static FOO: usize = 3; static BAR: Foo = Foo; -//~^ ERROR: `Foo: std::marker::Sync` is not satisfied +//~^ ERROR: `Foo` cannot be shared between threads safely [E0277] fn main() {} diff --git a/src/test/compile-fail/issue-43733-2.rs b/src/test/compile-fail/issue-43733-2.rs index 0fd31454596e..a5ba9ef9bd35 100644 --- a/src/test/compile-fail/issue-43733-2.rs +++ b/src/test/compile-fail/issue-43733-2.rs @@ -33,7 +33,7 @@ impl Key { use std::thread::__FastLocalKeyInner as Key; static __KEY: Key<()> = Key::new(); -//~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied -//~| ERROR `std::cell::Cell: std::marker::Sync` is not satisfied +//~^ ERROR `std::cell::UnsafeCell>` cannot be shared between threads +//~| ERROR `std::cell::Cell` cannot be shared between threads safely [E0277] fn main() {} diff --git a/src/test/compile-fail/issue-7364.rs b/src/test/compile-fail/issue-7364.rs index 16138c992ff7..801a1301ad77 100644 --- a/src/test/compile-fail/issue-7364.rs +++ b/src/test/compile-fail/issue-7364.rs @@ -15,6 +15,6 @@ use std::cell::RefCell; // Regression test for issue 7364 static boxed: Box> = box RefCell::new(0); //~^ ERROR allocations are not allowed in statics -//~| ERROR `std::cell::RefCell: std::marker::Sync` is not satisfied +//~| ERROR `std::cell::RefCell` cannot be shared between threads safely [E0277] fn main() { } diff --git a/src/test/compile-fail/kindck-send-object.rs b/src/test/compile-fail/kindck-send-object.rs index bd0e5642b9cc..a84eae0bfdae 100644 --- a/src/test/compile-fail/kindck-send-object.rs +++ b/src/test/compile-fail/kindck-send-object.rs @@ -20,7 +20,7 @@ trait Message : Send { } fn object_ref_with_static_bound_not_ok() { assert_send::<&'static (Dummy+'static)>(); - //~^ ERROR : std::marker::Sync` is not satisfied + //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277] } fn box_object_with_no_bound_not_ok<'a>() { diff --git a/src/test/compile-fail/kindck-send-object1.rs b/src/test/compile-fail/kindck-send-object1.rs index da56fccde2d4..66865bbcc7ee 100644 --- a/src/test/compile-fail/kindck-send-object1.rs +++ b/src/test/compile-fail/kindck-send-object1.rs @@ -18,7 +18,7 @@ trait Dummy { } // careful with object types, who knows what they close over... fn test51<'a>() { assert_send::<&'a Dummy>(); - //~^ ERROR : std::marker::Sync` is not satisfied + //~^ ERROR `Dummy + 'a` cannot be shared between threads safely [E0277] } fn test52<'a>() { assert_send::<&'a (Dummy+Sync)>(); diff --git a/src/test/compile-fail/kindck-send-object2.rs b/src/test/compile-fail/kindck-send-object2.rs index e52a6e12efc9..51bc587d74ff 100644 --- a/src/test/compile-fail/kindck-send-object2.rs +++ b/src/test/compile-fail/kindck-send-object2.rs @@ -14,7 +14,8 @@ fn assert_send() { } trait Dummy { } fn test50() { - assert_send::<&'static Dummy>(); //~ ERROR : std::marker::Sync` is not satisfied + assert_send::<&'static Dummy>(); + //~^ ERROR `Dummy + 'static` cannot be shared between threads safely [E0277] } fn test53() { diff --git a/src/test/compile-fail/mutable-enum-indirect.rs b/src/test/compile-fail/mutable-enum-indirect.rs index cafcabe6279b..9107745b0e9c 100644 --- a/src/test/compile-fail/mutable-enum-indirect.rs +++ b/src/test/compile-fail/mutable-enum-indirect.rs @@ -24,5 +24,6 @@ fn bar(_: T) {} fn main() { let x = Foo::A(NoSync); - bar(&x); //~ ERROR `NoSync: std::marker::Sync` is not satisfied + bar(&x); + //~^ ERROR `NoSync` cannot be shared between threads safely [E0277] } diff --git a/src/test/compile-fail/mutexguard-sync.rs b/src/test/compile-fail/mutexguard-sync.rs index 861714720c57..2d4b50eb7b23 100644 --- a/src/test/compile-fail/mutexguard-sync.rs +++ b/src/test/compile-fail/mutexguard-sync.rs @@ -18,5 +18,6 @@ fn main() { let m = Mutex::new(Cell::new(0i32)); let guard = m.lock().unwrap(); - test_sync(guard); //~ ERROR the trait bound + test_sync(guard); + //~^ ERROR `std::cell::Cell` cannot be shared between threads safely [E0277] } diff --git a/src/test/compile-fail/no_share-enum.rs b/src/test/compile-fail/no_share-enum.rs index ae9a25a95b4e..77a7012b3b03 100644 --- a/src/test/compile-fail/no_share-enum.rs +++ b/src/test/compile-fail/no_share-enum.rs @@ -22,5 +22,5 @@ fn bar(_: T) {} fn main() { let x = Foo::A(NoSync); bar(x); - //~^ ERROR `NoSync: std::marker::Sync` is not satisfied + //~^ ERROR `NoSync` cannot be shared between threads safely [E0277] } diff --git a/src/test/compile-fail/no_share-struct.rs b/src/test/compile-fail/no_share-struct.rs index d64d37a2f6c3..34e43e9f2aae 100644 --- a/src/test/compile-fail/no_share-struct.rs +++ b/src/test/compile-fail/no_share-struct.rs @@ -20,5 +20,5 @@ fn bar(_: T) {} fn main() { let x = Foo { a: 5 }; bar(x); - //~^ ERROR `Foo: std::marker::Sync` is not satisfied + //~^ ERROR `Foo` cannot be shared between threads safely [E0277] } diff --git a/src/test/compile-fail/not-sync.rs b/src/test/compile-fail/not-sync.rs index 12c292791789..a383244f415c 100644 --- a/src/test/compile-fail/not-sync.rs +++ b/src/test/compile-fail/not-sync.rs @@ -16,17 +16,17 @@ fn test() {} fn main() { test::>(); - //~^ ERROR `std::cell::Cell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::Cell` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::cell::RefCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::RefCell` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::rc::Rc: std::marker::Sync` is not satisfied + //~^ ERROR `std::rc::Rc` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::rc::Weak: std::marker::Sync` is not satisfied + //~^ ERROR `std::rc::Weak` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::sync::mpsc::Receiver: std::marker::Sync` is not satisfied + //~^ ERROR `std::sync::mpsc::Receiver` cannot be shared between threads safely [E0277] test::>(); - //~^ ERROR `std::sync::mpsc::Sender: std::marker::Sync` is not satisfied + //~^ ERROR `std::sync::mpsc::Sender` cannot be shared between threads safely [E0277] } diff --git a/src/test/compile-fail/phantom-oibit.rs b/src/test/compile-fail/phantom-oibit.rs index e36c4835ca1c..51e7d5da98f4 100644 --- a/src/test/compile-fail/phantom-oibit.rs +++ b/src/test/compile-fail/phantom-oibit.rs @@ -28,11 +28,13 @@ struct Nested(T); fn is_zen(_: T) {} fn not_sync(x: Guard) { - is_zen(x) //~ error: `T: std::marker::Sync` is not satisfied + is_zen(x) + //~^ ERROR `T` cannot be shared between threads safely [E0277] } fn nested_not_sync(x: Nested>) { - is_zen(x) //~ error: `T: std::marker::Sync` is not satisfied + is_zen(x) + //~^ ERROR `T` cannot be shared between threads safely [E0277] } fn main() {} diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs b/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs index cdf787a60ad4..c829ba3dcc35 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-negation-sync.rs @@ -43,11 +43,11 @@ fn is_sync() {} fn main() { is_sync::(); is_sync::(); - //~^ ERROR `MyNotSync: std::marker::Sync` is not satisfied + //~^ ERROR `MyNotSync` cannot be shared between threads safely [E0277] is_sync::(); - //~^ ERROR `std::cell::UnsafeCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell` cannot be shared between threads safely [E0277] is_sync::(); - //~^ ERROR `Managed: std::marker::Sync` is not satisfied + //~^ ERROR `Managed` cannot be shared between threads safely [E0277] } diff --git a/src/test/compile-fail/typeck-unsafe-always-share.rs b/src/test/compile-fail/typeck-unsafe-always-share.rs index f0172777cdab..fcfc8574b213 100644 --- a/src/test/compile-fail/typeck-unsafe-always-share.rs +++ b/src/test/compile-fail/typeck-unsafe-always-share.rs @@ -27,16 +27,16 @@ fn test(s: T) {} fn main() { let us = UnsafeCell::new(MySync{u: UnsafeCell::new(0)}); test(us); - //~^ ERROR `std::cell::UnsafeCell>: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell>` cannot be shared between threads safely let uns = UnsafeCell::new(NoSync); test(uns); - //~^ ERROR `std::cell::UnsafeCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell` cannot be shared between threads safely [E0277] let ms = MySync{u: uns}; test(ms); - //~^ ERROR `std::cell::UnsafeCell: std::marker::Sync` is not satisfied + //~^ ERROR `std::cell::UnsafeCell` cannot be shared between threads safely [E0277] test(NoSync); - //~^ ERROR `NoSync: std::marker::Sync` is not satisfied + //~^ ERROR `NoSync` cannot be shared between threads safely [E0277] } diff --git a/src/test/ui/error-codes/E0044.rs b/src/test/ui/error-codes/E0044.rs index 48fe23000312..4d20edea5fe1 100644 --- a/src/test/ui/error-codes/E0044.rs +++ b/src/test/ui/error-codes/E0044.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,7 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern { fn some_func(x: T); } //~ ERROR E0044 +extern { + fn sqrt(f: T) -> T; + //~^ ERROR foreign items may not have type parameters [E0044] + //~| HELP use specialization instead of type parameters by replacing them with concrete types +} fn main() { } diff --git a/src/test/ui/error-codes/E0044.stderr b/src/test/ui/error-codes/E0044.stderr index b823f3717b35..12324e771d3a 100644 --- a/src/test/ui/error-codes/E0044.stderr +++ b/src/test/ui/error-codes/E0044.stderr @@ -1,14 +1,10 @@ error[E0044]: foreign items may not have type parameters - --> $DIR/E0044.rs:11:10 + --> $DIR/E0044.rs:12:5 | -LL | extern { fn some_func(x: T); } //~ ERROR E0044 - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | fn sqrt(f: T) -> T; + | ^^^^^^^^^^^^^^^^^^^^^^ | -help: consider using specialization instead of type parameters - --> $DIR/E0044.rs:11:10 - | -LL | extern { fn some_func(x: T); } //~ ERROR E0044 - | ^^^^^^^^^^^^^^^^^^^^^^ + = help: use specialization instead of type parameters by replacing them with concrete types like `u32` error: aborting due to previous error diff --git a/src/test/ui/fmt/send-sync.rs b/src/test/ui/fmt/send-sync.rs index 3f13fd2e4913..424919a0eba6 100644 --- a/src/test/ui/fmt/send-sync.rs +++ b/src/test/ui/fmt/send-sync.rs @@ -15,6 +15,6 @@ fn main() { // `Cell` is not `Sync`, so `&Cell` is neither `Sync` nor `Send`, // `std::fmt::Arguments` used to forget this... let c = std::cell::Cell::new(42); - send(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied - sync(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied + send(format_args!("{:?}", c)); //~ ERROR E0277 + sync(format_args!("{:?}", c)); //~ ERROR E0277 } diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 0943b64c5c09..113a2a480aaf 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -1,7 +1,7 @@ -error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `[std::fmt::ArgumentV1<'_>]` +error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely --> $DIR/send-sync.rs:18:5 | -LL | send(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied +LL | send(format_args!("{:?}", c)); //~ ERROR E0277 | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely | = help: within `[std::fmt::ArgumentV1<'_>]`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` @@ -18,10 +18,10 @@ note: required by `send` LL | fn send(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>` +error[E0277]: `*mut std::ops::Fn() + 'static` cannot be shared between threads safely --> $DIR/send-sync.rs:19:5 | -LL | sync(format_args!("{:?}", c)); //~ ERROR Sync` is not satisfied +LL | sync(format_args!("{:?}", c)); //~ ERROR E0277 | ^^^^ `*mut std::ops::Fn() + 'static` cannot be shared between threads safely | = help: within `std::fmt::Arguments<'_>`, the trait `std::marker::Sync` is not implemented for `*mut std::ops::Fn() + 'static` diff --git a/src/test/ui/generator/not-send-sync.rs b/src/test/ui/generator/not-send-sync.rs index 0419758d8ea1..f0df05ebfdf8 100644 --- a/src/test/ui/generator/not-send-sync.rs +++ b/src/test/ui/generator/not-send-sync.rs @@ -17,14 +17,14 @@ fn main() { fn assert_send(_: T) {} assert_sync(|| { - //~^ ERROR: Sync` is not satisfied + //~^ ERROR: E0277 let a = Cell::new(2); yield; }); let a = Cell::new(2); assert_send(|| { - //~^ ERROR: Sync` is not satisfied + //~^ ERROR: E0277 drop(&a); yield; }); diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 6ca583bf16d6..669e0d26cf07 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `std::cell::Cell: std::marker::Sync` is not satisfied +error[E0277]: `std::cell::Cell` cannot be shared between threads safely --> $DIR/not-send-sync.rs:26:5 | LL | assert_send(|| { @@ -13,7 +13,7 @@ note: required by `main::assert_send` LL | fn assert_send(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `std::cell::Cell: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell, ()}]` +error[E0277]: `std::cell::Cell` cannot be shared between threads safely --> $DIR/not-send-sync.rs:19:5 | LL | assert_sync(|| { From fe1975448cf180a39393104a7b424291975998d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 11 Feb 2018 13:39:32 -0800 Subject: [PATCH 226/830] Suggest using `move` when trying to share `...::channel::{Receiver, Sender}` Extend `rustc_on_unimplemented` to match on ADT without evaluating type arguments. --- src/libcore/marker.rs | 8 +++++++ src/librustc/traits/error_reporting.rs | 31 ++++++++++++++----------- src/test/ui/closure-move-sync.rs | 32 ++++++++++++++++++++++++++ src/test/ui/closure-move-sync.stderr | 24 +++++++++++++++++++ 4 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/closure-move-sync.rs create mode 100644 src/test/ui/closure-move-sync.stderr diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index fd57491fcc76..51d2e29e6b15 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -344,6 +344,14 @@ pub trait Copy : Clone { #[stable(feature = "rust1", since = "1.0.0")] #[lang = "sync"] #[rustc_on_unimplemented( + on( + _Self="std::sync::mpsc::Receiver", + label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + ), + on( + _Self="std::sync::mpsc::Sender", + label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + ), message="`{Self}` cannot be shared between threads safely", label="`{Self}` cannot be shared between threads safely" )] diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index cd2d0d7e2a04..9cdab856b05e 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -338,18 +338,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .unwrap_or(trait_ref.def_id()); let trait_ref = *trait_ref.skip_binder(); - let desugaring; - let method; let mut flags = vec![]; - let direct = match obligation.cause.code { + match obligation.cause.code { ObligationCauseCode::BuiltinDerivedObligation(..) | - ObligationCauseCode::ImplDerivedObligation(..) => false, - _ => true - }; - if direct { - // this is a "direct", user-specified, rather than derived, - // obligation. - flags.push(("direct".to_string(), None)); + ObligationCauseCode::ImplDerivedObligation(..) => {} + _ => { + // this is a "direct", user-specified, rather than derived, + // obligation. + flags.push(("direct".to_string(), None)); + } } if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code { @@ -359,21 +356,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // // Currently I'm leaving it for what I need for `try`. if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) { - method = self.tcx.item_name(item); + let method = self.tcx.item_name(item); flags.push(("from_method".to_string(), None)); flags.push(("from_method".to_string(), Some(method.to_string()))); } } if let Some(k) = obligation.cause.span.compiler_desugaring_kind() { - desugaring = k.as_symbol().as_str(); + let desugaring = k.as_symbol().as_str(); flags.push(("from_desugaring".to_string(), None)); flags.push(("from_desugaring".to_string(), Some(desugaring.to_string()))); } let generics = self.tcx.generics_of(def_id); let self_ty = trait_ref.self_ty(); - let self_ty_str = self_ty.to_string(); - flags.push(("_Self".to_string(), Some(self_ty_str.clone()))); + // This is also included through the generics list as `Self`, + // but the parser won't allow you to use it + flags.push(("_Self".to_string(), Some(self_ty.to_string()))); + if let Some(def) = self_ty.ty_adt_def() { + // We also want to be able to select self's original + // signature with no type arguments resolved + flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string()))); + } for param in generics.types.iter() { let name = param.name.as_str().to_string(); diff --git a/src/test/ui/closure-move-sync.rs b/src/test/ui/closure-move-sync.rs new file mode 100644 index 000000000000..e096e7ca3a06 --- /dev/null +++ b/src/test/ui/closure-move-sync.rs @@ -0,0 +1,32 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::thread; +use std::sync::mpsc::channel; + +fn bar() { + let (send, recv) = channel(); + let t = thread::spawn(|| { + recv.recv().unwrap(); + //~^^ ERROR `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely + }); + + send.send(()); + + t.join().unwrap(); +} + +fn foo() { + let (tx, _rx) = channel(); + thread::spawn(|| tx.send(()).unwrap()); + //~^ ERROR `std::sync::mpsc::Sender<()>` cannot be shared between threads safely +} + +fn main() {} diff --git a/src/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr new file mode 100644 index 000000000000..fc53deeeef7a --- /dev/null +++ b/src/test/ui/closure-move-sync.stderr @@ -0,0 +1,24 @@ +error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely + --> $DIR/closure-move-sync.rs:16:13 + | +16 | let t = thread::spawn(|| { + | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, if using a closure consider marking it `move` + | + = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>` + = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>` + = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:16:27: 19:6 recv:&std::sync::mpsc::Receiver<()>]` + = note: required by `std::thread::spawn` + +error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely + --> $DIR/closure-move-sync.rs:28:5 + | +28 | thread::spawn(|| tx.send(()).unwrap()); + | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, if using a closure consider marking it `move` + | + = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>` + = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>` + = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:28:19: 28:42 tx:&std::sync::mpsc::Sender<()>]` + = note: required by `std::thread::spawn` + +error: aborting due to 2 previous errors + From cb5667eaa53c45f1cdf69f367f8cd749b0499ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Feb 2018 00:15:12 -0800 Subject: [PATCH 227/830] Make hint clearer, with the potential of being wrong --- src/libcore/marker.rs | 4 ++-- src/test/ui/closure-move-sync.stderr | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 51d2e29e6b15..d78453cc900b 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -346,11 +346,11 @@ pub trait Copy : Clone { #[rustc_on_unimplemented( on( _Self="std::sync::mpsc::Receiver", - label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + label="`{Self}` cannot be shared safely, consider marking the closure `move`" ), on( _Self="std::sync::mpsc::Sender", - label="`{Self}` cannot be shared safely, if using a closure consider marking it `move`" + label="`{Self}` cannot be shared safely, consider marking the closure `move`" ), message="`{Self}` cannot be shared between threads safely", label="`{Self}` cannot be shared between threads safely" diff --git a/src/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr index fc53deeeef7a..4b59ef8a4373 100644 --- a/src/test/ui/closure-move-sync.stderr +++ b/src/test/ui/closure-move-sync.stderr @@ -2,7 +2,7 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads s --> $DIR/closure-move-sync.rs:16:13 | 16 | let t = thread::spawn(|| { - | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, if using a closure consider marking it `move` + | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, consider marking the closure `move` | = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>` = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>` @@ -13,7 +13,7 @@ error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads saf --> $DIR/closure-move-sync.rs:28:5 | 28 | thread::spawn(|| tx.send(()).unwrap()); - | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, if using a closure consider marking it `move` + | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, consider marking the closure `move` | = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>` = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>` From bfc66daef9d1bdc52000cf8c079ea8572699f6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Feb 2018 13:18:29 -0800 Subject: [PATCH 228/830] Review comment: remove mention of `move` closure --- src/libcore/marker.rs | 18 ++++++++++-------- src/test/ui/closure-move-sync.stderr | 9 +++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index d78453cc900b..53b1d1cd12de 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -344,18 +344,20 @@ pub trait Copy : Clone { #[stable(feature = "rust1", since = "1.0.0")] #[lang = "sync"] #[rustc_on_unimplemented( - on( - _Self="std::sync::mpsc::Receiver", - label="`{Self}` cannot be shared safely, consider marking the closure `move`" - ), - on( - _Self="std::sync::mpsc::Sender", - label="`{Self}` cannot be shared safely, consider marking the closure `move`" - ), message="`{Self}` cannot be shared between threads safely", label="`{Self}` cannot be shared between threads safely" )] pub unsafe auto trait Sync { + // FIXME(estebank): once support to add notes in `rustc_on_unimplemented` + // lands in beta, and it has been extended to check whether a closure is + // anywhere in the requirement chain, extend it as such (#48534): + // ``` + // on( + // closure, + // note="`{Self}` cannot be shared safely, consider marking the closure `move`" + // ), + // ``` + // Empty } diff --git a/src/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr index 4b59ef8a4373..abf07d2cef52 100644 --- a/src/test/ui/closure-move-sync.stderr +++ b/src/test/ui/closure-move-sync.stderr @@ -1,8 +1,8 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely --> $DIR/closure-move-sync.rs:16:13 | -16 | let t = thread::spawn(|| { - | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared safely, consider marking the closure `move` +LL | let t = thread::spawn(|| { + | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely | = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>` = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>` @@ -12,8 +12,8 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads s error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely --> $DIR/closure-move-sync.rs:28:5 | -28 | thread::spawn(|| tx.send(()).unwrap()); - | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared safely, consider marking the closure `move` +LL | thread::spawn(|| tx.send(()).unwrap()); + | ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared between threads safely | = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>` = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>` @@ -22,3 +22,4 @@ error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads saf error: aborting due to 2 previous errors +If you want more information on this error, try using "rustc --explain E0277" From 1bbd4fd395b7b8f5f51f90401665168b19f0b9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 14 Mar 2018 18:10:25 -0700 Subject: [PATCH 229/830] Add span label to E0044 --- src/librustc_typeck/check/mod.rs | 1 + src/test/ui/closure-move-sync.stderr | 2 +- src/test/ui/error-codes/E0044.rs | 1 + src/test/ui/error-codes/E0044.stderr | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 92c6e3ffed2d..8fe9c62927ed 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1222,6 +1222,7 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item if !generics.types.is_empty() { let mut err = struct_span_err!(tcx.sess, item.span, E0044, "foreign items may not have type parameters"); + err.span_label(item.span, "can't have type parameters"); // FIXME: once we start storing spans for type arguments, turn this into a // suggestion. err.help("use specialization instead of type parameters by replacing them \ diff --git a/src/test/ui/closure-move-sync.stderr b/src/test/ui/closure-move-sync.stderr index abf07d2cef52..076bae8dbd7a 100644 --- a/src/test/ui/closure-move-sync.stderr +++ b/src/test/ui/closure-move-sync.stderr @@ -22,4 +22,4 @@ LL | thread::spawn(|| tx.send(()).unwrap()); error: aborting due to 2 previous errors -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/error-codes/E0044.rs b/src/test/ui/error-codes/E0044.rs index 4d20edea5fe1..35e3c7685589 100644 --- a/src/test/ui/error-codes/E0044.rs +++ b/src/test/ui/error-codes/E0044.rs @@ -12,6 +12,7 @@ extern { fn sqrt(f: T) -> T; //~^ ERROR foreign items may not have type parameters [E0044] //~| HELP use specialization instead of type parameters by replacing them with concrete types + //~| NOTE can't have type parameters } fn main() { diff --git a/src/test/ui/error-codes/E0044.stderr b/src/test/ui/error-codes/E0044.stderr index 12324e771d3a..0e22818f789f 100644 --- a/src/test/ui/error-codes/E0044.stderr +++ b/src/test/ui/error-codes/E0044.stderr @@ -2,7 +2,7 @@ error[E0044]: foreign items may not have type parameters --> $DIR/E0044.rs:12:5 | LL | fn sqrt(f: T) -> T; - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ can't have type parameters | = help: use specialization instead of type parameters by replacing them with concrete types like `u32` From 4647156985404f07dc2e61eed6f2e24770b339a9 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 15 Mar 2018 12:35:56 +0800 Subject: [PATCH 230/830] replace `convert::Infallible` with `!` --- src/libcore/convert.rs | 21 +-------------------- src/libcore/num/mod.rs | 18 +++++------------- src/libstd/error.rs | 9 --------- 3 files changed, 6 insertions(+), 42 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index d3a83dc795c8..a45f1ceab5ab 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -48,25 +48,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use fmt; - -/// A type used as the error type for implementations of fallible conversion -/// traits in cases where conversions cannot actually fail. -/// -/// Because `Infallible` has no variants, a value of this type can never exist. -/// It is used only to satisfy trait signatures that expect an error type, and -/// signals to both the compiler and the user that the error case is impossible. -#[unstable(feature = "try_from", issue = "33417")] -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub enum Infallible {} - -#[unstable(feature = "try_from", issue = "33417")] -impl fmt::Display for Infallible { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - match *self { - } - } -} /// A cheap reference-to-reference conversion. Used to convert a value to a /// reference value within generic code. /// @@ -438,7 +419,7 @@ impl TryInto for T where U: TryFrom // with an uninhabited error type. #[unstable(feature = "try_from", issue = "33417")] impl TryFrom for T where T: From { - type Error = Infallible; + type Error = !; fn try_from(value: U) -> Result { Ok(T::from(value)) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 09ab7060d37d..faeb87cf944c 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -12,7 +12,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use convert::{Infallible, TryFrom}; +use convert::TryFrom; use fmt; use intrinsics; use ops; @@ -3595,20 +3595,12 @@ impl fmt::Display for TryFromIntError { } } -#[unstable(feature = "try_from", issue = "33417")] -impl From for TryFromIntError { - fn from(infallible: Infallible) -> TryFromIntError { - match infallible { - } - } -} - // no possible bounds violation macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( #[unstable(feature = "try_from", issue = "33417")] impl TryFrom<$source> for $target { - type Error = Infallible; + type Error = !; #[inline] fn try_from(value: $source) -> Result { @@ -3719,7 +3711,7 @@ try_from_lower_bounded!(isize, usize); #[cfg(target_pointer_width = "16")] mod ptr_try_from_impls { use super::TryFromIntError; - use convert::{Infallible, TryFrom}; + use convert::TryFrom; try_from_upper_bounded!(usize, u8); try_from_unbounded!(usize, u16, u32, u64, u128); @@ -3745,7 +3737,7 @@ mod ptr_try_from_impls { #[cfg(target_pointer_width = "32")] mod ptr_try_from_impls { use super::TryFromIntError; - use convert::{Infallible, TryFrom}; + use convert::TryFrom; try_from_upper_bounded!(usize, u8, u16); try_from_unbounded!(usize, u32, u64, u128); @@ -3771,7 +3763,7 @@ mod ptr_try_from_impls { #[cfg(target_pointer_width = "64")] mod ptr_try_from_impls { use super::TryFromIntError; - use convert::{Infallible, TryFrom}; + use convert::TryFrom; try_from_upper_bounded!(usize, u8, u16, u32); try_from_unbounded!(usize, u64, u128); diff --git a/src/libstd/error.rs b/src/libstd/error.rs index f8dbe193fed2..79bb6af168fa 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -56,7 +56,6 @@ use any::TypeId; use borrow::Cow; use cell; use char; -use convert; use core::array; use fmt::{self, Debug, Display}; use mem::transmute; @@ -371,14 +370,6 @@ impl Error for char::ParseCharError { } } -#[unstable(feature = "try_from", issue = "33417")] -impl Error for convert::Infallible { - fn description(&self) -> &str { - match *self { - } - } -} - // copied from any.rs impl Error + 'static { /// Returns true if the boxed type is the same as `T` From b5913f2e7695ad247078619bf4c6a6d3dc4dece5 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 28 Jan 2018 03:09:36 +0800 Subject: [PATCH 231/830] Stabilize `inclusive_range` library feature. Stabilize std::ops::RangeInclusive and std::ops::RangeInclusiveTo. --- src/liballoc/lib.rs | 1 - src/liballoc/range.rs | 4 ++-- src/liballoc/string.rs | 8 +++---- src/libcore/iter/range.rs | 12 ++++------ src/libcore/ops/mod.rs | 2 +- src/libcore/ops/range.rs | 24 +++++++------------ src/libcore/slice/mod.rs | 4 ++-- src/libcore/str/mod.rs | 24 +++++-------------- src/libcore/tests/lib.rs | 1 - src/librustc/lib.rs | 1 - src/librustc_mir/lib.rs | 1 - src/librustc_trans/lib.rs | 1 - src/libstd/lib.rs | 1 - src/test/compile-fail/range_inclusive_gate.rs | 21 ---------------- src/test/compile-fail/range_traits-1.rs | 2 -- src/test/compile-fail/range_traits-6.rs | 2 -- src/test/compile-fail/range_traits-7.rs | 2 +- src/test/parse-fail/range_inclusive.rs | 2 +- .../parse-fail/range_inclusive_dotdotdot.rs | 2 +- src/test/parse-fail/range_inclusive_gate.rs | 2 +- src/test/run-pass/range_inclusive.rs | 2 +- 21 files changed, 33 insertions(+), 86 deletions(-) delete mode 100644 src/test/compile-fail/range_inclusive_gate.rs diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 3f3067845588..cbfec5546049 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -98,7 +98,6 @@ #![feature(fundamental)] #![feature(generic_param_attrs)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(iter_rfold)] #![feature(lang_items)] #![feature(needs_allocator)] diff --git a/src/liballoc/range.rs b/src/liballoc/range.rs index f862da0d61e0..b03abc851808 100644 --- a/src/liballoc/range.rs +++ b/src/liballoc/range.rs @@ -103,7 +103,7 @@ impl RangeArgument for Range { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl RangeArgument for RangeInclusive { fn start(&self) -> Bound<&T> { Included(&self.start) @@ -113,7 +113,7 @@ impl RangeArgument for RangeInclusive { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl RangeArgument for RangeToInclusive { fn start(&self) -> Bound<&T> { Unbounded diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 370fb6b4e890..185fb61ae9e1 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1876,7 +1876,7 @@ impl ops::Index for String { unsafe { str::from_utf8_unchecked(&self.vec) } } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for String { type Output = str; @@ -1885,7 +1885,7 @@ impl ops::Index> for String { Index::index(&**self, index) } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for String { type Output = str; @@ -1923,14 +1923,14 @@ impl ops::IndexMut for String { unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) } } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for String { #[inline] fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut str { IndexMut::index_mut(&mut **self, index) } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for String { #[inline] fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut str { diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 9a3fd215dcfe..8d1080bb876e 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -186,9 +186,7 @@ macro_rules! range_exact_iter_impl { macro_rules! range_incl_exact_iter_impl { ($($t:ty)*) => ($( - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ExactSizeIterator for ops::RangeInclusive<$t> { } )*) } @@ -202,9 +200,7 @@ macro_rules! range_trusted_len_impl { macro_rules! range_incl_trusted_len_impl { ($($t:ty)*) => ($( - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] unsafe impl TrustedLen for ops::RangeInclusive<$t> { } )*) } @@ -328,7 +324,7 @@ impl FusedIterator for ops::RangeFrom {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for ops::RangeFrom {} -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl Iterator for ops::RangeInclusive { type Item = A; @@ -422,7 +418,7 @@ impl Iterator for ops::RangeInclusive { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl DoubleEndedIterator for ops::RangeInclusive { #[inline] fn next_back(&mut self) -> Option { diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs index 70ef4487334c..234970a81faf 100644 --- a/src/libcore/ops/mod.rs +++ b/src/libcore/ops/mod.rs @@ -191,7 +191,7 @@ pub use self::index::{Index, IndexMut}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::range::{Range, RangeFrom, RangeFull, RangeTo}; -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] pub use self::range::{RangeInclusive, RangeToInclusive}; #[unstable(feature = "try_trait", issue = "42327")] diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 1d9c0f873b34..9bdd8094f618 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -283,7 +283,7 @@ impl> RangeTo { /// # Examples /// /// ``` -/// #![feature(inclusive_range,inclusive_range_syntax)] +/// #![feature(inclusive_range_syntax)] /// /// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); @@ -293,21 +293,17 @@ impl> RangeTo { /// assert_eq!(arr[1..=2], [ 1,2 ]); // RangeInclusive /// ``` #[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { /// The lower bound of the range (inclusive). - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] pub start: Idx, /// The upper bound of the range (inclusive). - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] pub end: Idx, } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl fmt::Debug for RangeInclusive { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{:?}..={:?}", self.start, self.end) @@ -385,7 +381,7 @@ impl> RangeInclusive { /// The `..=end` syntax is a `RangeToInclusive`: /// /// ``` -/// #![feature(inclusive_range,inclusive_range_syntax)] +/// #![feature(inclusive_range_syntax)] /// assert_eq!((..=5), std::ops::RangeToInclusive{ end: 5 }); /// ``` /// @@ -417,16 +413,14 @@ impl> RangeInclusive { /// [`Iterator`]: ../iter/trait.IntoIterator.html /// [slicing index]: ../slice/trait.SliceIndex.html #[derive(Copy, Clone, PartialEq, Eq, Hash)] -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeToInclusive { /// The upper bound of the range (inclusive) - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] pub end: Idx, } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl fmt::Debug for RangeToInclusive { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "..={:?}", self.end) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 19fe4dd36b68..0f1b7cb8fcc0 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1039,7 +1039,7 @@ impl SliceIndex<[T]> for ops::RangeFull { } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<[T]> for ops::RangeInclusive { type Output = [T]; @@ -1080,7 +1080,7 @@ impl SliceIndex<[T]> for ops::RangeInclusive { } } -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +#[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex<[T]> for ops::RangeToInclusive { type Output = [T]; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index e225c9522bc0..9cf862bd9362 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1779,9 +1779,7 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for str { type Output = str; @@ -1791,9 +1789,7 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::Index> for str { type Output = str; @@ -1803,18 +1799,14 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for str { #[inline] fn index_mut(&mut self, index: ops::RangeInclusive) -> &mut str { index.index_mut(self) } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl ops::IndexMut> for str { #[inline] fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut str { @@ -1997,9 +1989,7 @@ mod traits { } } - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex for ops::RangeInclusive { type Output = str; #[inline] @@ -2042,9 +2032,7 @@ mod traits { - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] + #[stable(feature = "inclusive_range", since = "1.26.0")] impl SliceIndex for ops::RangeToInclusive { type Output = str; #[inline] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 5bd5bca19c4e..8f01fbeb30e4 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -23,7 +23,6 @@ #![feature(fmt_internals)] #![feature(iterator_step_by)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![feature(iterator_try_fold)] #![feature(iterator_flatten)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 51882385b2ef..149ea96b636c 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -54,7 +54,6 @@ #![feature(fs_read_write)] #![feature(i128)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![cfg_attr(windows, feature(libc))] #![feature(match_default_bindings)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 5510e2197806..31eb203eefe3 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -29,7 +29,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(fs_read_write)] #![feature(i128_type)] #![feature(inclusive_range_syntax)] -#![feature(inclusive_range)] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 39eb38658fee..a9334461825c 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -26,7 +26,6 @@ #![allow(unused_attributes)] #![feature(i128_type)] #![feature(i128)] -#![feature(inclusive_range)] #![feature(inclusive_range_syntax)] #![feature(libc)] #![feature(quote)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index eea0e6b67527..c71a562b0d15 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -271,7 +271,6 @@ #![feature(heap_api)] #![feature(i128)] #![feature(i128_type)] -#![feature(inclusive_range)] #![feature(int_error_internals)] #![feature(integer_atomics)] #![feature(into_cow)] diff --git a/src/test/compile-fail/range_inclusive_gate.rs b/src/test/compile-fail/range_inclusive_gate.rs deleted file mode 100644 index 5b063dc1137c..000000000000 --- a/src/test/compile-fail/range_inclusive_gate.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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. - -// Make sure that #![feature(inclusive_range)] is required. - -#![feature(inclusive_range_syntax)] -// #![feature(inclusive_range)] - -pub fn main() { - let _: std::ops::RangeInclusive<_> = { use std::intrinsics; 1 } ..= { use std::intrinsics; 2 }; - //~^ ERROR use of unstable library feature 'inclusive_range' - //~| ERROR core_intrinsics - //~| ERROR core_intrinsics -} diff --git a/src/test/compile-fail/range_traits-1.rs b/src/test/compile-fail/range_traits-1.rs index f1ea8b04e5ac..7645dbb1a6de 100644 --- a/src/test/compile-fail/range_traits-1.rs +++ b/src/test/compile-fail/range_traits-1.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(inclusive_range)] - use std::ops::*; #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] diff --git a/src/test/compile-fail/range_traits-6.rs b/src/test/compile-fail/range_traits-6.rs index 7c62711feaee..f9510b5061ca 100644 --- a/src/test/compile-fail/range_traits-6.rs +++ b/src/test/compile-fail/range_traits-6.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(inclusive_range)] - use std::ops::*; #[derive(Copy, Clone)] //~ ERROR Copy diff --git a/src/test/compile-fail/range_traits-7.rs b/src/test/compile-fail/range_traits-7.rs index b6fec773a777..871b55b85cf8 100644 --- a/src/test/compile-fail/range_traits-7.rs +++ b/src/test/compile-fail/range_traits-7.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(rustc_attrs, inclusive_range)] +#![feature(rustc_attrs)] use std::ops::*; diff --git a/src/test/parse-fail/range_inclusive.rs b/src/test/parse-fail/range_inclusive.rs index cc32b9903b5a..6c6caa1e6497 100644 --- a/src/test/parse-fail/range_inclusive.rs +++ b/src/test/parse-fail/range_inclusive.rs @@ -10,7 +10,7 @@ // Make sure that inclusive ranges with no end point don't parse. -#![feature(inclusive_range_syntax, inclusive_range)] +#![feature(inclusive_range_syntax)] pub fn main() { for _ in 1..= {} //~ERROR inclusive range with no end diff --git a/src/test/parse-fail/range_inclusive_dotdotdot.rs b/src/test/parse-fail/range_inclusive_dotdotdot.rs index a4c36a2f0ba8..8a24038638b3 100644 --- a/src/test/parse-fail/range_inclusive_dotdotdot.rs +++ b/src/test/parse-fail/range_inclusive_dotdotdot.rs @@ -12,7 +12,7 @@ // Make sure that inclusive ranges with `...` syntax don't parse. -#![feature(inclusive_range_syntax, inclusive_range)] +#![feature(inclusive_range_syntax)] use std::ops::RangeToInclusive; diff --git a/src/test/parse-fail/range_inclusive_gate.rs b/src/test/parse-fail/range_inclusive_gate.rs index 6b6afc504e15..c8c84000e41e 100644 --- a/src/test/parse-fail/range_inclusive_gate.rs +++ b/src/test/parse-fail/range_inclusive_gate.rs @@ -12,7 +12,7 @@ // Make sure that #![feature(inclusive_range_syntax)] is required. -// #![feature(inclusive_range_syntax, inclusive_range)] +// #![feature(inclusive_range_syntax)] macro_rules! m { () => { for _ in 1..=10 {} } //~ ERROR inclusive range syntax is experimental diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs index 71e11804052d..29947860ff6a 100644 --- a/src/test/run-pass/range_inclusive.rs +++ b/src/test/run-pass/range_inclusive.rs @@ -10,7 +10,7 @@ // Test inclusive range syntax. -#![feature(inclusive_range_syntax, inclusive_range, iterator_step_by)] +#![feature(inclusive_range_syntax, iterator_step_by)] use std::ops::{RangeInclusive, RangeToInclusive}; From 92d1f8d8e4be62e6f4dc32bc57f9d44f53117ec9 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 28 Jan 2018 03:19:29 +0800 Subject: [PATCH 232/830] Stabilize `inclusive_range_syntax` language feature. Stabilize the syntax `a..=b` and `..=b`. --- .../inclusive-range-syntax.md | 20 ----- src/liballoc/tests/lib.rs | 2 +- src/libcore/lib.rs | 2 +- src/libcore/ops/range.rs | 19 ++--- src/libcore/tests/lib.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc_incremental/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_trans/lib.rs | 2 +- src/libsyntax/diagnostic_list.rs | 4 - src/libsyntax/feature_gate.rs | 10 +-- .../hashes/indexing_expressions.rs | 1 - src/test/parse-fail/range_inclusive.rs | 2 - .../parse-fail/range_inclusive_dotdotdot.rs | 2 - src/test/parse-fail/range_inclusive_gate.rs | 74 ------------------- src/test/run-pass/range_inclusive.rs | 2 +- src/test/run-pass/range_inclusive_gate.rs | 3 +- src/test/ui/impossible_range.rs | 2 - src/test/ui/impossible_range.stderr | 4 +- 19 files changed, 19 insertions(+), 138 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/inclusive-range-syntax.md delete mode 100644 src/test/parse-fail/range_inclusive_gate.rs diff --git a/src/doc/unstable-book/src/language-features/inclusive-range-syntax.md b/src/doc/unstable-book/src/language-features/inclusive-range-syntax.md deleted file mode 100644 index 56f58803150c..000000000000 --- a/src/doc/unstable-book/src/language-features/inclusive-range-syntax.md +++ /dev/null @@ -1,20 +0,0 @@ -# `inclusive_range_syntax` - -The tracking issue for this feature is: [#28237] - -[#28237]: https://github.com/rust-lang/rust/issues/28237 - ------------------------- - -To get a range that goes from 0 to 10 and includes the value 10, you -can write `0..=10`: - -```rust -#![feature(inclusive_range_syntax)] - -fn main() { - for i in 0..=10 { - println!("{}", i); - } -} -``` diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 168dbb2ce9b1..f5deecd47e8e 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -14,7 +14,7 @@ #![feature(alloc_system)] #![feature(attr_literals)] #![feature(box_syntax)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(collection_placement)] #![feature(const_fn)] #![feature(drain_filter)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a947c9f0b7c1..9aebe2e4ee4b 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -79,7 +79,7 @@ #![feature(fn_must_use)] #![feature(fundamental)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(intrinsics)] #![feature(iterator_flatten)] #![feature(iterator_repeat_with)] diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 9bdd8094f618..32aa6508805b 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -128,7 +128,7 @@ impl> Range { /// The range is empty if either side is incomparable: /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// use std::f32::NAN; /// assert!(!(3.0..5.0).is_empty()); @@ -283,8 +283,6 @@ impl> RangeTo { /// # Examples /// /// ``` -/// #![feature(inclusive_range_syntax)] -/// /// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); /// @@ -316,7 +314,7 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains,inclusive_range_syntax)] + /// #![feature(range_contains)] /// /// assert!(!(3..=5).contains(2)); /// assert!( (3..=5).contains(3)); @@ -337,7 +335,7 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// assert!(!(3..=5).is_empty()); /// assert!(!(3..=3).is_empty()); @@ -347,7 +345,7 @@ impl> RangeInclusive { /// The range is empty if either side is incomparable: /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// use std::f32::NAN; /// assert!(!(3.0..=5.0).is_empty()); @@ -358,7 +356,7 @@ impl> RangeInclusive { /// This method returns `true` after iteration has finished: /// /// ``` - /// #![feature(range_is_empty,inclusive_range_syntax)] + /// #![feature(range_is_empty)] /// /// let mut r = 3..=5; /// for _ in r.by_ref() {} @@ -381,7 +379,6 @@ impl> RangeInclusive { /// The `..=end` syntax is a `RangeToInclusive`: /// /// ``` -/// #![feature(inclusive_range_syntax)] /// assert_eq!((..=5), std::ops::RangeToInclusive{ end: 5 }); /// ``` /// @@ -389,8 +386,6 @@ impl> RangeInclusive { /// `for` loop directly. This won't compile: /// /// ```compile_fail,E0277 -/// #![feature(inclusive_range_syntax)] -/// /// // error[E0277]: the trait bound `std::ops::RangeToInclusive<{integer}>: /// // std::iter::Iterator` is not satisfied /// for i in ..=5 { @@ -402,8 +397,6 @@ impl> RangeInclusive { /// array elements up to and including the index indicated by `end`. /// /// ``` -/// #![feature(inclusive_range_syntax)] -/// /// let arr = [0, 1, 2, 3]; /// assert_eq!(arr[ ..=2], [0,1,2 ]); // RangeToInclusive /// assert_eq!(arr[1..=2], [ 1,2 ]); @@ -434,7 +427,7 @@ impl> RangeToInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains,inclusive_range_syntax)] + /// #![feature(range_contains)] /// /// assert!( (..=5).contains(-1_000_000_000)); /// assert!( (..=5).contains(5)); diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8f01fbeb30e4..85787f38f060 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -23,7 +23,7 @@ #![feature(fmt_internals)] #![feature(iterator_step_by)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(iterator_try_fold)] #![feature(iterator_flatten)] #![feature(conservative_impl_trait)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 149ea96b636c..ff2e8ea79d3b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -54,7 +54,7 @@ #![feature(fs_read_write)] #![feature(i128)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![cfg_attr(windows, feature(libc))] #![feature(match_default_bindings)] #![feature(macro_lifetime_matcher)] diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 65fbd9d0bf8f..d7ccf9d5562e 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -18,7 +18,7 @@ #![feature(conservative_impl_trait)] #![feature(fs_read_write)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(specialization)] extern crate graphviz; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 31eb203eefe3..ad7a5c94022f 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -28,7 +28,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(dyn_trait)] #![feature(fs_read_write)] #![feature(i128_type)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index a9334461825c..f2b76eb57d66 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -26,7 +26,7 @@ #![allow(unused_attributes)] #![feature(i128_type)] #![feature(i128)] -#![feature(inclusive_range_syntax)] +#![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(libc)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 549ef88afcc6..1f87c1b94c50 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -218,8 +218,6 @@ An inclusive range was used with no end. Erroneous code example: ```compile_fail,E0586 -#![feature(inclusive_range_syntax)] - fn main() { let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1]; let x = &tmp[1..=]; // error: inclusive range was used with no end @@ -239,8 +237,6 @@ fn main() { Or put an end to your inclusive range: ``` -#![feature(inclusive_range_syntax)] - fn main() { let tmp = vec![0, 1, 2, 3, 4, 4, 3, 3, 2, 1]; let x = &tmp[1..=3]; // ok! diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 91364fe6ed48..a415117b599b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -268,9 +268,6 @@ declare_features! ( // rustc internal (active, abi_vectorcall, "1.7.0", None, None), - // a..=b and ..=b - (active, inclusive_range_syntax, "1.7.0", Some(28237), None), - // X..Y patterns (active, exclusive_range_pattern, "1.11.0", Some(37854), None), @@ -554,6 +551,8 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), + // a..=b and ..=b + (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1592,11 +1591,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, type_ascription, e.span, "type ascription is experimental"); } - ast::ExprKind::Range(_, _, ast::RangeLimits::Closed) => { - gate_feature_post!(&self, inclusive_range_syntax, - e.span, - "inclusive range syntax is experimental"); - } ast::ExprKind::InPlace(..) => { gate_feature_post!(&self, placement_in_syntax, e.span, EXPLAIN_PLACEMENT_IN); } diff --git a/src/test/incremental/hashes/indexing_expressions.rs b/src/test/incremental/hashes/indexing_expressions.rs index e66e239b33c9..fb63aa857aa3 100644 --- a/src/test/incremental/hashes/indexing_expressions.rs +++ b/src/test/incremental/hashes/indexing_expressions.rs @@ -23,7 +23,6 @@ #![allow(warnings)] #![feature(rustc_attrs)] #![crate_type="rlib"] -#![feature(inclusive_range_syntax)] // Change simple index --------------------------------------------------------- #[cfg(cfail1)] diff --git a/src/test/parse-fail/range_inclusive.rs b/src/test/parse-fail/range_inclusive.rs index 6c6caa1e6497..2aa7d6d6cd79 100644 --- a/src/test/parse-fail/range_inclusive.rs +++ b/src/test/parse-fail/range_inclusive.rs @@ -10,8 +10,6 @@ // Make sure that inclusive ranges with no end point don't parse. -#![feature(inclusive_range_syntax)] - pub fn main() { for _ in 1..= {} //~ERROR inclusive range with no end //~^HELP bounded at the end diff --git a/src/test/parse-fail/range_inclusive_dotdotdot.rs b/src/test/parse-fail/range_inclusive_dotdotdot.rs index 8a24038638b3..fa6474717d3f 100644 --- a/src/test/parse-fail/range_inclusive_dotdotdot.rs +++ b/src/test/parse-fail/range_inclusive_dotdotdot.rs @@ -12,8 +12,6 @@ // Make sure that inclusive ranges with `...` syntax don't parse. -#![feature(inclusive_range_syntax)] - use std::ops::RangeToInclusive; fn return_range_to() -> RangeToInclusive { diff --git a/src/test/parse-fail/range_inclusive_gate.rs b/src/test/parse-fail/range_inclusive_gate.rs deleted file mode 100644 index c8c84000e41e..000000000000 --- a/src/test/parse-fail/range_inclusive_gate.rs +++ /dev/null @@ -1,74 +0,0 @@ -// 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. - -// gate-test-inclusive_range_syntax - -// Make sure that #![feature(inclusive_range_syntax)] is required. - -// #![feature(inclusive_range_syntax)] - -macro_rules! m { - () => { for _ in 1..=10 {} } //~ ERROR inclusive range syntax is experimental -} - -#[cfg(nope)] -fn f() {} -#[cfg(not(nope))] -fn f() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental -} - -#[cfg(nope)] -macro_rules! n { () => {} } -#[cfg(not(nope))] -macro_rules! n { - () => { for _ in 1..=10 {} } //~ ERROR inclusive range syntax is experimental -} - -macro_rules! o { - () => {{ - #[cfg(nope)] - fn g() {} - #[cfg(not(nope))] - fn g() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental - } - - g(); - }} -} - -#[cfg(nope)] -macro_rules! p { () => {} } -#[cfg(not(nope))] -macro_rules! p { - () => {{ - #[cfg(nope)] - fn h() {} - #[cfg(not(nope))] - fn h() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental - } - - h(); - }} -} - -pub fn main() { - for _ in 1..=10 {} //~ ERROR inclusive range syntax is experimental - for _ in ..=10 {} //~ ERROR inclusive range syntax is experimental - - f(); // not allowed in cfg'ed functions - - m!(); // not allowed in macros - n!(); // not allowed in cfg'ed macros - o!(); // not allowed in macros that output cfgs - p!(); // not allowed in cfg'ed macros that output cfgs -} diff --git a/src/test/run-pass/range_inclusive.rs b/src/test/run-pass/range_inclusive.rs index 29947860ff6a..5d46bfab8878 100644 --- a/src/test/run-pass/range_inclusive.rs +++ b/src/test/run-pass/range_inclusive.rs @@ -10,7 +10,7 @@ // Test inclusive range syntax. -#![feature(inclusive_range_syntax, iterator_step_by)] +#![feature(iterator_step_by)] use std::ops::{RangeInclusive, RangeToInclusive}; diff --git a/src/test/run-pass/range_inclusive_gate.rs b/src/test/run-pass/range_inclusive_gate.rs index 570087aedbba..6c2731fa5a9b 100644 --- a/src/test/run-pass/range_inclusive_gate.rs +++ b/src/test/run-pass/range_inclusive_gate.rs @@ -9,8 +9,7 @@ // except according to those terms. // Test that you only need the syntax gate if you don't mention the structs. - -#![feature(inclusive_range_syntax)] +// (Obsoleted since both features are stabilized) fn main() { let mut count = 0; diff --git a/src/test/ui/impossible_range.rs b/src/test/ui/impossible_range.rs index 5c72c506e6bf..073ed867bdb8 100644 --- a/src/test/ui/impossible_range.rs +++ b/src/test/ui/impossible_range.rs @@ -10,8 +10,6 @@ // Make sure that invalid ranges generate an error during HIR lowering, not an ICE -#![feature(inclusive_range_syntax)] - pub fn main() { ..; 0..; diff --git a/src/test/ui/impossible_range.stderr b/src/test/ui/impossible_range.stderr index d941b522defe..cfeaa53a6bb1 100644 --- a/src/test/ui/impossible_range.stderr +++ b/src/test/ui/impossible_range.stderr @@ -1,5 +1,5 @@ error[E0586]: inclusive range with no end - --> $DIR/impossible_range.rs:20:8 + --> $DIR/impossible_range.rs:18:8 | LL | ..=; //~ERROR inclusive range with no end | ^ @@ -7,7 +7,7 @@ LL | ..=; //~ERROR inclusive range with no end = help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`) error[E0586]: inclusive range with no end - --> $DIR/impossible_range.rs:27:9 + --> $DIR/impossible_range.rs:25:9 | LL | 0..=; //~ERROR inclusive range with no end | ^ From a4d80336c96d7f47b0ef025fa141a9c96abcafbd Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 28 Jan 2018 03:29:00 +0800 Subject: [PATCH 233/830] Stabilize `dotdoteq_in_patterns` language feature. Stabilize `match 2 { 1..=3 => {} }`. --- src/libsyntax/feature_gate.rs | 11 +++-------- src/test/run-pass/inc-range-pat.rs | 2 -- src/test/ui/feature-gate-dotdoteq_in_patterns.rs | 16 ---------------- .../ui/feature-gate-dotdoteq_in_patterns.stderr | 11 ----------- 4 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 src/test/ui/feature-gate-dotdoteq_in_patterns.rs delete mode 100644 src/test/ui/feature-gate-dotdoteq_in_patterns.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a415117b599b..51fa14895993 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -26,7 +26,7 @@ use self::AttributeType::*; use self::AttributeGate::*; use abi::Abi; -use ast::{self, NodeId, PatKind, RangeEnd, RangeSyntax}; +use ast::{self, NodeId, PatKind, RangeEnd}; use attr; use epoch::Epoch; use codemap::Spanned; @@ -399,9 +399,6 @@ declare_features! ( // allow `'_` placeholder lifetimes (active, underscore_lifetimes, "1.22.0", Some(44524), None), - // allow `..=` in patterns (RFC 1192) - (active, dotdoteq_in_patterns, "1.22.0", Some(28237), None), - // Default match binding modes (RFC 2005) (active, match_default_bindings, "1.22.0", Some(42640), None), @@ -553,6 +550,8 @@ declare_features! ( (accepted, use_nested_groups, "1.25.0", Some(44494), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), + // allow `..=` in patterns (RFC 1192) + (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1652,10 +1651,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, exclusive_range_pattern, pattern.span, "exclusive range pattern syntax is experimental"); } - PatKind::Range(_, _, RangeEnd::Included(RangeSyntax::DotDotEq)) => { - gate_feature_post!(&self, dotdoteq_in_patterns, pattern.span, - "`..=` syntax in patterns is experimental"); - } PatKind::Paren(..) => { gate_feature_post!(&self, pattern_parentheses, pattern.span, "parentheses in patterns are unstable"); diff --git a/src/test/run-pass/inc-range-pat.rs b/src/test/run-pass/inc-range-pat.rs index 5faf36eddaf0..237b41b6128c 100644 --- a/src/test/run-pass/inc-range-pat.rs +++ b/src/test/run-pass/inc-range-pat.rs @@ -9,8 +9,6 @@ // except according to those terms. // Test old and new syntax for inclusive range patterns. -#![feature(dotdoteq_in_patterns)] - fn main() { assert!(match 42 { 0 ... 100 => true, _ => false }); diff --git a/src/test/ui/feature-gate-dotdoteq_in_patterns.rs b/src/test/ui/feature-gate-dotdoteq_in_patterns.rs deleted file mode 100644 index 1fb139bf07f4..000000000000 --- a/src/test/ui/feature-gate-dotdoteq_in_patterns.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2014 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. - -pub fn main() { - match 22 { - 0 ..= 3 => {} //~ ERROR `..=` syntax in patterns is experimental - _ => {} - } -} diff --git a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr b/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr deleted file mode 100644 index 67f15be9d084..000000000000 --- a/src/test/ui/feature-gate-dotdoteq_in_patterns.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: `..=` syntax in patterns is experimental (see issue #28237) - --> $DIR/feature-gate-dotdoteq_in_patterns.rs:13:9 - | -LL | 0 ..= 3 => {} //~ ERROR `..=` syntax in patterns is experimental - | ^^^^^^^ - | - = help: add #![feature(dotdoteq_in_patterns)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. From 6399d16cfde37b06f6b82cdafa623e36385d7252 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sat, 3 Mar 2018 06:05:54 +0800 Subject: [PATCH 234/830] Disallow &a..=b and box a..=b in pattern. They are disallowed because they have different precedence than expressions. I assume parenthesis in pattern will be soon stabilized and thus write that as suggestion directly. --- src/librustc/hir/print.rs | 20 ++++++++++ src/libsyntax/parse/parser.rs | 29 +++++++++++++- .../range-inclusive-pattern-precedence.rs | 32 ++++++++++++++++ .../ui/range-inclusive-pattern-precedence.rs | 38 +++++++++++++++++++ .../range-inclusive-pattern-precedence.stderr | 14 +++++++ 5 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/range-inclusive-pattern-precedence.rs create mode 100644 src/test/ui/range-inclusive-pattern-precedence.rs create mode 100644 src/test/ui/range-inclusive-pattern-precedence.stderr diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index d91aa3a38519..9e755f366a7d 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1810,15 +1810,35 @@ impl<'a> State<'a> { self.pclose()?; } PatKind::Box(ref inner) => { + let is_range_inner = match inner.node { + PatKind::Range(..) => true, + _ => false, + }; self.s.word("box ")?; + if is_range_inner { + self.popen()?; + } self.print_pat(&inner)?; + if is_range_inner { + self.pclose()?; + } } PatKind::Ref(ref inner, mutbl) => { + let is_range_inner = match inner.node { + PatKind::Range(..) => true, + _ => false, + }; self.s.word("&")?; if mutbl == hir::MutMutable { self.s.word("mut ")?; } + if is_range_inner { + self.popen()?; + } self.print_pat(&inner)?; + if is_range_inner { + self.pclose()?; + } } PatKind::Lit(ref e) => self.print_expr(&e)?, PatKind::Range(ref begin, ref end, ref end_kind) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bd0ca0e67048..e3812ce159a9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3804,6 +3804,12 @@ impl<'a> Parser<'a> { /// Parse a pattern. pub fn parse_pat(&mut self) -> PResult<'a, P> { + self.parse_pat_with_range_pat(true) + } + + /// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are + /// allowed. + fn parse_pat_with_range_pat(&mut self, allow_range_pat: bool) -> PResult<'a, P> { maybe_whole!(self, NtPat, |x| x); let lo = self.span; @@ -3824,7 +3830,7 @@ impl<'a> Parser<'a> { err.span_label(self.span, "unexpected lifetime"); return Err(err); } - let subpat = self.parse_pat()?; + let subpat = self.parse_pat_with_range_pat(false)?; pat = PatKind::Ref(subpat, mutbl); } token::OpenDelim(token::Paren) => { @@ -3863,7 +3869,7 @@ impl<'a> Parser<'a> { pat = self.parse_pat_ident(BindingMode::ByRef(mutbl))?; } else if self.eat_keyword(keywords::Box) { // Parse box pat - let subpat = self.parse_pat()?; + let subpat = self.parse_pat_with_range_pat(false)?; pat = PatKind::Box(subpat); } else if self.token.is_ident() && !self.token.is_reserved_ident() && self.parse_as_ident() { @@ -3968,6 +3974,25 @@ impl<'a> Parser<'a> { let pat = Pat { node: pat, span: lo.to(self.prev_span), id: ast::DUMMY_NODE_ID }; let pat = self.maybe_recover_from_bad_qpath(pat, true)?; + if !allow_range_pat { + match pat.node { + PatKind::Range(_, _, RangeEnd::Included(RangeSyntax::DotDotDot)) => {} + PatKind::Range(..) => { + let mut err = self.struct_span_err( + pat.span, + "the range pattern here has ambiguous interpretation", + ); + err.span_suggestion( + pat.span, + "add parentheses to clarify the precedence", + format!("({})", pprust::pat_to_string(&pat)), + ); + return Err(err); + } + _ => {} + } + } + Ok(P(pat)) } diff --git a/src/test/run-pass/range-inclusive-pattern-precedence.rs b/src/test/run-pass/range-inclusive-pattern-precedence.rs new file mode 100644 index 000000000000..5e491d48bcf4 --- /dev/null +++ b/src/test/run-pass/range-inclusive-pattern-precedence.rs @@ -0,0 +1,32 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(box_patterns, pattern_parentheses)] + +const VALUE: usize = 21; + +pub fn main() { + match &18 { + &(18..=18) => {} + _ => { unreachable!(); } + } + match &21 { + &(VALUE..=VALUE) => {} + _ => { unreachable!(); } + } + match Box::new(18) { + box (18..=18) => {} + _ => { unreachable!(); } + } + match Box::new(21) { + box (VALUE..=VALUE) => {} + _ => { unreachable!(); } + } +} diff --git a/src/test/ui/range-inclusive-pattern-precedence.rs b/src/test/ui/range-inclusive-pattern-precedence.rs new file mode 100644 index 000000000000..67a0f79ca6b8 --- /dev/null +++ b/src/test/ui/range-inclusive-pattern-precedence.rs @@ -0,0 +1,38 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// In expression, `&a..=b` is treated as `(&a)..=(b)` and `box a..=b` is +// `(box a)..=(b)`. In a pattern, however, `&a..=b` means `&(a..=b)`. This may +// lead to confusion. +// +// We are going to disallow `&a..=b` and `box a..=b` in a pattern. However, the +// older ... syntax is still allowed as a stability guarantee. + +#![feature(box_patterns)] + +pub fn main() { + match &12 { + &0...9 => {} + &10..=15 => {} + //~^ ERROR the range pattern here has ambiguous interpretation + //~^^ HELP add parentheses to clarify the precedence + &(16..=20) => {} + _ => {} + } + + match Box::new(12) { + box 0...9 => {} + box 10..=15 => {} + //~^ ERROR the range pattern here has ambiguous interpretation + //~^^ HELP add parentheses to clarify the precedence + box (16..=20) => {} + _ => {} + } +} diff --git a/src/test/ui/range-inclusive-pattern-precedence.stderr b/src/test/ui/range-inclusive-pattern-precedence.stderr new file mode 100644 index 000000000000..99e0d739036b --- /dev/null +++ b/src/test/ui/range-inclusive-pattern-precedence.stderr @@ -0,0 +1,14 @@ +error: the range pattern here has ambiguous interpretation + --> $DIR/range-inclusive-pattern-precedence.rs:23:10 + | +LL | &10..=15 => {} + | ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)` + +error: the range pattern here has ambiguous interpretation + --> $DIR/range-inclusive-pattern-precedence.rs:32:13 + | +LL | box 10..=15 => {} + | ^^^^^^^ help: add parentheses to clarify the precedence: `(10 ..=15)` + +error: aborting due to 2 previous errors + From 939cfa251aeb34b4b1a11396af1a3396792c708d Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 15 Mar 2018 02:50:55 +0800 Subject: [PATCH 235/830] Keep the fields of RangeInclusive unstable. --- src/liballoc/lib.rs | 1 + src/liballoc/tests/lib.rs | 1 + src/libcore/ops/range.rs | 6 ++++-- src/libcore/tests/lib.rs | 1 + src/librustc/lib.rs | 1 + src/librustc_mir/lib.rs | 1 + src/librustc_trans/lib.rs | 1 + 7 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index cbfec5546049..fb7f114ba1a4 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -123,6 +123,7 @@ #![feature(on_unimplemented)] #![feature(exact_chunks)] #![feature(pointer_methods)] +#![feature(inclusive_range_fields)] #![cfg_attr(not(test), feature(fn_traits, placement_new_protocol, swap_with_slice, i128))] #![cfg_attr(test, feature(test, box_heap))] diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index f5deecd47e8e..4fea2375558d 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -29,6 +29,7 @@ #![feature(unboxed_closures)] #![feature(unicode)] #![feature(exact_chunks)] +#![feature(inclusive_range_fields)] extern crate alloc_system; extern crate std_unicode; diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 32aa6508805b..be51f5239b0c 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -283,6 +283,8 @@ impl> RangeTo { /// # Examples /// /// ``` +/// #![feature(inclusive_range_fields)] +/// /// assert_eq!((3..=5), std::ops::RangeInclusive { start: 3, end: 5 }); /// assert_eq!(3 + 4 + 5, (3..=5).sum()); /// @@ -294,10 +296,10 @@ impl> RangeTo { #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { /// The lower bound of the range (inclusive). - #[stable(feature = "inclusive_range", since = "1.26.0")] + #[unstable(feature = "inclusive_range_fields", issue = "49022")] pub start: Idx, /// The upper bound of the range (inclusive). - #[stable(feature = "inclusive_range", since = "1.26.0")] + #[unstable(feature = "inclusive_range_fields", issue = "49022")] pub end: Idx, } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 85787f38f060..e53964b5769b 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -47,6 +47,7 @@ #![feature(exact_chunks)] #![feature(atomic_nand)] #![feature(reverse_bits)] +#![feature(inclusive_range_fields)] extern crate core; extern crate test; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index ff2e8ea79d3b..77259f156e5e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -75,6 +75,7 @@ #![feature(trusted_len)] #![feature(catch_expr)] #![feature(test)] +#![feature(inclusive_range_fields)] #![recursion_limit="512"] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index ad7a5c94022f..ff35412ea5ba 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -39,6 +39,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(nonzero)] #![feature(underscore_lifetimes)] #![cfg_attr(stage0, feature(never_type))] +#![feature(inclusive_range_fields)] extern crate arena; #[macro_use] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index f2b76eb57d66..9b09dbf52761 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -33,6 +33,7 @@ #![feature(slice_patterns)] #![feature(conservative_impl_trait)] #![feature(optin_builtin_traits)] +#![feature(inclusive_range_fields)] use rustc::dep_graph::WorkProduct; use syntax_pos::symbol::Symbol; From 3125a307596db12d8b014da330373446dda5d7ca Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 15 Mar 2018 10:08:22 +0100 Subject: [PATCH 236/830] error on vector reduction usage if LLVM version is < 5.0 --- src/rustllvm/RustWrapper.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index c647218c1aca..cd3ae1e743bf 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -21,6 +21,8 @@ #if LLVM_VERSION_GE(5, 0) #include "llvm/ADT/Optional.h" +#else +#include #endif //===----------------------------------------------------------------------=== @@ -1397,7 +1399,7 @@ LLVMRustModuleCost(LLVMModuleRef M) { } // Vector reductions: -#if LLVM_VERSION_GE(6, 0) +#if LLVM_VERSION_GE(5, 0) extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Src) { return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc),unwrap(Src))); @@ -1445,48 +1447,65 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { #else +void error_and_exit(const char* msg) { + raw_fd_ostream OS(2, false); + OS << ::std::string(msg); + std::exit(EXIT_FAILURE); +} + extern "C" LLVMValueRef LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceFAdd requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceFMul requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceAdd requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceMul requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceAnd requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceOr requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef Src) { + error_and_exit("LLVMRustBuildVectorReduceXor requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceMin requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceMax requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceFMin requires LLVM >= 5.0"); return Src; } extern "C" LLVMValueRef LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef Src, bool) { + error_and_exit("LLVMRustBuildVectorReduceFMax requires LLVM >= 5.0"); return Src; } #endif From 8478fa2007a2d2a9de21d88ebed13f16b6330393 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 15 Mar 2018 10:10:16 +0100 Subject: [PATCH 237/830] add min-llvm version to reduction tests --- src/test/run-pass/simd-intrinsic-generic-reduction.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-pass/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd-intrinsic-generic-reduction.rs index 6755c92961b1..7355aba6c114 100644 --- a/src/test/run-pass/simd-intrinsic-generic-reduction.rs +++ b/src/test/run-pass/simd-intrinsic-generic-reduction.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// min-llvm-version 5.0 + // Test that the simd_reduce_{op} intrinsics produce the correct results. #![feature(repr_simd, platform_intrinsics)] From b6ec75fe62e2749841a91c0c4392653d49f10d6a Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 15 Mar 2018 17:59:17 +0800 Subject: [PATCH 238/830] Remove unnecessary "`" in error message E0307 (invalid self type). --- src/librustc_typeck/check/wfcheck.rs | 2 +- src/test/ui/span/issue-27522.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d10ee358e072..b94af0a1e008 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -525,7 +525,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { } else { fcx.tcx.sess.diagnostic().mut_span_err( span, &format!("invalid `self` type: {:?}", self_arg_ty)) - .note(&format!("type must be `{:?}` or a type that dereferences to it`", self_ty)) + .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty)) .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") .code(DiagnosticId::Error("E0307".into())) .emit(); diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr index d0611bd580fe..9b61ecae6512 100644 --- a/src/test/ui/span/issue-27522.stderr +++ b/src/test/ui/span/issue-27522.stderr @@ -4,7 +4,7 @@ error[E0307]: invalid `self` type: &SomeType LL | fn handler(self: &SomeType); //~ ERROR invalid `self` type | ^^^^^^^^^ | - = note: type must be `Self` or a type that dereferences to it` + = note: type must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box` error: aborting due to previous error From b41f2278f4fadd989dbbeb174ad6a4f55de25d99 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 13 Mar 2018 15:40:02 +0100 Subject: [PATCH 239/830] MonoItem collector: Cleanup start fn root collection. --- src/librustc_mir/monomorphize/collector.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 7fd2ea265de8..d43da5392ab8 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -341,6 +341,8 @@ fn collect_roots<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; tcx.hir.krate().visit_all_item_likes(&mut visitor); + + visitor.push_extra_entry_roots(); } // We can only translate items that are instantiable - items all of @@ -998,8 +1000,6 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { let instance = Instance::mono(self.tcx, def_id); self.output.push(create_fn_mono_item(instance)); - - self.push_extra_entry_roots(def_id); } } @@ -1008,20 +1008,22 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { /// monomorphized copy of the start lang item based on /// the return type of `main`. This is not needed when /// the user writes their own `start` manually. - fn push_extra_entry_roots(&mut self, def_id: DefId) { - if self.entry_fn != Some(def_id) { - return; + fn push_extra_entry_roots(&mut self) { + if self.tcx.sess.entry_type.get() != Some(config::EntryMain) { + return } - if self.tcx.sess.entry_type.get() != Some(config::EntryMain) { - return; - } + let main_def_id = if let Some(def_id) = self.entry_fn { + def_id + } else { + return + }; let start_def_id = match self.tcx.lang_items().require(StartFnLangItem) { Ok(s) => s, Err(err) => self.tcx.sess.fatal(&err), }; - let main_ret_ty = self.tcx.fn_sig(def_id).output(); + let main_ret_ty = self.tcx.fn_sig(main_def_id).output(); // Given that `main()` has no arguments, // then its return type cannot have From 5218c2d5efbb2907b279e627782e96896308d106 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 7 Mar 2018 15:24:50 +0100 Subject: [PATCH 240/830] Properly handle collecting default impls of methods with lifetime parameters. --- src/librustc_mir/monomorphize/collector.rs | 8 ++++-- src/test/compile-fail/issue-47309.rs | 31 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/issue-47309.rs diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index d43da5392ab8..446ef6bd3287 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1068,7 +1068,6 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id_to_string(tcx, impl_def_id)); if let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) { - let callee_substs = tcx.erase_regions(&trait_ref.substs); let overridden_methods: FxHashSet<_> = impl_item_refs.iter() .map(|iiref| iiref.name) @@ -1082,10 +1081,15 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, continue; } + let substs = Substs::for_item(tcx, + method.def_id, + |_, _| tcx.types.re_erased, + |def, _| trait_ref.substs.type_for_def(def)); + let instance = ty::Instance::resolve(tcx, ty::ParamEnv::reveal_all(), method.def_id, - callee_substs).unwrap(); + substs).unwrap(); let mono_item = create_fn_mono_item(instance); if mono_item.is_instantiable(tcx) diff --git a/src/test/compile-fail/issue-47309.rs b/src/test/compile-fail/issue-47309.rs new file mode 100644 index 000000000000..7141bd62dc0d --- /dev/null +++ b/src/test/compile-fail/issue-47309.rs @@ -0,0 +1,31 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Make sure that the mono-item collector does not crash when trying to +// instantiate a default impl of a method with lifetime parameters. +// See https://github.com/rust-lang/rust/issues/47309 + +// compile-flags:-Clink-dead-code +// must-compile-successfully + +#![crate_type="rlib"] + +pub trait EnvFuture { + type Item; + + fn boxed_result<'a>(self) where Self: Sized, Self::Item: 'a, { + } +} + +struct Foo; + +impl<'a> EnvFuture for &'a Foo { + type Item = (); +} From c24a58c87c41f17e341cb165f990ef2fd5ec3cb5 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 09:29:54 -0500 Subject: [PATCH 241/830] fix link --- src/doc/rustdoc/src/unstable-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 5f9978c61b6e..243d60737678 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -7,7 +7,7 @@ themselves unstable. Several features here require a matching `#![feature(...)]` enable, and thus are more fully documented in the [Unstable Book]. Those sections will link over there as necessary. -[Unstable Book]: ../unstable-book/ +[Unstable Book]: ../unstable-book/index.html ## Nightly-gated functionality From 43ed37711e98585178cc291283b9b3345448f311 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 09:33:57 -0500 Subject: [PATCH 242/830] add new section about CLI flags --- src/doc/rustdoc/src/unstable-features.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 243d60737678..837a55f371fb 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -196,3 +196,10 @@ chapter in the Unstable Book][unstable-include] and [its tracking issue][issue-i [unstable-include]: ../unstable-book/language-features/external-doc.html [issue-include]: https://github.com/rust-lang/rust/issues/44732 + +## Unstable command-line arguments + +These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are +themselves marked as unstable. To use any of these options, pass `-Z unstable-options` as well as +the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the +`RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command. From 4fe6acf9721b520ddf3c5ee1bc7d300d13545649 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 15 Mar 2018 16:36:02 +0100 Subject: [PATCH 243/830] add compile fail tests --- src/librustc_llvm/ffi.rs | 2 + src/librustc_trans/common.rs | 20 +++++ src/librustc_trans/intrinsic.rs | 28 ++++++- .../simd-intrinsic-generic-reduction.rs | 76 +++++++++++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/simd-intrinsic-generic-reduction.rs diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 00547017349d..c0cdd2127706 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -621,6 +621,7 @@ extern "C" { pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong; pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool, high: *mut u64, low: *mut u64) -> bool; + pub fn LLVMConstRealGetDouble (ConstantVal: ValueRef, losesInfo: *mut Bool) -> f64; // Operations on composite constants @@ -1607,6 +1608,7 @@ extern "C" { pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef); pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef; + pub fn LLVMIsAConstantFP(value_ref: ValueRef) -> ValueRef; pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind; pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef; diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 7c4e2340d5bd..a2c2fad68f6b 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -270,6 +270,19 @@ pub fn const_get_elt(v: ValueRef, idx: u64) -> ValueRef { } } +pub fn const_get_real(v: ValueRef) -> Option<(f64, bool)> { + unsafe { + if is_const_real(v) { + let mut loses_info: llvm::Bool = ::std::mem::uninitialized(); + let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info as *mut llvm::Bool); + let loses_info = if loses_info == 1 { true } else { false }; + Some((r, loses_info)) + } else { + None + } + } +} + pub fn const_to_uint(v: ValueRef) -> u64 { unsafe { llvm::LLVMConstIntGetZExtValue(v) @@ -282,6 +295,13 @@ pub fn is_const_integral(v: ValueRef) -> bool { } } +pub fn is_const_real(v: ValueRef) -> bool { + unsafe { + !llvm::LLVMIsAConstantFP(v).is_null() + } +} + + #[inline] fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 { ((hi as u128) << 64) | (lo as u128) diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 72c619a3b0ca..f1ecad2067b2 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1174,7 +1174,25 @@ fn generic_simd_intrinsic<'a, 'tcx>( ty::TyFloat(f) => { // ordered arithmetic reductions take an accumulator let acc = if $ordered { - args[1].immediate() + let acc = args[1].immediate(); + // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36734 + // * if the accumulator of the fadd isn't 0, incorrect + // code is generated + // * if the accumulator of the fmul isn't 1, incorrect + // code is generated + match const_get_real(acc) { + None => return_error!("accumulator of {} is not a constant", $name), + Some((v, loses_info)) => { + if $name.contains("mul") && v != 1.0_f64 { + return_error!("accumulator of {} is not 1.0", $name); + } else if $name.contains("add") && v != 0.0_f64 { + return_error!("accumulator of {} is not 0.0", $name); + } else if loses_info { + return_error!("accumulator of {} loses information", $name); + } + } + } + acc } else { // unordered arithmetic reductions do not: match f.bit_width() { @@ -1248,6 +1266,14 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, in_elem, in_ty, ret_ty); args[0].immediate() } else { + match in_elem.sty { + ty::TyInt(_) | ty::TyUint(_) => {}, + _ => { + return_error!("unsupported {} from `{}` with element `{}` to `{}`", + $name, in_ty, in_elem, ret_ty) + } + } + // boolean reductions operate on vectors of i1s: let i1 = Type::i1(bx.cx); let i1xn = Type::vector(&i1, in_len as u64); diff --git a/src/test/compile-fail/simd-intrinsic-generic-reduction.rs b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs new file mode 100644 index 000000000000..b4c069eb10f5 --- /dev/null +++ b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs @@ -0,0 +1,76 @@ +// Copyright 2015 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. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + + +extern "platform-intrinsic" { + fn simd_reduce_add_ordered(x: T, y: U) -> U; + fn simd_reduce_mul_ordered(x: T, y: U) -> U; + fn simd_reduce_and(x: T) -> U; + fn simd_reduce_or(x: T) -> U; + fn simd_reduce_xor(x: T) -> U; + fn simd_reduce_all(x: T) -> bool; + fn simd_reduce_any(x: T) -> bool; +} + +fn main() { + let x = u32x4(0, 0, 0, 0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + unsafe { + simd_reduce_add_ordered(z, 0_f32); + simd_reduce_mul_ordered(z, 1_f32); + + simd_reduce_add_ordered(z, 2_f32); + //~^ ERROR accumulator of simd_reduce_add_ordered is not 0.0 + simd_reduce_mul_ordered(z, 3_f32); + //~^ ERROR accumulator of simd_reduce_mul_ordered is not 1.0 + + let _: f32 = simd_reduce_and(x); + //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32` + let _: f32 = simd_reduce_or(x); + //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32` + let _: f32 = simd_reduce_xor(x); + //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32` + + let _: f32 = simd_reduce_and(z); + //~^ ERROR unsupported simd_reduce_and from `f32x4` with element `f32` to `f32` + let _: f32 = simd_reduce_or(z); + //~^ ERROR unsupported simd_reduce_or from `f32x4` with element `f32` to `f32` + let _: f32 = simd_reduce_xor(z); + //~^ ERROR unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32` + + let _: bool = simd_reduce_all(z); + //~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool` + let _: bool = simd_reduce_any(z); + //~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool` + + foo(0_f32); + } +} + +#[inline(never)] +unsafe fn foo(x: f32) { + let z = f32x4(0.0, 0.0, 0.0, 0.0); + simd_reduce_add_ordered(z, x); + //~^ ERROR accumulator of simd_reduce_add_ordered is not a constant + simd_reduce_mul_ordered(z, x); + //~^ ERROR accumulator of simd_reduce_mul_ordered is not a constant +} From 19b81f61142fe69edb48d08e9bbfa96d389e8ffd Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 15 Mar 2018 16:51:58 +0100 Subject: [PATCH 244/830] error via bug! instead of stderr+terminate --- src/librustc_trans/builder.rs | 66 ++++++++++++++++++++++++++++++----- src/rustllvm/RustWrapper.cpp | 61 ++++++++++++-------------------- 2 files changed, 79 insertions(+), 48 deletions(-) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 371f53013b90..3f5a9a54ff1e 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -962,6 +962,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFAdd is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -973,6 +976,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // https://bugs.llvm.org/show_bug.cgi?id=36732 // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMul is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -980,49 +986,80 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_add(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.add"); unsafe { - llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceAdd is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_mul(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.mul"); unsafe { - llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceMul is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_and(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.and"); unsafe { - llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceAnd is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_or(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.or"); unsafe { - llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceOr is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_xor(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.xor"); unsafe { - llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) + let instr = llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceXor is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin"); unsafe { - llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true) + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmax"); unsafe { - llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true) + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin_fast"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, false); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -1031,6 +1068,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.count_insn("vector.reduce.fmax_fast"); unsafe { let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, false); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); + } llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr } @@ -1038,13 +1078,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_min(&self, src: ValueRef, is_signed: bool) -> ValueRef { self.count_insn("vector.reduce.min"); unsafe { - llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) + let instr = llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceMin is not available in LLVM version < 5.0"); + } + instr } } pub fn vector_reduce_max(&self, src: ValueRef, is_signed: bool) -> ValueRef { self.count_insn("vector.reduce.max"); unsafe { - llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) + let instr = llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed); + if instr.is_null() { + bug!("LLVMRustBuildVectorReduceMax is not available in LLVM version < 5.0"); + } + instr } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index cd3ae1e743bf..a5644d6f9e2e 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1447,65 +1447,48 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef B, LLVMValueRef Src, bool NoNaN) { #else -void error_and_exit(const char* msg) { - raw_fd_ostream OS(2, false); - OS << ::std::string(msg); - std::exit(EXIT_FAILURE); -} - extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceFAdd requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceFMul requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceAdd requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceAdd(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceMul requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceMul(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceAnd requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceAnd(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceOr requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceOr(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef Src) { - error_and_exit("LLVMRustBuildVectorReduceXor requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceXor(LLVMBuilderRef, LLVMValueRef) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceMin requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceMin(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceMax requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceMax(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceFMin requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFMin(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } extern "C" LLVMValueRef -LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef Src, bool) { - error_and_exit("LLVMRustBuildVectorReduceFMax requires LLVM >= 5.0"); - return Src; +LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) { + return nullptr; } #endif From 6fbdaf42097f2e8fda09692693c7a27acb4c0ef2 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 15 Mar 2018 18:04:45 +0100 Subject: [PATCH 245/830] unstabilize FusedIterator for Flatten since Flatten is unstable --- src/libcore/iter/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index a6802d606ca8..b1b783b47c72 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -2605,7 +2605,7 @@ impl DoubleEndedIterator for Flatten } } -#[stable(feature = "fused", since = "1.26.0")] +#[unstable(feature = "iterator_flatten", issue = "48213")] impl FusedIterator for Flatten where I: FusedIterator, U: Iterator, I::Item: IntoIterator {} From f173a4c064e2bce979d85cc610264186913dc164 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 15 Mar 2018 18:42:53 +0100 Subject: [PATCH 246/830] add missing min-llvm-version --- src/test/compile-fail/simd-intrinsic-generic-reduction.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/compile-fail/simd-intrinsic-generic-reduction.rs b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs index b4c069eb10f5..4cb9d6aba75c 100644 --- a/src/test/compile-fail/simd-intrinsic-generic-reduction.rs +++ b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs @@ -8,6 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// min-llvm-version 5.0 + +// Test that the simd_reduce_{op} intrinsics produce ok-ish error +// messages when misused. + #![feature(repr_simd, platform_intrinsics)] #![allow(non_camel_case_types)] From 9e64946bded0698c8c45d74526e6a8b5a514c4a1 Mon Sep 17 00:00:00 2001 From: snf Date: Wed, 14 Mar 2018 14:56:37 +0000 Subject: [PATCH 247/830] setting ABORTING_MALLOC for asmjs backend --- src/liballoc/tests/string.rs | 5 ----- src/liballoc/tests/vec.rs | 7 +------ src/liballoc/tests/vec_deque.rs | 8 +------- src/librustc_back/target/asmjs_unknown_emscripten.rs | 4 +++- src/libstd/collections/hash/map.rs | 4 ---- 5 files changed, 5 insertions(+), 23 deletions(-) diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 9bbba4e22b03..d1e746ea43b4 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -9,11 +9,8 @@ // except according to those terms. use std::borrow::Cow; -#[cfg(not(target_arch = "asmjs"))] use std::collections::CollectionAllocErr::*; -#[cfg(not(target_arch = "asmjs"))] use std::mem::size_of; -#[cfg(not(target_arch = "asmjs"))] use std::{usize, isize}; pub trait IntoCow<'a, B: ?Sized> where B: ToOwned { @@ -535,7 +532,6 @@ fn test_reserve_exact() { assert!(s.capacity() >= 33) } -#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { @@ -613,7 +609,6 @@ fn test_try_reserve() { } -#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve_exact() { diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 85e11d8b8ee6..3c17a401bbaf 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -10,11 +10,8 @@ use std::borrow::Cow; use std::mem::size_of; -use std::{usize, panic}; -#[cfg(not(target_arch = "asmjs"))] -use std::isize; +use std::{usize, isize, panic}; use std::vec::{Drain, IntoIter}; -#[cfg(not(target_arch = "asmjs"))] use std::collections::CollectionAllocErr::*; struct DropCounter<'a> { @@ -994,7 +991,6 @@ fn test_reserve_exact() { assert!(v.capacity() >= 33) } -#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { @@ -1097,7 +1093,6 @@ fn test_try_reserve() { } -#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve_exact() { diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 9fd38ed6f6f4..fc1a0b624a55 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -11,13 +11,9 @@ use std::collections::VecDeque; use std::fmt::Debug; use std::collections::vec_deque::{Drain}; -#[cfg(not(target_arch = "asmjs"))] use std::collections::CollectionAllocErr::*; -#[cfg(not(target_arch = "asmjs"))] use std::mem::size_of; -use std::isize; -#[cfg(not(target_arch = "asmjs"))] -use std::usize; +use std::{usize, isize}; use self::Taggy::*; use self::Taggypar::*; @@ -1053,7 +1049,6 @@ fn test_reserve_exact_2() { assert!(v.capacity() >= 48) } -#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { @@ -1155,7 +1150,6 @@ fn test_try_reserve() { } -#[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve_exact() { diff --git a/src/librustc_back/target/asmjs_unknown_emscripten.rs b/src/librustc_back/target/asmjs_unknown_emscripten.rs index f114926740a5..ab7df4ba1c54 100644 --- a/src/librustc_back/target/asmjs_unknown_emscripten.rs +++ b/src/librustc_back/target/asmjs_unknown_emscripten.rs @@ -15,7 +15,9 @@ pub fn target() -> Result { let mut args = LinkArgs::new(); args.insert(LinkerFlavor::Em, vec!["-s".to_string(), - "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]); + "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(), + "-s".to_string(), + "ABORTING_MALLOC=0".to_string()]); let opts = TargetOptions { dynamic_linking: false, diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 5f5dec2dd4ff..b18b38ec3024 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2755,11 +2755,8 @@ mod test_map { use cell::RefCell; use rand::{thread_rng, Rng}; use panic; - #[cfg(not(target_arch = "asmjs"))] use realstd::collections::CollectionAllocErr::*; - #[cfg(not(target_arch = "asmjs"))] use realstd::mem::size_of; - #[cfg(not(target_arch = "asmjs"))] use realstd::usize; #[test] @@ -3696,7 +3693,6 @@ mod test_map { assert_eq!(hm.len(), 0); } - #[cfg(not(target_arch = "asmjs"))] #[test] fn test_try_reserve() { From bb328237fc68fcc9c0495b283da74f8ec361b371 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 12:47:26 -0500 Subject: [PATCH 248/830] talk about --markdown-(before|after)-content --- src/doc/rustdoc/src/unstable-features.md | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 837a55f371fb..873aebfc7777 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -203,3 +203,31 @@ These features are enabled by passing a command-line flag to Rustdoc, but the fl themselves marked as unstable. To use any of these options, pass `-Z unstable-options` as well as the flag in question to Rustdoc on the command-line. To do this from Cargo, you can either use the `RUSTDOCFLAGS` environment variable or the `cargo rustdoc` command. + +### `--markdown-before-content`: include rendered Markdown before the content + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --markdown-before-content extra.md +$ rustdoc README.md -Z unstable-options --markdown-before-content extra.md +``` + +Just like `--html-before-content`, this allows you to insert extra content inside the `` tag +but before the other content `rustdoc` would normally produce in the rendered documentation. +However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a +Markdown renderer before inserting the result into the file. + +### `--markdown-after-content`: include rendered Markdown after the content + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --markdown-after-content extra.md +$ rustdoc README.md -Z unstable-options --markdown-after-content extra.md +``` + +Just like `--html-after-content`, this allows you to insert extra content before the `` tag +but after the other content `rustdoc` would normally produce in the rendered documentation. +However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a +Markdown renderer before inserting the result into the file. From 4eaa85d3be27ceec2247eb1b83ca83b2ac92b3da Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 15 Mar 2018 14:27:00 -0400 Subject: [PATCH 249/830] add xref to rust-guide --- src/librustc_traits/lowering.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index 296ad18c480b..ae52e83cdc24 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -117,6 +117,10 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId if let ImplPolarity::Negative = tcx.impl_polarity(def_id) { return Lrc::new(vec![]); } + + // Rule Implemented-From-Impl + // + // (see rustc guide) let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); let trait_ref = ty::TraitPredicate { trait_ref }.lower(); From 5e991e1b7ee3ddbd160203dec84bef10b45c1589 Mon Sep 17 00:00:00 2001 From: Anthony Defranceschi Date: Thu, 8 Mar 2018 23:18:45 +0100 Subject: [PATCH 250/830] Improve `AddrParseError` documentation. Add a potential cause to `AddrParseError` raising. --- src/libstd/net/parser.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs index 261d44eebaa2..ae5037cc44e8 100644 --- a/src/libstd/net/parser.rs +++ b/src/libstd/net/parser.rs @@ -372,6 +372,25 @@ impl FromStr for SocketAddr { /// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and /// [`SocketAddrV6`]. /// +/// # Potential causes +/// +/// `AddrParseError` may be thrown because the provided string does not parse as the given type, +/// often because it includes information only handled by a different address type. +/// +/// ```should_panic +/// use std::net::IpAddr; +/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port"); +/// ``` +/// +/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead. +/// +/// ``` +/// use std::net::SocketAddr; +/// +/// // No problem, the `panic!` message has disappeared. +/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic"); +/// ``` +/// /// [`FromStr`]: ../../std/str/trait.FromStr.html /// [`IpAddr`]: ../../std/net/enum.IpAddr.html /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html From 4d5cd21a0db601636d88f4c95f50435b04bf71df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 14 Mar 2018 19:10:28 -0700 Subject: [PATCH 251/830] Coherence diagnostic tweaks --- src/librustc_typeck/coherence/mod.rs | 47 +++++++++-------- src/librustc_typeck/coherence/orphan.rs | 56 +++++++++++++-------- src/test/ui/codemap_tests/empty_span.stderr | 2 +- src/test/ui/coherence-impls-copy.stderr | 6 +-- src/test/ui/e0119/complex-impl.stderr | 6 ++- src/test/ui/e0119/issue-28981.stderr | 6 ++- src/test/ui/error-codes/E0117.stderr | 2 +- src/test/ui/error-codes/E0206.stderr | 2 +- src/test/ui/error-codes/E0328.rs | 20 ++++++++ src/test/ui/error-codes/E0328.stderr | 9 ++++ 10 files changed, 104 insertions(+), 52 deletions(-) create mode 100644 src/test/ui/error-codes/E0328.rs create mode 100644 src/test/ui/error-codes/E0328.stderr diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index d3de31d630a9..07b7c600b9f3 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -52,10 +52,10 @@ fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_def_id: DefId) { let did = Some(trait_def_id); let li = tcx.lang_items(); + let span = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap()); // Disallow *all* explicit impls of `Sized` and `Unsize` for now. if did == li.sized_trait() { - let span = tcx.span_of_impl(impl_def_id).unwrap(); struct_span_err!(tcx.sess, span, E0322, @@ -66,11 +66,12 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d } if did == li.unsize_trait() { - let span = tcx.span_of_impl(impl_def_id).unwrap(); - span_err!(tcx.sess, - span, - E0328, - "explicit impls for the `Unsize` trait are not permitted"); + struct_span_err!(tcx.sess, + span, + E0328, + "explicit impls for the `Unsize` trait are not permitted") + .span_label(span, "impl of `Unsize` not allowed") + .emit(); return; } @@ -88,14 +89,14 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, impl_def_id: DefId, trait_d } else { return; // everything OK }; - let mut err = struct_span_err!(tcx.sess, - tcx.span_of_impl(impl_def_id).unwrap(), - E0183, - "manual implementations of `{}` are experimental", - trait_name); - help!(&mut err, - "add `#![feature(unboxed_closures)]` to the crate attributes to enable"); - err.emit(); + struct_span_err!(tcx.sess, + span, + E0183, + "manual implementations of `{}` are experimental", + trait_name) + .span_label(span, format!("manual implementations of `{}` are experimental", trait_name)) + .help("add `#![feature(unboxed_closures)]` to the crate attributes to enable") + .emit(); } pub fn provide(providers: &mut Providers) { @@ -168,13 +169,17 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI traits::supertrait_def_ids(tcx, data.principal().unwrap().def_id()); if supertrait_def_ids.any(|d| d == trait_def_id) { - span_err!(tcx.sess, - tcx.span_of_impl(impl_def_id).unwrap(), - E0371, - "the object type `{}` automatically \ - implements the trait `{}`", - trait_ref.self_ty(), - tcx.item_path_str(trait_def_id)); + let sp = tcx.sess.codemap().def_span(tcx.span_of_impl(impl_def_id).unwrap()); + struct_span_err!(tcx.sess, + sp, + E0371, + "the object type `{}` automatically implements the trait `{}`", + trait_ref.self_ty(), + tcx.item_path_str(trait_def_id)) + .span_label(sp, format!("`{}` automatically implements trait `{}`", + trait_ref.self_ty(), + tcx.item_path_str(trait_def_id))) + .emit(); } } } diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index c2dfd798a3c4..6d6594e55437 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -40,29 +40,36 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { self.tcx.hir.node_to_string(item.id)); let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap(); let trait_def_id = trait_ref.def_id; + let cm = self.tcx.sess.codemap(); + let sp = cm.def_span(item.span); match traits::orphan_check(self.tcx, def_id) { Ok(()) => {} Err(traits::OrphanCheckErr::NoLocalInputType) => { struct_span_err!(self.tcx.sess, - item.span, + sp, E0117, "only traits defined in the current crate can be \ implemented for arbitrary types") - .span_label(item.span, "impl doesn't use types inside crate") - .note(&format!("the impl does not reference any types defined in \ - this crate")) + .span_label(sp, "impl doesn't use types inside crate") + .note("the impl does not reference any types defined in this crate") .note("define and implement a trait or new type instead") .emit(); return; } Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => { - span_err!(self.tcx.sess, - item.span, - E0210, - "type parameter `{}` must be used as the type parameter for \ - some local type (e.g. `MyStruct`); only traits defined in \ - the current crate can be implemented for a type parameter", - param_ty); + struct_span_err!(self.tcx.sess, + sp, + E0210, + "type parameter `{}` must be used as the type parameter \ + for some local type (e.g. `MyStruct<{}>`)", + param_ty, + param_ty) + .span_label(sp, + format!("type parameter `{}` must be used as the type \ + parameter for some local type", param_ty)) + .note("only traits defined in the current crate can be implemented \ + for a type parameter") + .emit(); return; } } @@ -121,22 +128,29 @@ impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { if self_def_id.is_local() { None } else { - Some(format!("cross-crate traits with a default impl, like `{}`, \ - can only be implemented for a struct/enum type \ - defined in the current crate", - self.tcx.item_path_str(trait_def_id))) + Some(( + format!("cross-crate traits with a default impl, like `{}`, \ + can only be implemented for a struct/enum type \ + defined in the current crate", + self.tcx.item_path_str(trait_def_id)), + "can't implement cross-crate trait for type in another crate" + )) } } _ => { - Some(format!("cross-crate traits with a default impl, like `{}`, can \ - only be implemented for a struct/enum type, not `{}`", - self.tcx.item_path_str(trait_def_id), - self_ty)) + Some((format!("cross-crate traits with a default impl, like `{}`, can \ + only be implemented for a struct/enum type, not `{}`", + self.tcx.item_path_str(trait_def_id), + self_ty), + "can't implement cross-crate trait with a default impl for \ + non-struct/enum type")) } }; - if let Some(msg) = msg { - span_err!(self.tcx.sess, item.span, E0321, "{}", msg); + if let Some((msg, label)) = msg { + struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg) + .span_label(sp, label) + .emit(); return; } } diff --git a/src/test/ui/codemap_tests/empty_span.stderr b/src/test/ui/codemap_tests/empty_span.stderr index 63b19c9e0c6a..2df1d69acdbd 100644 --- a/src/test/ui/codemap_tests/empty_span.stderr +++ b/src/test/ui/codemap_tests/empty_span.stderr @@ -2,7 +2,7 @@ error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, --> $DIR/empty_span.rs:17:5 | LL | unsafe impl Send for &'static Foo { } //~ ERROR cross-crate traits with a default impl - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type error: aborting due to previous error diff --git a/src/test/ui/coherence-impls-copy.stderr b/src/test/ui/coherence-impls-copy.stderr index 029b04789525..c276d8b95102 100644 --- a/src/test/ui/coherence-impls-copy.stderr +++ b/src/test/ui/coherence-impls-copy.stderr @@ -32,7 +32,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar --> $DIR/coherence-impls-copy.rs:33:1 | LL | impl Copy for (MyType, MyType) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | = note: the impl does not reference any types defined in this crate = note: define and implement a trait or new type instead @@ -41,7 +41,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar --> $DIR/coherence-impls-copy.rs:40:1 | LL | impl Copy for [MyType] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | = note: the impl does not reference any types defined in this crate = note: define and implement a trait or new type instead @@ -50,7 +50,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar --> $DIR/coherence-impls-copy.rs:44:1 | LL | impl Copy for &'static [NotSync] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | = note: the impl does not reference any types defined in this crate = note: define and implement a trait or new type instead diff --git a/src/test/ui/e0119/complex-impl.stderr b/src/test/ui/e0119/complex-impl.stderr index b268c7554045..7e0e8ff0372f 100644 --- a/src/test/ui/e0119/complex-impl.stderr +++ b/src/test/ui/e0119/complex-impl.stderr @@ -8,11 +8,13 @@ LL | impl External for (Q, R) {} //~ ERROR must be used - impl<'a, 'b, 'c, T, U, V, W> complex_impl_support::External for (T, complex_impl_support::M<'a, 'b, 'c, std::boxed::Box, V, W>) where >::Output == V, ::Item == T, 'b : 'a, T : 'a, U: std::ops::FnOnce<(T,)>, U : 'static, V: std::iter::Iterator, V: std::clone::Clone, W: std::ops::Add, ::Output: std::marker::Copy; -error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct`); only traits defined in the current crate can be implemented for a type parameter +error[E0210]: type parameter `R` must be used as the type parameter for some local type (e.g. `MyStruct`) --> $DIR/complex-impl.rs:19:1 | LL | impl External for (Q, R) {} //~ ERROR must be used - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `R` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/e0119/issue-28981.stderr b/src/test/ui/e0119/issue-28981.stderr index b1ec1111ede9..ade072336bcc 100644 --- a/src/test/ui/e0119/issue-28981.stderr +++ b/src/test/ui/e0119/issue-28981.stderr @@ -8,11 +8,13 @@ LL | impl Deref for Foo { } //~ ERROR must be used - impl<'a, T> std::ops::Deref for &'a T where T: ?Sized; -error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct`); only traits defined in the current crate can be implemented for a type parameter +error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g. `MyStruct`) --> $DIR/issue-28981.rs:15:1 | LL | impl Deref for Foo { } //~ ERROR must be used - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ type parameter `Foo` must be used as the type parameter for some local type + | + = note: only traits defined in the current crate can be implemented for a type parameter error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr index 240aa4240cc6..397028863484 100644 --- a/src/test/ui/error-codes/E0117.stderr +++ b/src/test/ui/error-codes/E0117.stderr @@ -8,7 +8,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar --> $DIR/E0117.rs:11:1 | LL | impl Drop for u32 {} //~ ERROR E0117 - | ^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | = note: the impl does not reference any types defined in this crate = note: define and implement a trait or new type instead diff --git a/src/test/ui/error-codes/E0206.stderr b/src/test/ui/error-codes/E0206.stderr index 0cd22a454e12..6c671967e84f 100644 --- a/src/test/ui/error-codes/E0206.stderr +++ b/src/test/ui/error-codes/E0206.stderr @@ -14,7 +14,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar --> $DIR/E0206.rs:13:1 | LL | impl Copy for Foo { } - | ^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate | = note: the impl does not reference any types defined in this crate = note: define and implement a trait or new type instead diff --git a/src/test/ui/error-codes/E0328.rs b/src/test/ui/error-codes/E0328.rs new file mode 100644 index 000000000000..e08532b02491 --- /dev/null +++ b/src/test/ui/error-codes/E0328.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(unsize)] + +use std::marker::Unsize; + +pub struct MyType; + +impl Unsize for MyType {} +//~^ ERROR explicit impls for the `Unsize` trait are not permitted [E0328] + +fn main() {} diff --git a/src/test/ui/error-codes/E0328.stderr b/src/test/ui/error-codes/E0328.stderr new file mode 100644 index 000000000000..ad3a224279ce --- /dev/null +++ b/src/test/ui/error-codes/E0328.stderr @@ -0,0 +1,9 @@ +error[E0328]: explicit impls for the `Unsize` trait are not permitted + --> $DIR/E0328.rs:17:1 + | +LL | impl Unsize for MyType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Unsize` not allowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0328`. From 5d8443aeb1bf441897efddfc1246377f0d51149d Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 15 Mar 2018 14:44:17 -0500 Subject: [PATCH 252/830] talk about --playground-url --- src/doc/rustdoc/src/unstable-features.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 873aebfc7777..9cb5760ec379 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -231,3 +231,26 @@ Just like `--html-after-content`, this allows you to insert extra content before but after the other content `rustdoc` would normally produce in the rendered documentation. However, instead of directly inserting the file verbatim, `rustdoc` will pass the files through a Markdown renderer before inserting the result into the file. + +### `--playground-url`: control the location of the playground + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --playground-url https://play.rust-lang.org/ +``` + +When rendering a crate's docs, this flag gives the base URL of the Rust Playground, to use for +generating `Run` buttons. Unlike `--markdown-playground-url`, this argument works for standalone +Markdown files *and* Rust crates. This works the same way as adding `#![doc(html_playground_url = +"url")]` to your crate root, as mentioned in [the chapter about the `#[doc]` +attribute][doc-playground]. Please be aware that the official Rust Playground at +https://play.rust-lang.org does not have every crate available, so if your examples require your +crate, make sure the playground you provide has your crate available. + +[doc-playground]: the-doc-attribute.html#html_playground_url + +If both `--playground-url` and `--markdown-playground-url` are present when rendering a standalone +Markdown file, the URL given to `--markdown-playground-url` will take precedence. If both +`--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs, +the attribute will take precedence. From e3c5f6958f3fc82858a3674277d620d3ba844350 Mon Sep 17 00:00:00 2001 From: boats Date: Thu, 15 Mar 2018 12:55:37 -0700 Subject: [PATCH 253/830] Add liballoc APIs. --- src/liballoc/boxed.rs | 97 ++++++++++++++++++++++++++++++++++++++++++- src/liballoc/lib.rs | 1 + 2 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 75a59de337ce..42903c7bde0d 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -64,8 +64,8 @@ use core::cmp::Ordering; use core::fmt; use core::hash::{self, Hash, Hasher}; use core::iter::FusedIterator; -use core::marker::{self, Unsize}; -use core::mem; +use core::marker::{self, Unpin, Unsize}; +use core::mem::{self, Pin}; use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState}; use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer}; use core::ptr::{self, NonNull, Unique}; @@ -896,3 +896,96 @@ impl Generator for Box (**self).resume() } } + +/// A pinned, heap allocated reference. +#[unstable(feature = "pin", issue = "0")] +pub struct PinBox { + inner: Box, +} + +#[unstable(feature = "pin", issue = "0")] +impl PinBox { + /// Allocate memory on the heap, move the data into it and pin it. + #[unstable(feature = "pin", issue = "0")] + pub fn new(data: T) -> PinBox { + PinBox { inner: Box::new(data) } + } +} + +#[unstable(feature = "pin", issue = "0")] +impl PinBox { + /// Get a pinned reference to the data in this PinBox. + pub fn as_pin<'a>(&'a mut self) -> Pin<'a, T> { + unsafe { Pin::new_unchecked(&mut *self.inner) } + } + + /// Get a mutable reference to the data inside this PinBox. + /// + /// This function is unsafe. Users must guarantee that the data is never + /// moved out of this reference. + pub unsafe fn get_mut<'a>(this: &'a mut PinBox) -> &'a mut T { + &mut *this.inner + } + + /// Convert this PinBox into an unpinned Box. + /// + /// This function is unsafe. Users must guarantee that the data is never + /// moved out of the box. + pub unsafe fn unpin(this: PinBox) -> Box { + this.inner + } +} + +#[unstable(feature = "pin", issue = "0")] +impl From> for PinBox { + fn from(boxed: Box) -> PinBox { + PinBox { inner: boxed } + } +} + +#[unstable(feature = "pin", issue = "0")] +impl From> for Box { + fn from(pinned: PinBox) -> Box { + pinned.inner + } +} + +#[unstable(feature = "pin", issue = "0")] +impl Deref for PinBox { + type Target = T; + + fn deref(&self) -> &T { + &*self.inner + } +} + +#[unstable(feature = "pin", issue = "0")] +impl DerefMut for PinBox { + fn deref_mut(&mut self) -> &mut T { + &mut *self.inner + } +} + +#[unstable(feature = "pin", issue = "0")] +impl fmt::Display for PinBox { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&*self.inner, f) + } +} + +#[unstable(feature = "pin", issue = "0")] +impl fmt::Debug for PinBox { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&*self.inner, f) + } +} + +#[unstable(feature = "pin", issue = "0")] +impl fmt::Pointer for PinBox { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // It's not possible to extract the inner Uniq directly from the Box, + // instead we cast it to a *const which aliases the Unique + let ptr: *const T = &*self.inner; + fmt::Pointer::fmt(&ptr, f) + } +} diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d250cfe1880f..73e452b6a36e 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -107,6 +107,7 @@ #![feature(offset_to)] #![feature(optin_builtin_traits)] #![feature(pattern)] +#![feature(pin)] #![feature(placement_in_syntax)] #![feature(placement_new_protocol)] #![feature(ptr_internals)] From 72cb109bec8e73b1568c2f287ed08348453bf534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 20:13:33 +0100 Subject: [PATCH 254/830] Faster submodule updating --- config.toml.example | 4 +++ src/bootstrap/bootstrap.py | 62 ++++++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/config.toml.example b/config.toml.example index b47f9163c0da..aec5e5a0e2c8 100644 --- a/config.toml.example +++ b/config.toml.example @@ -118,6 +118,10 @@ # Indicate whether submodules are managed and updated automatically. #submodules = true +# Update submodules only when the checked out commit in the submodules differs +# from what is committed in the main rustc repo. +#fast-submodules = true + # The path to (or name of) the GDB executable to use. This is only used for # executing the debuginfo test suite. #gdb = "gdb" diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d8f7cd7ed922..6ea374b2f265 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -614,20 +614,55 @@ class RustBuild(object): return config return default_build_triple() + def check_submodule(self, module, slow_submodules): + if not slow_submodules: + checked_out = subprocess.Popen(["git", "rev-parse", "HEAD"], + cwd=os.path.join(self.rust_root, module), + stdout=subprocess.PIPE) + return checked_out + else: + return None + + def update_submodule(self, module, checked_out, recorded_submodules): + module_path = os.path.join(self.rust_root, module) + + if checked_out != None: + default_encoding = sys.getdefaultencoding() + checked_out = checked_out.communicate()[0].decode(default_encoding).strip() + if recorded_submodules[module] == checked_out: + return + + print("Updating submodule", module) + + run(["git", "submodule", "-q", "sync", module], + cwd=self.rust_root, verbose=self.verbose) + run(["git", "submodule", "update", + "--init", "--recursive", module], + cwd=self.rust_root, verbose=self.verbose) + run(["git", "reset", "-q", "--hard"], + cwd=module_path, verbose=self.verbose) + run(["git", "clean", "-qdfx"], + cwd=module_path, verbose=self.verbose) + def update_submodules(self): """Update submodules""" if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \ self.get_toml('submodules') == "false": return - print('Updating submodules') + slow_submodules = self.get_toml('fast-submodule') == "false" + start_time = time() + if slow_submodules: + print('Unconditionally updating all submodules') + else: + print('Updating only changed submodules') default_encoding = sys.getdefaultencoding() - run(["git", "submodule", "-q", "sync"], cwd=self.rust_root, verbose=self.verbose) submodules = [s.split(' ', 1)[1] for s in subprocess.check_output( ["git", "config", "--file", os.path.join(self.rust_root, ".gitmodules"), "--get-regexp", "path"] ).decode(default_encoding).splitlines()] filtered_submodules = [] + submodules_names = [] for module in submodules: if module.endswith("llvm"): if self.get_toml('llvm-config'): @@ -645,16 +680,19 @@ class RustBuild(object): config = self.get_toml('lld') if config is None or config == 'false': continue - filtered_submodules.append(module) - run(["git", "submodule", "update", - "--init", "--recursive"] + filtered_submodules, - cwd=self.rust_root, verbose=self.verbose) - run(["git", "submodule", "-q", "foreach", "git", - "reset", "-q", "--hard"], - cwd=self.rust_root, verbose=self.verbose) - run(["git", "submodule", "-q", "foreach", "git", - "clean", "-qdfx"], - cwd=self.rust_root, verbose=self.verbose) + check = self.check_submodule(module, slow_submodules) + filtered_submodules.append((module, check)) + submodules_names.append(module) + recorded = subprocess.Popen(["git", "ls-tree", "HEAD"] + submodules_names, + cwd=self.rust_root, stdout=subprocess.PIPE) + recorded = recorded.communicate()[0].decode(default_encoding).strip().splitlines() + recorded_submodules = {} + for data in recorded: + data = data.split() + recorded_submodules[data[3]] = data[2] + for module in filtered_submodules: + self.update_submodule(module[0], module[1], recorded_submodules) + print("Submodules updated in %.2f seconds" % (time() - start_time)) def set_dev_environment(self): """Set download URL for development environment""" From ef3b4e1f5bfb8cf5347b086ed60aefd519a3335d Mon Sep 17 00:00:00 2001 From: Alexandre Martin Date: Thu, 15 Mar 2018 23:20:06 +0100 Subject: [PATCH 255/830] Fix tidy --- src/librustc_traits/lowering.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index ae52e83cdc24..c9666f55d440 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -117,7 +117,7 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId if let ImplPolarity::Negative = tcx.impl_polarity(def_id) { return Lrc::new(vec![]); } - + // Rule Implemented-From-Impl // // (see rustc guide) From 2f1c24a60d173f323fdbe3c716349a9974134568 Mon Sep 17 00:00:00 2001 From: boats Date: Thu, 15 Mar 2018 16:10:18 -0700 Subject: [PATCH 256/830] CoerceUnsized for PinBox --- src/liballoc/boxed.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 42903c7bde0d..5e5d7b917209 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -989,3 +989,6 @@ impl fmt::Pointer for PinBox { fmt::Pointer::fmt(&ptr, f) } } + +#[unstable(feature = "pin", issue = "0")] +impl, U: ?Sized> CoerceUnsized> for PinBox {} From 81d0ecef2c4ba5ebb36a72f76adbce1b229fb856 Mon Sep 17 00:00:00 2001 From: boats Date: Thu, 15 Mar 2018 16:16:11 -0700 Subject: [PATCH 257/830] Pin and PinBox are fundamental. --- src/liballoc/boxed.rs | 1 + src/libcore/mem.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 5e5d7b917209..46d3ccb9de52 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -899,6 +899,7 @@ impl Generator for Box /// A pinned, heap allocated reference. #[unstable(feature = "pin", issue = "0")] +#[fundamental] pub struct PinBox { inner: Box, } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 792d71732e66..e960b5ae7582 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1112,6 +1112,7 @@ pub unsafe fn unreachable() -> ! { /// safe to move a value out of a pinned reference unless the type of that /// value implements the `Unpin` trait. #[unstable(feature = "pin", issue = "0")] +#[fundamental] pub struct Pin<'a, T: ?Sized + 'a> { inner: &'a mut T, } From ec49234f44adbaf858efa646df67a41055fc905d Mon Sep 17 00:00:00 2001 From: comex Date: Sun, 11 Mar 2018 16:44:05 -0700 Subject: [PATCH 258/830] Support extra-verbose builds: - The bootstrap crate currently passes -v to Cargo if itself invoked with -vv. But Cargo supports -vv (to show build script output), so make bootstrap pass that if itself invoked with -vvv. (More specifically, pass N '-v's to Cargo if invoked with N+1 of them.) - bootstrap.py currently tries to pass on up to two '-v's to cargo when building bootstrap, but incorrectly ('-v' is marked as 'store_true', so argparse stores either False or True, ignoring multiple '-v's). Fix this, allow passing any number of '-v's, and make it consistent with bootstrap's invocation of Cargo (i.e. subtract one from the number of '-v's). - Also improve bootstrap.py's config.toml 'parsing' to support arbitrary verbosity levels, + allow command line to override it. --- src/bootstrap/bootstrap.py | 13 +++++-------- src/bootstrap/builder.rs | 2 +- src/bootstrap/flags.rs | 2 +- src/bootstrap/lib.rs | 4 ---- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d8f7cd7ed922..11f174a52a63 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -597,10 +597,8 @@ class RustBuild(object): self.cargo())) args = [self.cargo(), "build", "--manifest-path", os.path.join(self.rust_root, "src/bootstrap/Cargo.toml")] - if self.verbose: + for _ in range(1, self.verbose): args.append("--verbose") - if self.verbose > 1: - args.append("--verbose") if self.use_locked_deps: args.append("--locked") if self.use_vendored_sources: @@ -675,7 +673,7 @@ def bootstrap(help_triggered): parser.add_argument('--config') parser.add_argument('--build') parser.add_argument('--clean', action='store_true') - parser.add_argument('-v', '--verbose', action='store_true') + parser.add_argument('-v', '--verbose', action='count', default=0) args = [a for a in sys.argv if a != '-h' and a != '--help'] args, _ = parser.parse_known_args(args) @@ -691,10 +689,9 @@ def bootstrap(help_triggered): except (OSError, IOError): pass - if '\nverbose = 2' in build.config_toml: - build.verbose = 2 - elif '\nverbose = 1' in build.config_toml: - build.verbose = 1 + match = re.search(r'\nverbose = (\d+)', build.config_toml) + if match is not None: + build.verbose = max(build.verbose, int(match.group(1))) build.use_vendored_sources = '\nvendor = true' in build.config_toml diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 1b74e7c41e7a..4185384cf499 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -763,7 +763,7 @@ impl<'a> Builder<'a> { cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1"); } - if self.is_very_verbose() { + for _ in 1..self.verbosity { cargo.arg("-v"); } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index af50ad1e96b9..c5af0f8e2e15 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -29,7 +29,7 @@ use cache::{Interned, INTERNER}; /// Deserialized version of all flags for this compile. pub struct Flags { - pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose + pub verbose: usize, // number of -v args; each extra -v after the first is passed to Cargo pub on_fail: Option, pub stage: Option, pub keep_stage: Option, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 938237dd82d5..8b3fbf56d594 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -605,10 +605,6 @@ impl Build { self.verbosity > 0 } - pub fn is_very_verbose(&self) -> bool { - self.verbosity > 1 - } - /// Prints a message if this build is configured in verbose mode. fn verbose(&self, msg: &str) { if self.is_verbose() { From 450d35f582a100e25a394a188c34c283c837087e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 7 Mar 2018 19:37:18 -0500 Subject: [PATCH 259/830] Remove unused fields Related to #46753 --- src/librustc_typeck/check/wfcheck.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index b94af0a1e008..edb4ebb6284e 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -28,7 +28,6 @@ use rustc::hir; pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - code: ObligationCauseCode<'tcx>, } /// Helper type of a temporary returned by .for_item(...). @@ -36,7 +35,6 @@ pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>). struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>, - code: ObligationCauseCode<'gcx>, id: ast::NodeId, span: Span, param_env: ty::ParamEnv<'tcx>, @@ -47,7 +45,6 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>, &mut CheckTypeWellFormedVisitor<'b, 'gcx>) -> Vec> { - let code = self.code.clone(); let id = self.id; let span = self.span; let param_env = self.param_env; @@ -55,7 +52,6 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { let fcx = FnCtxt::new(&inh, param_env, id); let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor { tcx: fcx.tcx.global_tcx(), - code, }); fcx.select_all_obligations_or_error(); fcx.regionck_item(id, span, &wf_tys); @@ -68,7 +64,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { -> CheckTypeWellFormedVisitor<'a, 'gcx> { CheckTypeWellFormedVisitor { tcx, - code: ObligationCauseCode::MiscObligation } } @@ -165,7 +160,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { item_id: ast::NodeId, span: Span, sig_if_method: Option<&hir::MethodSig>) { - let code = self.code.clone(); + let code = ObligationCauseCode::MiscObligation; self.for_id(item_id, span).with_fcx(|fcx, this| { let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); @@ -213,7 +208,6 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let def_id = self.tcx.hir.local_def_id(id); CheckWfFcxBuilder { inherited: Inherited::build(self.tcx, def_id), - code: self.code.clone(), id, span, param_env: self.tcx.param_env(def_id), @@ -265,7 +259,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // All field types must be well-formed. for field in &variant.fields { - fcx.register_wf_obligation(field.ty, field.span, this.code.clone()) + fcx.register_wf_obligation(field.ty, field.span, ObligationCauseCode::MiscObligation) } } @@ -300,11 +294,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { { debug!("check_item_type: {:?}", item); - self.for_item(item).with_fcx(|fcx, this| { + self.for_item(item).with_fcx(|fcx, _this| { let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id)); let item_ty = fcx.normalize_associated_types_in(item.span, &ty); - fcx.register_wf_obligation(item_ty, item.span, this.code.clone()); + fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation); vec![] // no implied bounds in a const etc }); @@ -339,7 +333,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { None => { let self_ty = fcx.tcx.type_of(item_def_id); let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); - fcx.register_wf_obligation(self_ty, ast_self_ty.span, this.code.clone()); + fcx.register_wf_obligation(self_ty, ast_self_ty.span, ObligationCauseCode::MiscObligation); } } @@ -374,7 +368,7 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // parameter includes another (e.g., ). In those cases, we can't // be sure if it will error or not as user might always specify the other. if !ty.needs_subst() { - fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), self.code.clone()); + fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), ObligationCauseCode::MiscObligation); } } @@ -458,11 +452,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); for input_ty in sig.inputs() { - fcx.register_wf_obligation(&input_ty, span, self.code.clone()); + fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); } implied_bounds.extend(sig.inputs()); - fcx.register_wf_obligation(sig.output(), span, self.code.clone()); + fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation); // FIXME(#25759) return types should not be implied bounds implied_bounds.push(sig.output()); From 86a123c2fd018905fca7af94a352227fe97e1623 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 9 Mar 2018 22:35:15 -0500 Subject: [PATCH 260/830] Queryify check_item_well_formed Fixes #46753 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/mod.rs | 2 ++ src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_typeck/check/mod.rs | 5 +++ src/librustc_typeck/check/wfcheck.rs | 50 ++++++++++++++++++++-------- 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 8d7fef90b754..20c3fb501572 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -579,6 +579,7 @@ define_dep_nodes!( <'tcx> [] GetPanicStrategy(CrateNum), [] IsNoBuiltins(CrateNum), [] ImplDefaultness(DefId), + [] CheckItemWellFormed(DefId), [] ReachableNonGenerics(CrateNum), [] NativeLibraries(CrateNum), [] PluginRegistrarFn(CrateNum), diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index c1783654effe..8f4100ad5f70 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -298,6 +298,8 @@ define_maps! { <'tcx> [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness, + [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (), + // The DefIds of all non-generic functions and statics in the given crate // that can be reached from outside the crate. // diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index bc7186f781a8..732c91ea98aa 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -871,6 +871,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::GetPanicStrategy => { force!(panic_strategy, krate!()); } DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); } DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); } + DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); } DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); } DepKind::NativeLibraries => { force!(native_libraries, krate!()); } DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dc9455487ede..a6b307b84149 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -718,6 +718,10 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum })?) } +fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + wfcheck::CheckTypeWellFormed::new(tcx).check_item_well_formed(def_id); +} + pub fn provide(providers: &mut Providers) { *providers = Providers { typeck_item_bodies, @@ -725,6 +729,7 @@ pub fn provide(providers: &mut Providers) { has_typeck_tables, adt_destructor, used_trait_imports, + check_item_well_formed, ..*providers }; } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index edb4ebb6284e..d665e55898d4 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -26,7 +26,7 @@ use errors::{DiagnosticBuilder, DiagnosticId}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { +pub struct CheckTypeWellFormed<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } @@ -43,14 +43,14 @@ struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { fn with_fcx(&'tcx mut self, f: F) where F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>, - &mut CheckTypeWellFormedVisitor<'b, 'gcx>) -> Vec> + &mut CheckTypeWellFormed<'b, 'gcx>) -> Vec> { let id = self.id; let span = self.span; let param_env = self.param_env; self.inherited.enter(|inh| { let fcx = FnCtxt::new(&inh, param_env, id); - let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor { + let wf_tys = f(&fcx, &mut CheckTypeWellFormed { tcx: fcx.tcx.global_tcx(), }); fcx.select_all_obligations_or_error(); @@ -59,10 +59,10 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { +impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) - -> CheckTypeWellFormedVisitor<'a, 'gcx> { - CheckTypeWellFormedVisitor { + -> CheckTypeWellFormed<'a, 'gcx> { + CheckTypeWellFormed { tcx, } } @@ -78,11 +78,14 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { /// We do this check as a pre-pass before checking fn bodies because if these constraints are /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. - fn check_item_well_formed(&mut self, item: &hir::Item) { + pub fn check_item_well_formed(&mut self, def_id: DefId) { let tcx = self.tcx; + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let item = tcx.hir.expect_item(node_id); + debug!("check_item_well_formed(it.id={}, it.name={})", item.id, - tcx.item_path_str(tcx.hir.local_def_id(item.id))); + tcx.item_path_str(def_id)); match item.node { // Right now we check that every default trait implementation @@ -259,7 +262,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // All field types must be well-formed. for field in &variant.fields { - fcx.register_wf_obligation(field.ty, field.span, ObligationCauseCode::MiscObligation) + fcx.register_wf_obligation(field.ty, field.span, + ObligationCauseCode::MiscObligation) } } @@ -333,7 +337,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { None => { let self_ty = fcx.tcx.type_of(item_def_id); let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); - fcx.register_wf_obligation(self_ty, ast_self_ty.span, ObligationCauseCode::MiscObligation); + fcx.register_wf_obligation(self_ty, ast_self_ty.span, + ObligationCauseCode::MiscObligation); } } @@ -368,7 +373,8 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { // parameter includes another (e.g., ). In those cases, we can't // be sure if it will error or not as user might always specify the other. if !ty.needs_subst() { - fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), ObligationCauseCode::MiscObligation); + fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), + ObligationCauseCode::MiscObligation); } } @@ -642,6 +648,19 @@ fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { } } +pub struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, +} + +impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { + pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) + -> CheckTypeWellFormedVisitor<'a, 'gcx> { + CheckTypeWellFormedVisitor { + tcx, + } + } +} + impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> { NestedVisitorMap::None @@ -649,7 +668,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn visit_item(&mut self, i: &hir::Item) { debug!("visit_item: {:?}", i); - self.check_item_well_formed(i); + let def_id = self.tcx.hir.local_def_id(i.id); + ty::maps::queries::check_item_well_formed::ensure(self.tcx, def_id); intravisit::walk_item(self, i); } @@ -659,7 +679,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { hir::TraitItemKind::Method(ref sig, _) => Some(sig), _ => None }; - self.check_associated_item(trait_item.id, trait_item.span, method_sig); + CheckTypeWellFormed::new(self.tcx) + .check_associated_item(trait_item.id, trait_item.span, method_sig); intravisit::walk_trait_item(self, trait_item) } @@ -669,7 +690,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { hir::ImplItemKind::Method(ref sig, _) => Some(sig), _ => None }; - self.check_associated_item(impl_item.id, impl_item.span, method_sig); + CheckTypeWellFormed::new(self.tcx) + .check_associated_item(impl_item.id, impl_item.span, method_sig); intravisit::walk_impl_item(self, impl_item) } } From edbd02fd35ffd3724a415c05c21e4e4fc5575e1e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 10 Mar 2018 11:25:03 -0500 Subject: [PATCH 261/830] Queryify check_trait_item_well_formed Fixes #46753 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/mod.rs | 1 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_typeck/check/mod.rs | 5 +++++ src/librustc_typeck/check/wfcheck.rs | 20 ++++++++++++++------ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 20c3fb501572..9cb59da47bd9 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -580,6 +580,7 @@ define_dep_nodes!( <'tcx> [] IsNoBuiltins(CrateNum), [] ImplDefaultness(DefId), [] CheckItemWellFormed(DefId), + [] CheckTraitItemWellFormed(DefId), [] ReachableNonGenerics(CrateNum), [] NativeLibraries(CrateNum), [] PluginRegistrarFn(CrateNum), diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 8f4100ad5f70..3e2015604744 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -299,6 +299,7 @@ define_maps! { <'tcx> [] fn impl_defaultness: ImplDefaultness(DefId) -> hir::Defaultness, [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (), + [] fn check_trait_item_well_formed: CheckTraitItemWellFormed(DefId) -> (), // The DefIds of all non-generic functions and statics in the given crate // that can be reached from outside the crate. diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 732c91ea98aa..2eba72a590e3 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -872,6 +872,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::IsNoBuiltins => { force!(is_no_builtins, krate!()); } DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); } DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); } + DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); } DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); } DepKind::NativeLibraries => { force!(native_libraries, krate!()); } DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a6b307b84149..9ffe029468d3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -722,6 +722,10 @@ fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) wfcheck::CheckTypeWellFormed::new(tcx).check_item_well_formed(def_id); } +fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + wfcheck::CheckTypeWellFormed::new(tcx).check_trait_item(def_id); +} + pub fn provide(providers: &mut Providers) { *providers = Providers { typeck_item_bodies, @@ -730,6 +734,7 @@ pub fn provide(providers: &mut Providers) { adt_destructor, used_trait_imports, check_item_well_formed, + check_trait_item_well_formed, ..*providers }; } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d665e55898d4..c80e0b8bba06 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -159,6 +159,18 @@ impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { } } + pub fn check_trait_item(&mut self, def_id: DefId) { + let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); + let trait_item = self.tcx.hir.expect_trait_item(node_id); + + let method_sig = match trait_item.node { + hir::TraitItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + CheckTypeWellFormed::new(self.tcx) + .check_associated_item(trait_item.id, trait_item.span, method_sig); + } + fn check_associated_item(&mut self, item_id: ast::NodeId, span: Span, @@ -675,12 +687,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) { debug!("visit_trait_item: {:?}", trait_item); - let method_sig = match trait_item.node { - hir::TraitItemKind::Method(ref sig, _) => Some(sig), - _ => None - }; - CheckTypeWellFormed::new(self.tcx) - .check_associated_item(trait_item.id, trait_item.span, method_sig); + let def_id = self.tcx.hir.local_def_id(trait_item.id); + ty::maps::queries::check_trait_item_well_formed::ensure(self.tcx, def_id); intravisit::walk_trait_item(self, trait_item) } From 4f1f389d06a32bc64e1f75b11a2a84c8e8ae9af5 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 10 Mar 2018 17:17:30 -0500 Subject: [PATCH 262/830] Queryify check_impl_item_well_formed Fixes #46753 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/mod.rs | 1 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_typeck/check/mod.rs | 5 +++++ src/librustc_typeck/check/wfcheck.rs | 19 +++++++++++++------ 5 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 9cb59da47bd9..13cf7a9ec8f1 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -581,6 +581,7 @@ define_dep_nodes!( <'tcx> [] ImplDefaultness(DefId), [] CheckItemWellFormed(DefId), [] CheckTraitItemWellFormed(DefId), + [] CheckImplItemWellFormed(DefId), [] ReachableNonGenerics(CrateNum), [] NativeLibraries(CrateNum), [] PluginRegistrarFn(CrateNum), diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 3e2015604744..4dcd7c20c33d 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -300,6 +300,7 @@ define_maps! { <'tcx> [] fn check_item_well_formed: CheckItemWellFormed(DefId) -> (), [] fn check_trait_item_well_formed: CheckTraitItemWellFormed(DefId) -> (), + [] fn check_impl_item_well_formed: CheckImplItemWellFormed(DefId) -> (), // The DefIds of all non-generic functions and statics in the given crate // that can be reached from outside the crate. diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 2eba72a590e3..267d7da5e0c2 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -873,6 +873,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::ImplDefaultness => { force!(impl_defaultness, def_id!()); } DepKind::CheckItemWellFormed => { force!(check_item_well_formed, def_id!()); } DepKind::CheckTraitItemWellFormed => { force!(check_trait_item_well_formed, def_id!()); } + DepKind::CheckImplItemWellFormed => { force!(check_impl_item_well_formed, def_id!()); } DepKind::ReachableNonGenerics => { force!(reachable_non_generics, krate!()); } DepKind::NativeLibraries => { force!(native_libraries, krate!()); } DepKind::PluginRegistrarFn => { force!(plugin_registrar_fn, krate!()); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9ffe029468d3..5b3a4529f1a0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -726,6 +726,10 @@ fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D wfcheck::CheckTypeWellFormed::new(tcx).check_trait_item(def_id); } +fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + wfcheck::CheckTypeWellFormed::new(tcx).check_impl_item(def_id); +} + pub fn provide(providers: &mut Providers) { *providers = Providers { typeck_item_bodies, @@ -735,6 +739,7 @@ pub fn provide(providers: &mut Providers) { used_trait_imports, check_item_well_formed, check_trait_item_well_formed, + check_impl_item_well_formed, ..*providers }; } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index c80e0b8bba06..72f40627b831 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -171,6 +171,17 @@ impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { .check_associated_item(trait_item.id, trait_item.span, method_sig); } + pub fn check_impl_item(&mut self, def_id: DefId) { + let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); + let impl_item = self.tcx.hir.expect_impl_item(node_id); + + let method_sig = match impl_item.node { + hir::ImplItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + self.check_associated_item(impl_item.id, impl_item.span, method_sig); + } + fn check_associated_item(&mut self, item_id: ast::NodeId, span: Span, @@ -694,12 +705,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> { fn visit_impl_item(&mut self, impl_item: &'v hir::ImplItem) { debug!("visit_impl_item: {:?}", impl_item); - let method_sig = match impl_item.node { - hir::ImplItemKind::Method(ref sig, _) => Some(sig), - _ => None - }; - CheckTypeWellFormed::new(self.tcx) - .check_associated_item(impl_item.id, impl_item.span, method_sig); + let def_id = self.tcx.hir.local_def_id(impl_item.id); + ty::maps::queries::check_impl_item_well_formed::ensure(self.tcx, def_id); intravisit::walk_impl_item(self, impl_item) } } From b418b7ba0f7393d789860f96a718a4fba2729271 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Mon, 12 Mar 2018 22:18:51 -0400 Subject: [PATCH 263/830] Remove CheckTypeWellFormed struct and convert to free functions Related to #48939 --- src/librustc_typeck/check/mod.rs | 6 +- src/librustc_typeck/check/wfcheck.rs | 1033 +++++++++++++------------- 2 files changed, 511 insertions(+), 528 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5b3a4529f1a0..8b5d45d6aa11 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -719,15 +719,15 @@ fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum } fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { - wfcheck::CheckTypeWellFormed::new(tcx).check_item_well_formed(def_id); + wfcheck::check_item_well_formed(tcx, def_id); } fn check_trait_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { - wfcheck::CheckTypeWellFormed::new(tcx).check_trait_item(def_id); + wfcheck::check_trait_item(tcx, def_id); } fn check_impl_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { - wfcheck::CheckTypeWellFormed::new(tcx).check_impl_item(def_id); + wfcheck::check_impl_item(tcx, def_id); } pub fn provide(providers: &mut Providers) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 72f40627b831..406ff9463a03 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -26,10 +26,6 @@ use errors::{DiagnosticBuilder, DiagnosticId}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -pub struct CheckTypeWellFormed<'a, 'tcx:'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, -} - /// Helper type of a temporary returned by .for_item(...). /// Necessary because we can't write the following bound: /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>). @@ -43,612 +39,599 @@ struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { fn with_fcx(&'tcx mut self, f: F) where F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>, - &mut CheckTypeWellFormed<'b, 'gcx>) -> Vec> + TyCtxt<'b, 'gcx, 'gcx>) -> Vec> { let id = self.id; let span = self.span; let param_env = self.param_env; self.inherited.enter(|inh| { let fcx = FnCtxt::new(&inh, param_env, id); - let wf_tys = f(&fcx, &mut CheckTypeWellFormed { - tcx: fcx.tcx.global_tcx(), - }); + let wf_tys = f(&fcx, fcx.tcx.global_tcx()); fcx.select_all_obligations_or_error(); fcx.regionck_item(id, span, &wf_tys); }); } } -impl<'a, 'gcx> CheckTypeWellFormed<'a, 'gcx> { - pub fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) - -> CheckTypeWellFormed<'a, 'gcx> { - CheckTypeWellFormed { - tcx, - } - } +/// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are +/// well-formed, meaning that they do not require any constraints not declared in the struct +/// definition itself. For example, this definition would be illegal: +/// +/// struct Ref<'a, T> { x: &'a T } +/// +/// because the type did not declare that `T:'a`. +/// +/// We do this check as a pre-pass before checking fn bodies because if these constraints are +/// not included it frequently leads to confusing errors in fn bodies. So it's better to check +/// the types first. +pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let item = tcx.hir.expect_item(node_id); - /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are - /// well-formed, meaning that they do not require any constraints not declared in the struct - /// definition itself. For example, this definition would be illegal: - /// - /// struct Ref<'a, T> { x: &'a T } - /// - /// because the type did not declare that `T:'a`. - /// - /// We do this check as a pre-pass before checking fn bodies because if these constraints are - /// not included it frequently leads to confusing errors in fn bodies. So it's better to check - /// the types first. - pub fn check_item_well_formed(&mut self, def_id: DefId) { - let tcx = self.tcx; - let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); - let item = tcx.hir.expect_item(node_id); + debug!("check_item_well_formed(it.id={}, it.name={})", + item.id, + tcx.item_path_str(def_id)); - debug!("check_item_well_formed(it.id={}, it.name={})", - item.id, - tcx.item_path_str(def_id)); - - match item.node { - // Right now we check that every default trait implementation - // has an implementation of itself. Basically, a case like: - // - // `impl Trait for T {}` - // - // has a requirement of `T: Trait` which was required for default - // method implementations. Although this could be improved now that - // there's a better infrastructure in place for this, it's being left - // for a follow-up work. - // - // Since there's such a requirement, we need to check *just* positive - // implementations, otherwise things like: - // - // impl !Send for T {} - // - // won't be allowed unless there's an *explicit* implementation of `Send` - // for `T` - hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => { - let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)) - .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); - if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) { - tcx.sess.span_err(item.span, "impls of auto traits cannot be default"); - } - if polarity == hir::ImplPolarity::Positive { - self.check_impl(item, self_ty, trait_ref); - } else { - // FIXME(#27579) what amount of WF checking do we need for neg impls? - if trait_ref.is_some() && !is_auto { - span_err!(tcx.sess, item.span, E0192, - "negative impls are only allowed for \ - auto traits (e.g., `Send` and `Sync`)") - } + match item.node { + // Right now we check that every default trait implementation + // has an implementation of itself. Basically, a case like: + // + // `impl Trait for T {}` + // + // has a requirement of `T: Trait` which was required for default + // method implementations. Although this could be improved now that + // there's a better infrastructure in place for this, it's being left + // for a follow-up work. + // + // Since there's such a requirement, we need to check *just* positive + // implementations, otherwise things like: + // + // impl !Send for T {} + // + // won't be allowed unless there's an *explicit* implementation of `Send` + // for `T` + hir::ItemImpl(_, polarity, defaultness, _, ref trait_ref, ref self_ty, _) => { + let is_auto = tcx.impl_trait_ref(tcx.hir.local_def_id(item.id)) + .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); + if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) { + tcx.sess.span_err(item.span, "impls of auto traits cannot be default"); + } + if polarity == hir::ImplPolarity::Positive { + check_impl(tcx, item, self_ty, trait_ref); + } else { + // FIXME(#27579) what amount of WF checking do we need for neg impls? + if trait_ref.is_some() && !is_auto { + span_err!(tcx.sess, item.span, E0192, + "negative impls are only allowed for \ + auto traits (e.g., `Send` and `Sync`)") } } - hir::ItemFn(..) => { - self.check_item_fn(item); - } - hir::ItemStatic(..) => { - self.check_item_type(item); - } - hir::ItemConst(..) => { - self.check_item_type(item); - } - hir::ItemStruct(ref struct_def, ref ast_generics) => { - self.check_type_defn(item, false, |fcx| { - vec![fcx.non_enum_variant(struct_def)] - }); - - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemUnion(ref struct_def, ref ast_generics) => { - self.check_type_defn(item, true, |fcx| { - vec![fcx.non_enum_variant(struct_def)] - }); - - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemEnum(ref enum_def, ref ast_generics) => { - self.check_type_defn(item, true, |fcx| { - fcx.enum_variants(enum_def) - }); - - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemTrait(..) => { - self.check_trait(item); - } - _ => {} } + hir::ItemFn(..) => { + check_item_fn(tcx, item); + } + hir::ItemStatic(..) => { + check_item_type(tcx, item); + } + hir::ItemConst(..) => { + check_item_type(tcx, item); + } + hir::ItemStruct(ref struct_def, ref ast_generics) => { + check_type_defn(tcx, item, false, |fcx| { + vec![fcx.non_enum_variant(struct_def)] + }); + + check_variances_for_type_defn(tcx, item, ast_generics); + } + hir::ItemUnion(ref struct_def, ref ast_generics) => { + check_type_defn(tcx, item, true, |fcx| { + vec![fcx.non_enum_variant(struct_def)] + }); + + check_variances_for_type_defn(tcx, item, ast_generics); + } + hir::ItemEnum(ref enum_def, ref ast_generics) => { + check_type_defn(tcx, item, true, |fcx| { + fcx.enum_variants(enum_def) + }); + + check_variances_for_type_defn(tcx, item, ast_generics); + } + hir::ItemTrait(..) => { + check_trait(tcx, item); + } + _ => {} } +} - pub fn check_trait_item(&mut self, def_id: DefId) { - let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); - let trait_item = self.tcx.hir.expect_trait_item(node_id); +pub fn check_trait_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let trait_item = tcx.hir.expect_trait_item(node_id); - let method_sig = match trait_item.node { - hir::TraitItemKind::Method(ref sig, _) => Some(sig), - _ => None + let method_sig = match trait_item.node { + hir::TraitItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + check_associated_item(tcx, trait_item.id, trait_item.span, method_sig); +} + +pub fn check_impl_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) { + let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); + let impl_item = tcx.hir.expect_impl_item(node_id); + + let method_sig = match impl_item.node { + hir::ImplItemKind::Method(ref sig, _) => Some(sig), + _ => None + }; + check_associated_item(tcx, impl_item.id, impl_item.span, method_sig); +} + +fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_id: ast::NodeId, + span: Span, + sig_if_method: Option<&hir::MethodSig>) { + let code = ObligationCauseCode::MiscObligation; + for_id(tcx, item_id, span).with_fcx(|fcx, tcx| { + let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); + + let (mut implied_bounds, self_ty) = match item.container { + ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()), + ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span), + fcx.tcx.type_of(def_id)) }; - CheckTypeWellFormed::new(self.tcx) - .check_associated_item(trait_item.id, trait_item.span, method_sig); - } - pub fn check_impl_item(&mut self, def_id: DefId) { - let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap(); - let impl_item = self.tcx.hir.expect_impl_item(node_id); - - let method_sig = match impl_item.node { - hir::ImplItemKind::Method(ref sig, _) => Some(sig), - _ => None - }; - self.check_associated_item(impl_item.id, impl_item.span, method_sig); - } - - fn check_associated_item(&mut self, - item_id: ast::NodeId, - span: Span, - sig_if_method: Option<&hir::MethodSig>) { - let code = ObligationCauseCode::MiscObligation; - self.for_id(item_id, span).with_fcx(|fcx, this| { - let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); - - let (mut implied_bounds, self_ty) = match item.container { - ty::TraitContainer(_) => (vec![], fcx.tcx.mk_self_type()), - ty::ImplContainer(def_id) => (fcx.impl_implied_bounds(def_id, span), - fcx.tcx.type_of(def_id)) - }; - - match item.kind { - ty::AssociatedKind::Const => { + match item.kind { + ty::AssociatedKind::Const => { + let ty = fcx.tcx.type_of(item.def_id); + let ty = fcx.normalize_associated_types_in(span, &ty); + fcx.register_wf_obligation(ty, span, code.clone()); + } + ty::AssociatedKind::Method => { + reject_shadowing_type_parameters(fcx.tcx, item.def_id); + let sig = fcx.tcx.fn_sig(item.def_id); + let sig = fcx.normalize_associated_types_in(span, &sig); + check_fn_or_method(tcx, fcx, span, sig, + item.def_id, &mut implied_bounds); + let sig_if_method = sig_if_method.expect("bad signature for method"); + check_method_receiver(fcx, sig_if_method, &item, self_ty); + } + ty::AssociatedKind::Type => { + if item.defaultness.has_value() { let ty = fcx.tcx.type_of(item.def_id); let ty = fcx.normalize_associated_types_in(span, &ty); fcx.register_wf_obligation(ty, span, code.clone()); } - ty::AssociatedKind::Method => { - reject_shadowing_type_parameters(fcx.tcx, item.def_id); - let sig = fcx.tcx.fn_sig(item.def_id); - let sig = fcx.normalize_associated_types_in(span, &sig); - this.check_fn_or_method(fcx, span, sig, - item.def_id, &mut implied_bounds); - let sig_if_method = sig_if_method.expect("bad signature for method"); - this.check_method_receiver(fcx, sig_if_method, &item, self_ty); - } - ty::AssociatedKind::Type => { - if item.defaultness.has_value() { - let ty = fcx.tcx.type_of(item.def_id); - let ty = fcx.normalize_associated_types_in(span, &ty); - fcx.register_wf_obligation(ty, span, code.clone()); - } - } } - - implied_bounds - }) - } - - fn for_item<'tcx>(&self, item: &hir::Item) - -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { - self.for_id(item.id, item.span) - } - - fn for_id<'tcx>(&self, id: ast::NodeId, span: Span) - -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { - let def_id = self.tcx.hir.local_def_id(id); - CheckWfFcxBuilder { - inherited: Inherited::build(self.tcx, def_id), - id, - span, - param_env: self.tcx.param_env(def_id), } + + implied_bounds + }) +} + +fn for_item<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, item: &hir::Item) + -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { + for_id(tcx, item.id, item.span) +} + +fn for_id<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, id: ast::NodeId, span: Span) + -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { + let def_id = tcx.hir.local_def_id(id); + CheckWfFcxBuilder { + inherited: Inherited::build(tcx, def_id), + id, + span, + param_env: tcx.param_env(def_id), } +} - /// In a type definition, we check that to ensure that the types of the fields are well-formed. - fn check_type_defn(&mut self, item: &hir::Item, all_sized: bool, mut lookup_fields: F) - where F: for<'fcx, 'tcx> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx>) -> Vec> - { - self.for_item(item).with_fcx(|fcx, this| { - let variants = lookup_fields(fcx); - let def_id = fcx.tcx.hir.local_def_id(item.id); - let packed = fcx.tcx.adt_def(def_id).repr.packed(); +/// In a type definition, we check that to ensure that the types of the fields are well-formed. +fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item, all_sized: bool, mut lookup_fields: F) + where F: for<'fcx, 'gcx, 'tcx2> FnMut(&FnCtxt<'fcx, 'gcx, 'tcx2>) -> Vec> +{ + for_item(tcx, item).with_fcx(|fcx, fcx_tcx| { + let variants = lookup_fields(fcx); + let def_id = fcx.tcx.hir.local_def_id(item.id); + let packed = fcx.tcx.adt_def(def_id).repr.packed(); - for variant in &variants { - // For DST, or when drop needs to copy things around, all - // intermediate types must be sized. - let needs_drop_copy = || { - packed && { - let ty = variant.fields.last().unwrap().ty; - let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(this.tcx) - .unwrap_or_else(|| { - span_bug!(item.span, "inference variables in {:?}", ty) - }); - ty.needs_drop(this.tcx, this.tcx.param_env(def_id)) - } - }; - let unsized_len = if - all_sized || - variant.fields.is_empty() || - needs_drop_copy() - { - 0 - } else { - 1 - }; - for field in &variant.fields[..variant.fields.len() - unsized_len] { - fcx.register_bound( - field.ty, - fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem), - traits::ObligationCause::new(field.span, - fcx.body_id, - traits::FieldSized(match item.node.adt_kind() { - Some(i) => i, - None => bug!(), - }))); - } - - // All field types must be well-formed. - for field in &variant.fields { - fcx.register_wf_obligation(field.ty, field.span, - ObligationCauseCode::MiscObligation) + for variant in &variants { + // For DST, or when drop needs to copy things around, all + // intermediate types must be sized. + let needs_drop_copy = || { + packed && { + let ty = variant.fields.last().unwrap().ty; + let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx) + .unwrap_or_else(|| { + span_bug!(item.span, "inference variables in {:?}", ty) + }); + ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)) } + }; + let unsized_len = if + all_sized || + variant.fields.is_empty() || + needs_drop_copy() + { + 0 + } else { + 1 + }; + for field in &variant.fields[..variant.fields.len() - unsized_len] { + fcx.register_bound( + field.ty, + fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem), + traits::ObligationCause::new(field.span, + fcx.body_id, + traits::FieldSized(match item.node.adt_kind() { + Some(i) => i, + None => bug!(), + }))); } - self.check_where_clauses(fcx, item.span, def_id); + // All field types must be well-formed. + for field in &variant.fields { + fcx.register_wf_obligation(field.ty, field.span, + ObligationCauseCode::MiscObligation) + } + } - vec![] // no implied bounds in a struct def'n - }); - } + check_where_clauses(tcx, fcx, item.span, def_id); - fn check_trait(&mut self, item: &hir::Item) { - let trait_def_id = self.tcx.hir.local_def_id(item.id); - self.for_item(item).with_fcx(|fcx, _| { - self.check_where_clauses(fcx, item.span, trait_def_id); - vec![] - }); - } + vec![] // no implied bounds in a struct def'n + }); +} - fn check_item_fn(&mut self, item: &hir::Item) { - self.for_item(item).with_fcx(|fcx, this| { - let def_id = fcx.tcx.hir.local_def_id(item.id); - let sig = fcx.tcx.fn_sig(def_id); - let sig = fcx.normalize_associated_types_in(item.span, &sig); - let mut implied_bounds = vec![]; - this.check_fn_or_method(fcx, item.span, sig, - def_id, &mut implied_bounds); - implied_bounds - }) - } +fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { + let trait_def_id = tcx.hir.local_def_id(item.id); + for_item(tcx, item).with_fcx(|fcx, _| { + check_where_clauses(tcx, fcx, item.span, trait_def_id); + vec![] + }); +} - fn check_item_type(&mut self, - item: &hir::Item) - { - debug!("check_item_type: {:?}", item); +fn check_item_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { + for_item(tcx, item).with_fcx(|fcx, tcx| { + let def_id = fcx.tcx.hir.local_def_id(item.id); + let sig = fcx.tcx.fn_sig(def_id); + let sig = fcx.normalize_associated_types_in(item.span, &sig); + let mut implied_bounds = vec![]; + check_fn_or_method(tcx, fcx, item.span, sig, + def_id, &mut implied_bounds); + implied_bounds + }) +} - self.for_item(item).with_fcx(|fcx, _this| { - let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id)); - let item_ty = fcx.normalize_associated_types_in(item.span, &ty); +fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item) +{ + debug!("check_item_type: {:?}", item); - fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation); + for_item(tcx, item).with_fcx(|fcx, _this| { + let ty = fcx.tcx.type_of(fcx.tcx.hir.local_def_id(item.id)); + let item_ty = fcx.normalize_associated_types_in(item.span, &ty); - vec![] // no implied bounds in a const etc - }); - } + fcx.register_wf_obligation(item_ty, item.span, ObligationCauseCode::MiscObligation); - fn check_impl(&mut self, - item: &hir::Item, - ast_self_ty: &hir::Ty, - ast_trait_ref: &Option) - { - debug!("check_impl: {:?}", item); + vec![] // no implied bounds in a const etc + }); +} - self.for_item(item).with_fcx(|fcx, this| { - let item_def_id = fcx.tcx.hir.local_def_id(item.id); +fn check_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item, + ast_self_ty: &hir::Ty, + ast_trait_ref: &Option) +{ + debug!("check_impl: {:?}", item); - match *ast_trait_ref { - Some(ref ast_trait_ref) => { - let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap(); - let trait_ref = - fcx.normalize_associated_types_in( - ast_trait_ref.path.span, &trait_ref); - let obligations = - ty::wf::trait_obligations(fcx, - fcx.param_env, - fcx.body_id, - &trait_ref, - ast_trait_ref.path.span); - for obligation in obligations { - fcx.register_predicate(obligation); - } - } - None => { - let self_ty = fcx.tcx.type_of(item_def_id); - let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); - fcx.register_wf_obligation(self_ty, ast_self_ty.span, - ObligationCauseCode::MiscObligation); + for_item(tcx, item).with_fcx(|fcx, tcx| { + let item_def_id = fcx.tcx.hir.local_def_id(item.id); + + match *ast_trait_ref { + Some(ref ast_trait_ref) => { + let trait_ref = fcx.tcx.impl_trait_ref(item_def_id).unwrap(); + let trait_ref = + fcx.normalize_associated_types_in( + ast_trait_ref.path.span, &trait_ref); + let obligations = + ty::wf::trait_obligations(fcx, + fcx.param_env, + fcx.body_id, + &trait_ref, + ast_trait_ref.path.span); + for obligation in obligations { + fcx.register_predicate(obligation); } } - - this.check_where_clauses(fcx, item.span, item_def_id); - - fcx.impl_implied_bounds(item_def_id, item.span) - }); - } - - /// Checks where clauses and inline bounds that are declared on def_id. - fn check_where_clauses<'fcx, 'tcx>(&mut self, - fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, - span: Span, - def_id: DefId) { - use ty::subst::Subst; - use rustc::ty::TypeFoldable; - - let mut predicates = fcx.tcx.predicates_of(def_id); - let mut substituted_predicates = Vec::new(); - - let generics = self.tcx.generics_of(def_id); - let is_our_default = |def: &ty::TypeParameterDef| - def.has_default && def.index >= generics.parent_count() as u32; - - // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. - // For example this forbids the declaration: - // struct Foo> { .. } - // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. - for d in generics.types.iter().cloned().filter(is_our_default).map(|p| p.def_id) { - let ty = fcx.tcx.type_of(d); - // ignore dependent defaults -- that is, where the default of one type - // parameter includes another (e.g., ). In those cases, we can't - // be sure if it will error or not as user might always specify the other. - if !ty.needs_subst() { - fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), + None => { + let self_ty = fcx.tcx.type_of(item_def_id); + let self_ty = fcx.normalize_associated_types_in(item.span, &self_ty); + fcx.register_wf_obligation(self_ty, ast_self_ty.span, ObligationCauseCode::MiscObligation); } } - // Check that trait predicates are WF when params are substituted by their defaults. - // We don't want to overly constrain the predicates that may be written but we want to - // catch cases where a default my never be applied such as `struct Foo`. - // Therefore we check if a predicate which contains a single type param - // with a concrete default is WF with that default substituted. - // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. - // - // First we build the defaulted substitution. - let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| { - // All regions are identity. - fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data())) - }, |def, _| { - // If the param has a default, - if is_our_default(def) { - let default_ty = fcx.tcx.type_of(def.def_id); - // and it's not a dependent default - if !default_ty.needs_subst() { - // then substitute with the default. - return default_ty; - } - } - // Mark unwanted params as err. - fcx.tcx.types.err - }); - // Now we build the substituted predicates. - for &pred in predicates.predicates.iter() { - struct CountParams { params: FxHashSet } - impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { - fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - match t.sty { - ty::TyParam(p) => { - self.params.insert(p.idx); - t.super_visit_with(self) - } - _ => t.super_visit_with(self) - } - } - } - let mut param_count = CountParams { params: FxHashSet() }; - pred.visit_with(&mut param_count); - let substituted_pred = pred.subst(fcx.tcx, substs); - // Don't check non-defaulted params, dependent defaults or preds with multiple params. - if substituted_pred.references_error() || param_count.params.len() > 1 { - continue; - } - // Avoid duplication of predicates that contain no parameters, for example. - if !predicates.predicates.contains(&substituted_pred) { - substituted_predicates.push(substituted_pred); - } - } + check_where_clauses(tcx, fcx, item.span, item_def_id); - predicates.predicates.extend(substituted_predicates); - let predicates = predicates.instantiate_identity(fcx.tcx); - let predicates = fcx.normalize_associated_types_in(span, &predicates); + fcx.impl_implied_bounds(item_def_id, item.span) + }); +} - let obligations = - predicates.predicates - .iter() - .flat_map(|p| ty::wf::predicate_obligations(fcx, - fcx.param_env, - fcx.body_id, - p, - span)); +/// Checks where clauses and inline bounds that are declared on def_id. +fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, + fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, + span: Span, + def_id: DefId) { + use ty::subst::Subst; + use rustc::ty::TypeFoldable; - for obligation in obligations { - fcx.register_predicate(obligation); + let mut predicates = fcx.tcx.predicates_of(def_id); + let mut substituted_predicates = Vec::new(); + + let generics = tcx.generics_of(def_id); + let is_our_default = |def: &ty::TypeParameterDef| + def.has_default && def.index >= generics.parent_count() as u32; + + // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. + // For example this forbids the declaration: + // struct Foo> { .. } + // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. + for d in generics.types.iter().cloned().filter(is_our_default).map(|p| p.def_id) { + let ty = fcx.tcx.type_of(d); + // ignore dependent defaults -- that is, where the default of one type + // parameter includes another (e.g., ). In those cases, we can't + // be sure if it will error or not as user might always specify the other. + if !ty.needs_subst() { + fcx.register_wf_obligation(ty, fcx.tcx.def_span(d), + ObligationCauseCode::MiscObligation); } } - fn check_fn_or_method<'fcx, 'tcx>(&mut self, - fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, - span: Span, - sig: ty::PolyFnSig<'tcx>, - def_id: DefId, - implied_bounds: &mut Vec>) - { - let sig = fcx.normalize_associated_types_in(span, &sig); - let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); - - for input_ty in sig.inputs() { - fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); + // Check that trait predicates are WF when params are substituted by their defaults. + // We don't want to overly constrain the predicates that may be written but we want to + // catch cases where a default my never be applied such as `struct Foo`. + // Therefore we check if a predicate which contains a single type param + // with a concrete default is WF with that default substituted. + // For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`. + // + // First we build the defaulted substitution. + let substs = ty::subst::Substs::for_item(fcx.tcx, def_id, |def, _| { + // All regions are identity. + fcx.tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data())) + }, |def, _| { + // If the param has a default, + if is_our_default(def) { + let default_ty = fcx.tcx.type_of(def.def_id); + // and it's not a dependent default + if !default_ty.needs_subst() { + // then substitute with the default. + return default_ty; + } + } + // Mark unwanted params as err. + fcx.tcx.types.err + }); + // Now we build the substituted predicates. + for &pred in predicates.predicates.iter() { + struct CountParams { params: FxHashSet } + impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + match t.sty { + ty::TyParam(p) => { + self.params.insert(p.idx); + t.super_visit_with(self) + } + _ => t.super_visit_with(self) + } + } + } + let mut param_count = CountParams { params: FxHashSet() }; + pred.visit_with(&mut param_count); + let substituted_pred = pred.subst(fcx.tcx, substs); + // Don't check non-defaulted params, dependent defaults or preds with multiple params. + if substituted_pred.references_error() || param_count.params.len() > 1 { + continue; + } + // Avoid duplication of predicates that contain no parameters, for example. + if !predicates.predicates.contains(&substituted_pred) { + substituted_predicates.push(substituted_pred); } - implied_bounds.extend(sig.inputs()); - - fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation); - - // FIXME(#25759) return types should not be implied bounds - implied_bounds.push(sig.output()); - - self.check_where_clauses(fcx, span, def_id); } - fn check_method_receiver<'fcx, 'tcx>(&mut self, - fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, - method_sig: &hir::MethodSig, - method: &ty::AssociatedItem, - self_ty: Ty<'tcx>) - { - // check that the method has a valid receiver type, given the type `Self` - debug!("check_method_receiver({:?}, self_ty={:?})", - method, self_ty); + predicates.predicates.extend(substituted_predicates); + let predicates = predicates.instantiate_identity(fcx.tcx); + let predicates = fcx.normalize_associated_types_in(span, &predicates); - if !method.method_has_self_argument { - return; - } + let obligations = + predicates.predicates + .iter() + .flat_map(|p| ty::wf::predicate_obligations(fcx, + fcx.param_env, + fcx.body_id, + p, + span)); - let span = method_sig.decl.inputs[0].span; + for obligation in obligations { + fcx.register_predicate(obligation); + } +} - let sig = fcx.tcx.fn_sig(method.def_id); - let sig = fcx.normalize_associated_types_in(span, &sig); - let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig); +fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, + fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, + span: Span, + sig: ty::PolyFnSig<'tcx>, + def_id: DefId, + implied_bounds: &mut Vec>) +{ + let sig = fcx.normalize_associated_types_in(span, &sig); + let sig = fcx.tcx.liberate_late_bound_regions(def_id, &sig); - debug!("check_method_receiver: sig={:?}", sig); + for input_ty in sig.inputs() { + fcx.register_wf_obligation(&input_ty, span, ObligationCauseCode::MiscObligation); + } + implied_bounds.extend(sig.inputs()); - let self_ty = fcx.normalize_associated_types_in(span, &self_ty); - let self_ty = fcx.tcx.liberate_late_bound_regions( - method.def_id, - &ty::Binder(self_ty) - ); + fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation); - let self_arg_ty = sig.inputs()[0]; + // FIXME(#25759) return types should not be implied bounds + implied_bounds.push(sig.output()); - let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver); - let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty); - let self_arg_ty = fcx.tcx.liberate_late_bound_regions( - method.def_id, - &ty::Binder(self_arg_ty) - ); + check_where_clauses(tcx, fcx, span, def_id); +} - let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers(); +fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, + method_sig: &hir::MethodSig, + method: &ty::AssociatedItem, + self_ty: Ty<'tcx>) +{ + // check that the method has a valid receiver type, given the type `Self` + debug!("check_method_receiver({:?}, self_ty={:?})", + method, self_ty); - loop { - if let Some((potential_self_ty, _)) = autoderef.next() { - debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`", - potential_self_ty, self_ty); + if !method.method_has_self_argument { + return; + } - if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() { - autoderef.finalize(); - if let Some(mut err) = fcx.demand_eqtype_with_origin( - &cause, self_ty, potential_self_ty) { - err.emit(); - } - break + let span = method_sig.decl.inputs[0].span; + + let sig = fcx.tcx.fn_sig(method.def_id); + let sig = fcx.normalize_associated_types_in(span, &sig); + let sig = fcx.tcx.liberate_late_bound_regions(method.def_id, &sig); + + debug!("check_method_receiver: sig={:?}", sig); + + let self_ty = fcx.normalize_associated_types_in(span, &self_ty); + let self_ty = fcx.tcx.liberate_late_bound_regions( + method.def_id, + &ty::Binder(self_ty) + ); + + let self_arg_ty = sig.inputs()[0]; + + let cause = fcx.cause(span, ObligationCauseCode::MethodReceiver); + let self_arg_ty = fcx.normalize_associated_types_in(span, &self_arg_ty); + let self_arg_ty = fcx.tcx.liberate_late_bound_regions( + method.def_id, + &ty::Binder(self_arg_ty) + ); + + let mut autoderef = fcx.autoderef(span, self_arg_ty).include_raw_pointers(); + + loop { + if let Some((potential_self_ty, _)) = autoderef.next() { + debug!("check_method_receiver: potential self type `{:?}` to match `{:?}`", + potential_self_ty, self_ty); + + if fcx.infcx.can_eq(fcx.param_env, self_ty, potential_self_ty).is_ok() { + autoderef.finalize(); + if let Some(mut err) = fcx.demand_eqtype_with_origin( + &cause, self_ty, potential_self_ty) { + err.emit(); } - } else { - fcx.tcx.sess.diagnostic().mut_span_err( - span, &format!("invalid `self` type: {:?}", self_arg_ty)) - .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty)) + break + } + } else { + fcx.tcx.sess.diagnostic().mut_span_err( + span, &format!("invalid `self` type: {:?}", self_arg_ty)) + .note(&format!("type must be `{:?}` or a type that dereferences to it", self_ty)) + .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + .code(DiagnosticId::Error("E0307".into())) + .emit(); + return + } + } + + let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok(); + let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty); + + if !fcx.tcx.features().arbitrary_self_types { + match self_kind { + ExplicitSelf::ByValue | + ExplicitSelf::ByReference(_, _) | + ExplicitSelf::ByBox => (), + + ExplicitSelf::ByRawPointer(_) => { + feature_gate::feature_err( + &fcx.tcx.sess.parse_sess, + "arbitrary_self_types", + span, + GateIssue::Language, + "raw pointer `self` is unstable") .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") - .code(DiagnosticId::Error("E0307".into())) .emit(); - return } - } - let is_self_ty = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok(); - let self_kind = ExplicitSelf::determine(self_arg_ty, is_self_ty); - - if !fcx.tcx.features().arbitrary_self_types { - match self_kind { - ExplicitSelf::ByValue | - ExplicitSelf::ByReference(_, _) | - ExplicitSelf::ByBox => (), - - ExplicitSelf::ByRawPointer(_) => { - feature_gate::feature_err( - &fcx.tcx.sess.parse_sess, - "arbitrary_self_types", - span, - GateIssue::Language, - "raw pointer `self` is unstable") - .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") - .emit(); - } - - ExplicitSelf::Other => { - feature_gate::feature_err( - &fcx.tcx.sess.parse_sess, - "arbitrary_self_types", - span, - GateIssue::Language,"arbitrary `self` types are unstable") - .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") - .emit(); - } + ExplicitSelf::Other => { + feature_gate::feature_err( + &fcx.tcx.sess.parse_sess, + "arbitrary_self_types", + span, + GateIssue::Language,"arbitrary `self` types are unstable") + .help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") + .emit(); } } } +} - fn check_variances_for_type_defn(&self, - item: &hir::Item, - ast_generics: &hir::Generics) - { - let item_def_id = self.tcx.hir.local_def_id(item.id); - let ty = self.tcx.type_of(item_def_id); - if self.tcx.has_error_field(ty) { - return; - } - - let ty_predicates = self.tcx.predicates_of(item_def_id); - assert_eq!(ty_predicates.parent, None); - let variances = self.tcx.variances_of(item_def_id); - - let mut constrained_parameters: FxHashSet<_> = - variances.iter().enumerate() - .filter(|&(_, &variance)| variance != ty::Bivariant) - .map(|(index, _)| Parameter(index as u32)) - .collect(); - - identify_constrained_type_params(self.tcx, - ty_predicates.predicates.as_slice(), - None, - &mut constrained_parameters); - - for (index, _) in variances.iter().enumerate() { - if constrained_parameters.contains(&Parameter(index as u32)) { - continue; - } - - let (span, name) = match ast_generics.params[index] { - hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()), - hir::GenericParam::Type(ref tp) => (tp.span, tp.name), - }; - self.report_bivariance(span, name); - } +fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + item: &hir::Item, + ast_generics: &hir::Generics) +{ + let item_def_id = tcx.hir.local_def_id(item.id); + let ty = tcx.type_of(item_def_id); + if tcx.has_error_field(ty) { + return; } - fn report_bivariance(&self, - span: Span, - param_name: ast::Name) - { - let mut err = error_392(self.tcx, span, param_name); + let ty_predicates = tcx.predicates_of(item_def_id); + assert_eq!(ty_predicates.parent, None); + let variances = tcx.variances_of(item_def_id); - let suggested_marker_id = self.tcx.lang_items().phantom_data(); - match suggested_marker_id { - Some(def_id) => { - err.help( - &format!("consider removing `{}` or using a marker such as `{}`", - param_name, - self.tcx.item_path_str(def_id))); - } - None => { - // no lang items, no help! - } + let mut constrained_parameters: FxHashSet<_> = + variances.iter().enumerate() + .filter(|&(_, &variance)| variance != ty::Bivariant) + .map(|(index, _)| Parameter(index as u32)) + .collect(); + + identify_constrained_type_params(tcx, + ty_predicates.predicates.as_slice(), + None, + &mut constrained_parameters); + + for (index, _) in variances.iter().enumerate() { + if constrained_parameters.contains(&Parameter(index as u32)) { + continue; } - err.emit(); + + let (span, name) = match ast_generics.params[index] { + hir::GenericParam::Lifetime(ref ld) => (ld.lifetime.span, ld.lifetime.name.name()), + hir::GenericParam::Type(ref tp) => (tp.span, tp.name), + }; + report_bivariance(tcx, span, name); } } +fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + span: Span, + param_name: ast::Name) +{ + let mut err = error_392(tcx, span, param_name); + + let suggested_marker_id = tcx.lang_items().phantom_data(); + match suggested_marker_id { + Some(def_id) => { + err.help( + &format!("consider removing `{}` or using a marker such as `{}`", + param_name, + tcx.item_path_str(def_id))); + } + None => { + // no lang items, no help! + } + } + err.emit(); +} + fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { let generics = tcx.generics_of(def_id); let parent = tcx.generics_of(generics.parent.unwrap()); From 0b111e677c6bd58cf046d925493c5413c05773fe Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Thu, 8 Mar 2018 16:29:35 +0800 Subject: [PATCH 264/830] change &self to self and fix lifetime annotations --- src/librustc_borrowck/borrowck/mod.rs | 28 ++-- src/librustc_mir/util/borrowck_errors.rs | 178 +++++++++++++---------- 2 files changed, 119 insertions(+), 87 deletions(-) diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index bb198adea4a6..93d6247eeae4 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -253,28 +253,28 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> { used_mut_nodes: RefCell>, } -impl<'b, 'tcx: 'b> BorrowckErrors for BorrowckCtxt<'b, 'tcx> { - fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> +impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> { + fn struct_span_err_with_code>(self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'a> { self.tcx.sess.struct_span_err_with_code(sp, msg, code) } - fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> + fn struct_span_err>(self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'a> { self.tcx.sess.struct_span_err(sp, msg) } - fn cancel_if_wrong_origin<'a>(&'a self, - mut diag: DiagnosticBuilder<'a>, - o: Origin) - -> DiagnosticBuilder<'a> + fn cancel_if_wrong_origin(self, + mut diag: DiagnosticBuilder<'a>, + o: Origin) + -> DiagnosticBuilder<'a> { if !o.should_emit_errors(self.tcx.borrowck_mode()) { self.tcx.sess.diagnostic().cancel(&mut diag); diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 89242ca32bcb..48575584530c 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -52,30 +52,34 @@ impl Origin { } } -pub trait BorrowckErrors { - fn struct_span_err_with_code<'a, S: Into>(&'a self, +pub trait BorrowckErrors<'cx> { + fn struct_span_err_with_code>(self, sp: S, msg: &str, code: DiagnosticId) - -> DiagnosticBuilder<'a>; + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy; - fn struct_span_err<'a, S: Into>(&'a self, + fn struct_span_err>(self, sp: S, msg: &str) - -> DiagnosticBuilder<'a>; + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy; /// Cancels the given error if we shouldn't emit errors for a given /// origin in the current mode. /// /// Always make sure that the error gets passed through this function /// before you return it. - fn cancel_if_wrong_origin<'a>(&'a self, - diag: DiagnosticBuilder<'a>, + fn cancel_if_wrong_origin(self, + diag: DiagnosticBuilder<'cx>, o: Origin) - -> DiagnosticBuilder<'a>; + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy; - fn cannot_move_when_borrowed(&self, span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder<'_> + fn cannot_move_when_borrowed(self, span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0505, "cannot move out of `{}` because it is borrowed{OGN}", @@ -83,13 +87,14 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_use_when_mutably_borrowed(&self, + fn cannot_use_when_mutably_borrowed(self, span: Span, desc: &str, borrow_span: Span, borrow_desc: &str, o: Origin) - -> DiagnosticBuilder<'_> + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0503, "cannot use `{}` because it was mutably borrowed{OGN}", @@ -101,12 +106,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_act_on_uninitialized_variable(&self, + fn cannot_act_on_uninitialized_variable(self, span: Span, verb: &str, desc: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0381, "{} of possibly uninitialized variable: `{}`{OGN}", @@ -114,7 +120,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_mutably_borrow_multiply(&self, + fn cannot_mutably_borrow_multiply(self, new_loan_span: Span, desc: &str, opt_via: &str, @@ -122,7 +128,8 @@ pub trait BorrowckErrors { old_opt_via: &str, old_load_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0499, "cannot borrow `{}`{} as mutable more than once at a time{OGN}", @@ -148,13 +155,14 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_uniquely_borrow_by_two_closures(&self, + fn cannot_uniquely_borrow_by_two_closures(self, new_loan_span: Span, desc: &str, old_loan_span: Span, old_load_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0524, "two closures require unique access to `{}` at the same time{OGN}", @@ -173,7 +181,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_uniquely_borrow_by_one_closure(&self, + fn cannot_uniquely_borrow_by_one_closure(self, new_loan_span: Span, desc_new: &str, opt_via: &str, @@ -182,7 +190,8 @@ pub trait BorrowckErrors { old_opt_via: &str, previous_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0500, "closure requires unique access to `{}` but {} is already borrowed{}{OGN}", @@ -197,7 +206,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_reborrow_already_uniquely_borrowed(&self, + fn cannot_reborrow_already_uniquely_borrowed(self, new_loan_span: Span, desc_new: &str, opt_via: &str, @@ -206,7 +215,8 @@ pub trait BorrowckErrors { old_opt_via: &str, previous_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0501, "cannot borrow `{}`{} as {} because previous closure \ @@ -222,7 +232,7 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_reborrow_already_borrowed(&self, + fn cannot_reborrow_already_borrowed(self, span: Span, desc_new: &str, msg_new: &str, @@ -233,7 +243,8 @@ pub trait BorrowckErrors { msg_old: &str, old_load_end_span: Option, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0502, "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}", @@ -246,8 +257,9 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign_to_borrowed(&self, span: Span, borrow_span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_assign_to_borrowed(self, span: Span, borrow_span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0506, "cannot assign to `{}` because it is borrowed{OGN}", @@ -259,8 +271,9 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_move_into_closure(&self, span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0504, "cannot move `{}` into closure because it is borrowed{OGN}", @@ -269,8 +282,9 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_reassign_immutable(&self, span: Span, desc: &str, is_arg: bool, o: Origin) - -> DiagnosticBuilder + fn cannot_reassign_immutable(self, span: Span, desc: &str, is_arg: bool, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let msg = if is_arg { "to immutable argument" @@ -284,7 +298,8 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign(&self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder + fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0594, "cannot assign to {}{OGN}", @@ -292,14 +307,16 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign_static(&self, span: Span, desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_assign_static(self, span: Span, desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { self.cannot_assign(span, &format!("immutable static item `{}`", desc), o) } - fn cannot_move_out_of(&self, move_from_span: Span, move_from_desc: &str, o: Origin) - -> DiagnosticBuilder + fn cannot_move_out_of(self, move_from_span: Span, move_from_desc: &str, o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, move_from_span, E0507, "cannot move out of {}{OGN}", @@ -311,12 +328,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_move_out_of_interior_noncopy(&self, + fn cannot_move_out_of_interior_noncopy(self, move_from_span: Span, ty: ty::Ty, is_index: bool, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let type_name = match (&ty.sty, is_index) { (&ty::TyArray(_, _), true) => "array", @@ -332,11 +350,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_move_out_of_interior_of_drop(&self, + fn cannot_move_out_of_interior_of_drop(self, move_from_span: Span, container_ty: ty::Ty, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, move_from_span, E0509, "cannot move out of type `{}`, \ @@ -347,13 +366,14 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_act_on_moved_value(&self, + fn cannot_act_on_moved_value(self, use_span: Span, verb: &str, optional_adverb_for_moved: &str, moved_path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, use_span, E0382, "{} of {}moved value: `{}`{OGN}", @@ -362,11 +382,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_partially_reinit_an_uninit_struct(&self, + fn cannot_partially_reinit_an_uninit_struct(self, span: Span, uninit_path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, @@ -377,11 +398,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn closure_cannot_assign_to_borrowed(&self, + fn closure_cannot_assign_to_borrowed(self, span: Span, descr: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0595, "closure cannot assign to {}{OGN}", descr, OGN=o); @@ -389,11 +411,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_borrow_path_as_mutable(&self, + fn cannot_borrow_path_as_mutable(self, span: Span, path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{OGN}", path, OGN=o); @@ -401,11 +424,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_borrow_across_generator_yield(&self, + fn cannot_borrow_across_generator_yield(self, span: Span, yield_span: Span, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, @@ -417,11 +441,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn path_does_not_live_long_enough(&self, + fn path_does_not_live_long_enough(self, span: Span, path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0597, "{} does not live long enough{OGN}", path, OGN=o); @@ -429,11 +454,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn lifetime_too_short_for_reborrow(&self, + fn lifetime_too_short_for_reborrow(self, span: Span, path: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let err = struct_span_err!(self, span, E0598, "lifetime of {} is too short to guarantee \ @@ -443,12 +469,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_act_on_capture_in_sharable_fn(&self, + fn cannot_act_on_capture_in_sharable_fn(self, span: Span, bad_thing: &str, help: (Span, &str), o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let (help_span, help_msg) = help; let mut err = struct_span_err!(self, span, E0387, @@ -459,11 +486,12 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_assign_into_immutable_reference(&self, + fn cannot_assign_into_immutable_reference(self, span: Span, bad_thing: &str, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0389, "{} in a `&` reference{OGN}", bad_thing, OGN=o); @@ -472,12 +500,13 @@ pub trait BorrowckErrors { self.cancel_if_wrong_origin(err, o) } - fn cannot_capture_in_long_lived_closure(&self, + fn cannot_capture_in_long_lived_closure(self, closure_span: Span, borrowed_path: &str, capture_span: Span, o: Origin) - -> DiagnosticBuilder + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { let mut err = struct_span_err!(self, closure_span, E0373, "closure may outlive the current function, \ @@ -491,28 +520,31 @@ pub trait BorrowckErrors { } } -impl<'b, 'gcx, 'tcx> BorrowckErrors for TyCtxt<'b, 'gcx, 'tcx> { - fn struct_span_err_with_code<'a, S: Into>(&'a self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'a> +impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> { + fn struct_span_err_with_code>(self, + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { self.sess.struct_span_err_with_code(sp, msg, code) } - fn struct_span_err<'a, S: Into>(&'a self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'a> + fn struct_span_err>(self, + sp: S, + msg: &str) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { self.sess.struct_span_err(sp, msg) } - fn cancel_if_wrong_origin<'a>(&'a self, - mut diag: DiagnosticBuilder<'a>, - o: Origin) - -> DiagnosticBuilder<'a> + fn cancel_if_wrong_origin(self, + mut diag: DiagnosticBuilder<'cx>, + o: Origin) + -> DiagnosticBuilder<'cx> + where Self: Sized + Copy { if !o.should_emit_errors(self.borrowck_mode()) { self.sess.diagnostic().cancel(&mut diag); From c62d9eb729deec2437ad36220207cd4720452274 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sun, 11 Mar 2018 01:03:51 +0000 Subject: [PATCH 265/830] fix formatting --- src/librustc_mir/util/borrowck_errors.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 48575584530c..bcd7a3e7cd34 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -54,16 +54,16 @@ impl Origin { pub trait BorrowckErrors<'cx> { fn struct_span_err_with_code>(self, - sp: S, - msg: &str, - code: DiagnosticId) - -> DiagnosticBuilder<'cx> + sp: S, + msg: &str, + code: DiagnosticId) + -> DiagnosticBuilder<'cx> where Self: Sized + Copy; fn struct_span_err>(self, - sp: S, - msg: &str) - -> DiagnosticBuilder<'cx> + sp: S, + msg: &str) + -> DiagnosticBuilder<'cx> where Self: Sized + Copy; /// Cancels the given error if we shouldn't emit errors for a given @@ -72,9 +72,9 @@ pub trait BorrowckErrors<'cx> { /// Always make sure that the error gets passed through this function /// before you return it. fn cancel_if_wrong_origin(self, - diag: DiagnosticBuilder<'cx>, - o: Origin) - -> DiagnosticBuilder<'cx> + diag: DiagnosticBuilder<'cx>, + o: Origin) + -> DiagnosticBuilder<'cx> where Self: Sized + Copy; fn cannot_move_when_borrowed(self, span: Span, desc: &str, o: Origin) From aaac69f78e6a9f0ee52b41969d81f4bb79da6418 Mon Sep 17 00:00:00 2001 From: Maxwell Powlison Date: Fri, 16 Mar 2018 03:41:53 -0400 Subject: [PATCH 266/830] Fix Issue #48345, is_file, is_dir, and is_symlink note mutual exclusion The methods on the structures `fs::FileType` and `fs::Metadata` of (respectively) `is_file`, `is_dir`, and `is_symlink` had some ambiguity in documentation, where it was not noted whether files will pass those tests exclusively or not. It is now written that the tests are mutually exclusive. Fixes #48345. --- src/libstd/fs.rs | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index db52ed67d3a8..5caa703ee97e 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -906,7 +906,13 @@ impl Metadata { FileType(self.0.file_type()) } - /// Returns whether this metadata is for a directory. + /// Returns whether this metadata is for a directory. The + /// result is mutually exclusive to the result of + /// [`is_file`], and will be false for symlink metadata + /// obtained from [`symlink_metadata`]. + /// + /// [`is_file`]: struct.Metadata.html#method.is_file + /// [`symlink_metadata`]: fn.symlink_metadata.html /// /// # Examples /// @@ -923,7 +929,13 @@ impl Metadata { #[stable(feature = "rust1", since = "1.0.0")] pub fn is_dir(&self) -> bool { self.file_type().is_dir() } - /// Returns whether this metadata is for a regular file. + /// Returns whether this metadata is for a regular file. The + /// result is mutually exclusive to the result of + /// [`is_dir`], and will be false for symlink metadata + /// obtained from [`symlink_metadata`]. + /// + /// [`is_dir`]: struct.Metadata.html#method.is_dir + /// [`symlink_metadata`]: fn.symlink_metadata.html /// /// # Examples /// @@ -1148,7 +1160,13 @@ impl Permissions { } impl FileType { - /// Test whether this file type represents a directory. + /// Test whether this file type represents a directory. The + /// result is mutually exclusive to the results of + /// [`is_file`] and [`is_symlink`]; only zero or one of these + /// tests may pass. + /// + /// [`is_file`]: struct.FileType.html#method.is_file + /// [`is_symlink`]: struct.FileType.html#method.is_symlink /// /// # Examples /// @@ -1167,6 +1185,12 @@ impl FileType { pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Test whether this file type represents a regular file. + /// The result is mutually exclusive to the results of + /// [`is_dir`] and [`is_symlink`]; only zero or one of these + /// tests may pass. + /// + /// [`is_dir`]: struct.FileType.html#method.is_dir + /// [`is_symlink`]: struct.FileType.html#method.is_symlink /// /// # Examples /// @@ -1185,6 +1209,9 @@ impl FileType { pub fn is_file(&self) -> bool { self.0.is_file() } /// Test whether this file type represents a symbolic link. + /// The result is mutually exclusive to the results of + /// [`is_dir`] and [`is_file`]; only zero or one of these + /// tests may pass. /// /// The underlying [`Metadata`] struct needs to be retrieved /// with the [`fs::symlink_metadata`] function and not the @@ -1195,6 +1222,8 @@ impl FileType { /// [`Metadata`]: struct.Metadata.html /// [`fs::metadata`]: fn.metadata.html /// [`fs::symlink_metadata`]: fn.symlink_metadata.html + /// [`is_dir`]: struct.FileType.html#method.is_dir + /// [`is_file`]: struct.FileType.html#method.is_file /// [`is_symlink`]: struct.FileType.html#method.is_symlink /// /// # Examples From 4be3e96b80a5dc5bddeaccd2a7c3af1abf8bf452 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Fri, 16 Mar 2018 16:53:40 +0900 Subject: [PATCH 267/830] Checks for unknown attributes before aborting ...due to unresolved macros. --- src/librustc_driver/driver.rs | 10 ++++++---- src/test/ui/issue-49074.rs | 24 ++++++++++++++++++++++++ src/test/ui/issue-49074.stderr | 19 +++++++++++++++++++ 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/issue-49074.rs create mode 100644 src/test/ui/issue-49074.stderr diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index e52575f02b2f..b5e31bdf6686 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -877,10 +877,6 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, Ok(()) })?; - if resolver.found_unresolved_macro { - sess.parse_sess.span_diagnostic.abort_if_errors(); - } - // Needs to go *after* expansion to be able to check the results of macro expansion. time(sess, "complete gated feature checking", || { sess.track_errors(|| { @@ -892,6 +888,12 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, }) })?; + // Unresolved macros might be due to mistyped `#[macro_use]`, + // so abort after checking for unknown attributes. (#49074) + if resolver.found_unresolved_macro { + sess.parse_sess.span_diagnostic.abort_if_errors(); + } + // Lower ast -> hir. // First, we need to collect the dep_graph. let dep_graph = match future_dep_graph { diff --git a/src/test/ui/issue-49074.rs b/src/test/ui/issue-49074.rs new file mode 100644 index 000000000000..2e7e11844109 --- /dev/null +++ b/src/test/ui/issue-49074.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Check that unknown attribute error is shown even if there are unresolved macros. + +#[marco_use] // typo +//~^ ERROR The attribute `marco_use` is currently unknown to the compiler +mod foo { + macro_rules! bar { + () => (); + } +} + +fn main() { + bar!(); + //~^ ERROR cannot find macro `bar!` +} diff --git a/src/test/ui/issue-49074.stderr b/src/test/ui/issue-49074.stderr new file mode 100644 index 000000000000..c9984ea2e9a8 --- /dev/null +++ b/src/test/ui/issue-49074.stderr @@ -0,0 +1,19 @@ +error: cannot find macro `bar!` in this scope + --> $DIR/issue-49074.rs:22:4 + | +LL | bar!(); + | ^^^ + | + = help: have you added the `#[macro_use]` on the module/import? + +error[E0658]: The attribute `marco_use` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/issue-49074.rs:13:1 + | +LL | #[marco_use] // typo + | ^^^^^^^^^^^^ + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From 06148cb4b0f83ecec70148de8b589644b618e66f Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Fri, 16 Mar 2018 09:39:41 +0100 Subject: [PATCH 268/830] ignore emscripten --- src/test/compile-fail/simd-intrinsic-generic-reduction.rs | 1 + src/test/run-pass/simd-intrinsic-generic-reduction.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/test/compile-fail/simd-intrinsic-generic-reduction.rs b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs index 4cb9d6aba75c..57e4bb76a6ce 100644 --- a/src/test/compile-fail/simd-intrinsic-generic-reduction.rs +++ b/src/test/compile-fail/simd-intrinsic-generic-reduction.rs @@ -9,6 +9,7 @@ // except according to those terms. // min-llvm-version 5.0 +// ignore-emscripten // Test that the simd_reduce_{op} intrinsics produce ok-ish error // messages when misused. diff --git a/src/test/run-pass/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd-intrinsic-generic-reduction.rs index 7355aba6c114..9a1214d3b35e 100644 --- a/src/test/run-pass/simd-intrinsic-generic-reduction.rs +++ b/src/test/run-pass/simd-intrinsic-generic-reduction.rs @@ -9,6 +9,7 @@ // except according to those terms. // min-llvm-version 5.0 +// ignore-emscripten // Test that the simd_reduce_{op} intrinsics produce the correct results. From 683ad942966c427be773b412d9314baa55a6e188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:38:12 +0100 Subject: [PATCH 269/830] Add OnDrop --- src/librustc_data_structures/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 81246aea1b56..bf0b3726bb30 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -76,6 +76,14 @@ pub mod flock; pub mod sync; pub mod owning_ref; +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { + (self.0)(); + } +} + // See comments in src/librustc/lib.rs #[doc(hidden)] pub fn __noop_fix_for_27438() {} From 3b43dcbb4c62a36b68afd7f9a1bf12aed1b53d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 20:11:23 +0100 Subject: [PATCH 270/830] Replace Rc with Lrc --- src/librustc/middle/const_val.rs | 4 ++-- src/librustc/traits/query/dropck_outlives.rs | 6 +++--- src/librustc/traits/query/normalize.rs | 6 +++--- src/librustc/ty/structural_impls.rs | 3 ++- src/librustc_mir/interpret/const_eval.rs | 6 +++--- src/librustc_traits/dropck_outlives.rs | 4 ++-- src/librustc_traits/normalize_projection_ty.rs | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 8c3dfd0bce75..19a7576b7cea 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -19,7 +19,7 @@ use graphviz::IntoCow; use syntax_pos::Span; use std::borrow::Cow; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>; @@ -52,7 +52,7 @@ impl<'tcx> ConstVal<'tcx> { #[derive(Clone, Debug)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub kind: Rc>, + pub kind: Lrc>, } #[derive(Clone, Debug)] diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1caab6fd89ef..e16a1082214f 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -15,7 +15,7 @@ use std::iter::FromIterator; use traits::query::CanonicalTyGoal; use ty::{self, Ty, TyCtxt}; use ty::subst::Kind; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set @@ -182,13 +182,13 @@ impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, DropckOutlivesResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 70c5cf5f3902..63f50cff4c2a 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -17,7 +17,7 @@ use infer::at::At; use infer::canonical::{Canonical, Canonicalize, QueryResult}; use middle::const_val::ConstVal; use mir::interpret::GlobalId; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use traits::query::CanonicalProjectionGoal; use traits::project::Normalized; @@ -259,13 +259,13 @@ impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::Pr impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index c9a69d5405c9..3fc20508ad7e 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -18,6 +18,7 @@ use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::sync::Lrc; use mir::interpret; use std::rc::Rc; @@ -465,7 +466,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> { tcx.lift(&*self.kind).map(|kind| { ConstEvalErr { span: self.span, - kind: Rc::new(kind), + kind: Lrc::new(kind), } }) } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 82eb28287b03..50997089a576 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -14,7 +14,7 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory}; use std::fmt; use std::error::Error; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -477,7 +477,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do match-check before building MIR if tcx.check_match(def_id).is_err() { return Err(ConstEvalErr { - kind: Rc::new(CheckMatchError), + kind: Lrc::new(CheckMatchError), span, }); } @@ -489,7 +489,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do not continue into miri if typeck errors occurred; it will fail horribly if tables.tainted_by_errors { return Err(ConstEvalErr { - kind: Rc::new(TypeckError), + kind: Lrc::new(TypeckError), span, }); } diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 2a8cfe5cc06b..1fe2f87128ab 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -16,14 +16,14 @@ use rustc::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResu use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc::ty::subst::Subst; use rustc::util::nodemap::FxHashSet; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::codemap::{Span, DUMMY_SP}; use util; crate fn dropck_outlives<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalTyGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("dropck_outlives(goal={:#?})", goal); tcx.infer_ctxt().enter(|ref infcx| { diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 55785d9586cc..62d5ef11551c 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -14,7 +14,7 @@ use rustc::traits::{self, FulfillmentContext, Normalized, ObligationCause, use rustc::traits::query::{CanonicalProjectionGoal, NoSolution, normalize::NormalizationResult}; use rustc::ty::{ParamEnvAnd, TyCtxt}; use rustc::util::common::CellUsizeExt; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::DUMMY_SP; use util; @@ -22,7 +22,7 @@ use util; crate fn normalize_projection_ty<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalProjectionGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("normalize_provider(goal={:#?})", goal); tcx.sess.perf_stats.normalize_projection_ty.increment(); From 910bf840cce1da57b96f7ac15f8b803675bb8a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:09:20 +0100 Subject: [PATCH 271/830] Always print `aborting due to n previous error(s)` and only print it once for multi-threaded code --- src/librustc_driver/lib.rs | 46 +++++++++++++++++++--------------- src/librustc_errors/lib.rs | 34 +++++++++++++------------ src/librustc_typeck/astconv.rs | 3 ++- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5a1983bfec64..2a15d57a262e 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -63,6 +63,7 @@ use rustc_resolve as resolve; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::OnDrop; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::CompileIncomplete; use rustc::session::config::{Input, PrintRequest, ErrorOutputType}; @@ -515,30 +516,35 @@ fn run_compiler_impl<'a>(args: &[String], target_features::add_configuration(&mut cfg, &sess, &*trans); sess.parse_sess.config = cfg; - let plugins = sess.opts.debugging_opts.extra_plugins.clone(); + let result = { + let plugins = sess.opts.debugging_opts.extra_plugins.clone(); - let cstore = CStore::new(trans.metadata_loader()); + let cstore = CStore::new(trans.metadata_loader()); - do_or_return!(callbacks.late_callback(&*trans, - &matches, - &sess, - &cstore, - &input, - &odir, - &ofile), Some(sess)); + do_or_return!(callbacks.late_callback(&*trans, + &matches, + &sess, + &cstore, + &input, + &odir, + &ofile), Some(sess)); - let control = callbacks.build_controller(&sess, &matches); + let _sess_abort_error = OnDrop(|| sess.diagnostic().print_error_count()); - (driver::compile_input(trans, - &sess, - &cstore, - &input_file_path, - &input, - &odir, - &ofile, - Some(plugins), - &control), - Some(sess)) + let control = callbacks.build_controller(&sess, &matches); + + driver::compile_input(trans, + &sess, + &cstore, + &input_file_path, + &input, + &odir, + &ofile, + Some(plugins), + &control) + }; + + (result, Some(sess)) } // Extract output directory and file from matches. diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7148969191f2..b3265c21884b 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -555,21 +555,15 @@ impl Handler { pub fn has_errors(&self) -> bool { self.err_count() > 0 } - pub fn abort_if_errors(&self) { - let s; - match self.err_count() { - 0 => { - if let Some(bug) = self.delayed_span_bug.borrow_mut().take() { - DiagnosticBuilder::new_diagnostic(self, bug).emit(); - } - return; - } - 1 => s = "aborting due to previous error".to_string(), - _ => { - s = format!("aborting due to {} previous errors", self.err_count()); - } - } - let err = self.fatal(&s); + + pub fn print_error_count(&self) { + let s = match self.err_count() { + 0 => return, + 1 => "aborting due to previous error".to_string(), + _ => format!("aborting due to {} previous errors", self.err_count()) + }; + + let _ = self.fatal(&s); let can_show_explain = self.emitter.borrow().should_show_explain(); let are_there_diagnostics = !self.tracked_diagnostic_codes.borrow().is_empty(); @@ -600,8 +594,16 @@ impl Handler { } } } + } - err.raise(); + pub fn abort_if_errors(&self) { + if self.err_count() == 0 { + if let Some(bug) = self.delayed_span_bug.borrow_mut().take() { + DiagnosticBuilder::new_diagnostic(self, bug).emit(); + } + return; + } + FatalError.raise(); } pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) { if lvl == Warning && !self.flags.can_emit_warnings { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 827ca79334cb..bc69fbdb7783 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -27,6 +27,7 @@ use std::slice; use require_c_abi_if_variadic; use util::common::ErrorReported; use util::nodemap::FxHashSet; +use errors::FatalError; use std::iter; use syntax::{abi, ast}; @@ -337,7 +338,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { Def::Trait(trait_def_id) => trait_def_id, Def::TraitAlias(alias_def_id) => alias_def_id, Def::Err => { - self.tcx().sess.fatal("cannot continue compilation due to previous error"); + FatalError.raise(); } _ => unreachable!(), } From f0ad533fe316c4eb26ab6ebda879e60956633c0e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Mar 2018 11:44:55 +0100 Subject: [PATCH 272/830] Remove deprecated unstable alloc::heap::EMPTY constant --- src/liballoc/heap.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 372d606e4572..c13ad39e5e1d 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -228,14 +228,6 @@ unsafe impl Alloc for Heap { } } -/// An arbitrary non-null address to represent zero-size allocations. -/// -/// This preserves the non-null invariant for types like `Box`. The address -/// may overlap with non-zero-size memory allocations. -#[rustc_deprecated(since = "1.19.0", reason = "Use Unique/NonNull::empty() instead")] -#[unstable(feature = "heap_api", issue = "27700")] -pub const EMPTY: *mut () = 1 as *mut (); - /// The allocator for unique pointers. // This function must not unwind. If it does, MIR trans will fail. #[cfg(not(test))] From 4133b160363143b975cf9927cff87d183f1f5405 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 16 Mar 2018 11:48:32 +0100 Subject: [PATCH 273/830] Only generate miri backtraces if explicitly requested --- src/librustc/mir/interpret/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 51660b180cd9..9e69990f22c0 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -20,7 +20,7 @@ pub struct EvalError<'tcx> { impl<'tcx> From> for EvalError<'tcx> { fn from(kind: EvalErrorKind<'tcx>) -> Self { - let backtrace = match env::var("RUST_BACKTRACE") { + let backtrace = match env::var("MIRI_BACKTRACE") { Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()), _ => None }; From b1d872b38eaacefbef73faa6a4a0c07622a8c941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 16:13:47 +0100 Subject: [PATCH 274/830] Update tests --- src/test/ui-fulldeps/custom-derive/issue-36935.stderr | 2 ++ src/test/ui-fulldeps/proc-macro/load-panic.stderr | 2 ++ src/test/ui/codemap_tests/two_files.stderr | 3 ++- src/test/ui/cross-file-errors/main.stderr | 2 ++ src/test/ui/did_you_mean/recursion_limit_macro.stderr | 2 ++ src/test/ui/error-codes/E0404.stderr | 3 ++- src/test/ui/error-codes/E0405.stderr | 3 ++- src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr | 2 ++ src/test/ui/feature-gate-fn_must_use.stderr | 2 ++ .../feature-gate/issue-43106-gating-of-builtin-attrs.stderr | 2 ++ .../ui/feature-gate/issue-43106-gating-of-deprecated.stderr | 2 ++ src/test/ui/impl-trait/universal_wrong_bounds.stderr | 4 +++- src/test/ui/issue-22644.stderr | 2 ++ src/test/ui/issue-44406.stderr | 2 ++ src/test/ui/lint-output-format-2.stderr | 2 ++ src/test/ui/loops-reject-duplicate-labels-2.stderr | 2 ++ src/test/ui/loops-reject-duplicate-labels.stderr | 2 ++ src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr | 2 ++ src/test/ui/loops-reject-lifetime-shadowing-label.stderr | 2 ++ src/test/ui/macro-context.stderr | 2 ++ src/test/ui/macros/macro_path_as_generic_bound.stderr | 3 ++- src/test/ui/macros/trace_faulty_macros.stderr | 2 ++ src/test/ui/raw_string.stderr | 2 ++ src/test/ui/resolve/issue-21221-1.stderr | 4 +++- src/test/ui/resolve/issue-21221-2.stderr | 3 ++- src/test/ui/resolve/issue-21221-3.stderr | 3 ++- src/test/ui/resolve/issue-21221-4.stderr | 3 ++- src/test/ui/resolve/issue-3907.stderr | 3 ++- src/test/ui/resolve/issue-5035.stderr | 4 +++- .../ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr | 4 +++- .../generic-associated-types-where.stderr | 2 -- src/test/ui/span/issue-24690.stderr | 2 ++ src/test/ui/span/issue-35987.stderr | 3 ++- 33 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr index b082999a8978..027825699412 100644 --- a/src/test/ui-fulldeps/custom-derive/issue-36935.stderr +++ b/src/test/ui-fulldeps/custom-derive/issue-36935.stderr @@ -6,3 +6,5 @@ LL | #[derive(Foo, Bar)] //~ ERROR proc-macro derive panicked | = help: message: lolnope +error: aborting due to previous error + diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.stderr b/src/test/ui-fulldeps/proc-macro/load-panic.stderr index edfd134469cd..30ad53f9041f 100644 --- a/src/test/ui-fulldeps/proc-macro/load-panic.stderr +++ b/src/test/ui-fulldeps/proc-macro/load-panic.stderr @@ -6,3 +6,5 @@ LL | #[derive(A)] | = help: message: nope! +error: aborting due to previous error + diff --git a/src/test/ui/codemap_tests/two_files.stderr b/src/test/ui/codemap_tests/two_files.stderr index 614531c98212..e247e86fbcb2 100644 --- a/src/test/ui/codemap_tests/two_files.stderr +++ b/src/test/ui/codemap_tests/two_files.stderr @@ -4,5 +4,6 @@ error[E0404]: expected trait, found type alias `Bar` LL | impl Bar for Baz { } //~ ERROR expected trait, found type alias | ^^^ type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/cross-file-errors/main.stderr b/src/test/ui/cross-file-errors/main.stderr index a9db5214e6a2..8fe795f7f1d8 100644 --- a/src/test/ui/cross-file-errors/main.stderr +++ b/src/test/ui/cross-file-errors/main.stderr @@ -9,3 +9,5 @@ LL | _ LL | underscore!(); | -------------- in this macro invocation +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/recursion_limit_macro.stderr b/src/test/ui/did_you_mean/recursion_limit_macro.stderr index f6bce55528c7..265a688df991 100644 --- a/src/test/ui/did_you_mean/recursion_limit_macro.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_macro.stderr @@ -9,3 +9,5 @@ LL | recurse!(0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9); | = help: consider adding a `#![recursion_limit="20"]` attribute to your crate +error: aborting due to previous error + diff --git a/src/test/ui/error-codes/E0404.stderr b/src/test/ui/error-codes/E0404.stderr index 9f705da58616..afb748bedbe0 100644 --- a/src/test/ui/error-codes/E0404.stderr +++ b/src/test/ui/error-codes/E0404.stderr @@ -10,5 +10,6 @@ error[E0404]: expected trait, found struct `Foo` LL | fn baz(_: T) {} //~ ERROR E0404 | ^^^ not a trait -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/error-codes/E0405.stderr b/src/test/ui/error-codes/E0405.stderr index b5901dd9c848..27190af1c6c1 100644 --- a/src/test/ui/error-codes/E0405.stderr +++ b/src/test/ui/error-codes/E0405.stderr @@ -4,5 +4,6 @@ error[E0405]: cannot find trait `SomeTrait` in this scope LL | impl SomeTrait for Foo {} //~ ERROR E0405 | ^^^^^^^^^ not found in this scope -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr index a9952ff4fac1..a2c1dedff385 100644 --- a/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr +++ b/src/test/ui/feature-gate-fn_must_use-cap-lints-allow.stderr @@ -4,3 +4,5 @@ error: compilation successful LL | fn main() {} //~ ERROR compilation successful | ^^^^^^^^^^^^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate-fn_must_use.stderr b/src/test/ui/feature-gate-fn_must_use.stderr index 4772cf28f6c1..431c57abd265 100644 --- a/src/test/ui/feature-gate-fn_must_use.stderr +++ b/src/test/ui/feature-gate-fn_must_use.stderr @@ -20,3 +20,5 @@ error: compilation successful LL | fn main() {} //~ ERROR compilation successful | ^^^^^^^^^^^^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 9c4fb79f6f1a..0beed6279871 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -1316,3 +1316,5 @@ LL | | println!("Hello World"); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr index 83f6e016370b..802c5d9384d7 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-deprecated.stderr @@ -6,3 +6,5 @@ LL | | println!("Hello World"); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index a02fc1f748fa..3cc0bebe8165 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -24,5 +24,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::fmt::Debug; | -error: cannot continue compilation due to previous error +error: aborting due to 3 previous errors +Some errors occurred: E0405, E0425. +For more information about an error, try `rustc --explain E0405`. diff --git a/src/test/ui/issue-22644.stderr b/src/test/ui/issue-22644.stderr index 257b9bd235d7..aeb465b2ab23 100644 --- a/src/test/ui/issue-22644.stderr +++ b/src/test/ui/issue-22644.stderr @@ -89,3 +89,5 @@ error: expected type, found `4` LL | println!("{}", a: &mut 4); //~ ERROR expected type, found `4` | ^ expecting a type here because of type ascription +error: aborting due to 9 previous errors + diff --git a/src/test/ui/issue-44406.stderr b/src/test/ui/issue-44406.stderr index 443b28cf0996..de7c11732e4a 100644 --- a/src/test/ui/issue-44406.stderr +++ b/src/test/ui/issue-44406.stderr @@ -13,3 +13,5 @@ LL | bar(baz: $rest) LL | foo!(true); //~ ERROR expected type, found keyword | ^^^^ expecting a type here because of type ascription +error: aborting due to 2 previous errors + diff --git a/src/test/ui/lint-output-format-2.stderr b/src/test/ui/lint-output-format-2.stderr index b2d1e1ac0582..d484061ef966 100644 --- a/src/test/ui/lint-output-format-2.stderr +++ b/src/test/ui/lint-output-format-2.stderr @@ -22,3 +22,5 @@ LL | | let _y = bar(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops-reject-duplicate-labels-2.stderr index d35ed4ff88a6..830270a99d11 100644 --- a/src/test/ui/loops-reject-duplicate-labels-2.stderr +++ b/src/test/ui/loops-reject-duplicate-labels-2.stderr @@ -70,3 +70,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-duplicate-labels.stderr b/src/test/ui/loops-reject-duplicate-labels.stderr index d1b874ea9972..a71f98b812a8 100644 --- a/src/test/ui/loops-reject-duplicate-labels.stderr +++ b/src/test/ui/loops-reject-duplicate-labels.stderr @@ -73,3 +73,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr index 0cdd58fdbd75..af524d5b0176 100644 --- a/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr +++ b/src/test/ui/loops-reject-labels-shadowing-lifetimes.stderr @@ -108,3 +108,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr index a050aec50c72..999cfb9cc3c6 100644 --- a/src/test/ui/loops-reject-lifetime-shadowing-label.stderr +++ b/src/test/ui/loops-reject-lifetime-shadowing-label.stderr @@ -14,3 +14,5 @@ LL | | foo(); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/macro-context.stderr b/src/test/ui/macro-context.stderr index 4dc6bbe4d656..b3e67fb2607c 100644 --- a/src/test/ui/macro-context.stderr +++ b/src/test/ui/macro-context.stderr @@ -43,3 +43,5 @@ LL | () => ( i ; typeof ); //~ ERROR expected expression, found reserved k LL | m!(); | ----- in this macro invocation +error: aborting due to 4 previous errors + diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr index 06d22714dd8b..0f9f0607c5bf 100644 --- a/src/test/ui/macros/macro_path_as_generic_bound.stderr +++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr @@ -4,5 +4,6 @@ error[E0433]: failed to resolve. Use of undeclared type or module `m` LL | foo!(m::m2::A); //~ ERROR failed to resolve | ^ Use of undeclared type or module `m` -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index 9fb5b17a3114..a9ffef8ef809 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -45,3 +45,5 @@ LL | my_recursive_macro!(); = note: expanding `my_recursive_macro! { }` = note: to `my_recursive_macro ! ( ) ;` +error: aborting due to 2 previous errors + diff --git a/src/test/ui/raw_string.stderr b/src/test/ui/raw_string.stderr index b8aa596ef953..ddf1cfe406f7 100644 --- a/src/test/ui/raw_string.stderr +++ b/src/test/ui/raw_string.stderr @@ -6,3 +6,5 @@ LL | let x = r##"lol"#; | = note: this raw string should be terminated with `"##` +error: aborting due to previous error + diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index a9d2aeee2d15..3edfa33d80a0 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -45,5 +45,7 @@ help: possible candidate is found in another module, you can import it into scop LL | use std::ops::Div; | -error: cannot continue compilation due to previous error +error: aborting due to 4 previous errors +Some errors occurred: E0405, E0412. +For more information about an error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-2.stderr b/src/test/ui/resolve/issue-21221-2.stderr index c61ffe3b33e8..e11fe9ac4cf1 100644 --- a/src/test/ui/resolve/issue-21221-2.stderr +++ b/src/test/ui/resolve/issue-21221-2.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use foo::bar::T; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-3.stderr b/src/test/ui/resolve/issue-21221-3.stderr index 7725f74cb49f..f406cd6e35fc 100644 --- a/src/test/ui/resolve/issue-21221-3.stderr +++ b/src/test/ui/resolve/issue-21221-3.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use issue_21221_3::outer::OuterTrait; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-21221-4.stderr b/src/test/ui/resolve/issue-21221-4.stderr index b0a4d5ba4d89..c0a7f1734f49 100644 --- a/src/test/ui/resolve/issue-21221-4.stderr +++ b/src/test/ui/resolve/issue-21221-4.stderr @@ -8,5 +8,6 @@ help: possible candidate is found in another module, you can import it into scop LL | use issue_21221_4::T; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0405`. diff --git a/src/test/ui/resolve/issue-3907.stderr b/src/test/ui/resolve/issue-3907.stderr index 2b8b2b20685f..3627c09b28fd 100644 --- a/src/test/ui/resolve/issue-3907.stderr +++ b/src/test/ui/resolve/issue-3907.stderr @@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in LL | use issue_3907::Foo; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. diff --git a/src/test/ui/resolve/issue-5035.stderr b/src/test/ui/resolve/issue-5035.stderr index 6597f05889af..353a0b1c3d9d 100644 --- a/src/test/ui/resolve/issue-5035.stderr +++ b/src/test/ui/resolve/issue-5035.stderr @@ -13,5 +13,7 @@ LL | impl K for isize {} //~ ERROR expected trait, found type alias `K` | did you mean `I`? | type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +Some errors occurred: E0404, E0432. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr index 6e7bd28d16fc..f32c5e9b2c6b 100644 --- a/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr +++ b/src/test/ui/resolve/unboxed-closure-sugar-nonexistent-trait.stderr @@ -10,5 +10,7 @@ error[E0404]: expected trait, found type alias `Typedef` LL | fn g isize>(x: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^ type aliases cannot be used for traits -error: cannot continue compilation due to previous error +error: aborting due to 2 previous errors +Some errors occurred: E0404, E0405. +For more information about an error, try `rustc --explain E0404`. diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr index bb55d86f620b..e69de29bb2d1 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr @@ -1,2 +0,0 @@ -error: cannot continue compilation due to previous error - diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index 6a4ec73b27a6..b496a1a76c01 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -36,3 +36,5 @@ LL | | println!("{}", theTwo); LL | | } | |_^ +error: aborting due to previous error + diff --git a/src/test/ui/span/issue-35987.stderr b/src/test/ui/span/issue-35987.stderr index 2d4a7cc72f5f..1dd45bb1e5ef 100644 --- a/src/test/ui/span/issue-35987.stderr +++ b/src/test/ui/span/issue-35987.stderr @@ -8,5 +8,6 @@ help: possible better candidate is found in another module, you can import it in LL | use std::ops::Add; | -error: cannot continue compilation due to previous error +error: aborting due to previous error +For more information about this error, try `rustc --explain E0404`. From ea6a1bdf6ba754f3b96e3a46f9173b17ff18ed07 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 10:46:06 +0000 Subject: [PATCH 275/830] Compute each key only one during slice::sort_by_key --- src/liballoc/slice.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index dc40062ef13d..c57f1e7f5729 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1328,10 +1328,18 @@ impl [T] { /// ``` #[stable(feature = "slice_sort_by_key", since = "1.7.0")] #[inline] - pub fn sort_by_key(&mut self, mut f: F) + pub fn sort_by_key(&mut self, f: F) where F: FnMut(&T) -> B, B: Ord { - merge_sort(self, |a, b| f(a).lt(&f(b))); + let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); + indices.sort(); + for i in 0..self.len() { + let mut index = indices[i].1; + while index < i { + index = indices[index].1; + } + self.swap(i, index); + } } /// Sorts the slice, but may not preserve the order of equal elements. From 670e69e20753e2ef33ee61b0515092cace3fd716 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 12:15:05 +0000 Subject: [PATCH 276/830] Update documentation for sort_by_key --- src/liballoc/slice.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index c57f1e7f5729..db3b14859ddd 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1302,11 +1302,9 @@ impl [T] { /// Sorts the slice with a key extraction function. /// - /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. - /// - /// When applicable, unstable sorting is preferred because it is generally faster than stable - /// sorting and it doesn't allocate auxiliary memory. - /// See [`sort_unstable_by_key`](#method.sort_unstable_by_key). + /// During sorting, the key function is called only once per element. + /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)` + /// worst-case, where the key function is `O(m)`. /// /// # Current implementation /// @@ -1315,8 +1313,7 @@ impl [T] { /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of /// two or more sorted sequences concatenated one after another. /// - /// Also, it allocates temporary storage half the size of `self`, but for short slices a - /// non-allocating insertion sort is used instead. + /// The algorithm allocates temporary storage the size of `self`. /// /// # Examples /// From b8452cc3266f2d9567b5c07ca3044b3960e10ebf Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 12:22:11 +0000 Subject: [PATCH 277/830] Clarify behaviour of sort_unstable_by_key with respect to sort_by_key --- src/liballoc/slice.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index db3b14859ddd..63b22bd0f6d8 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1303,6 +1303,7 @@ impl [T] { /// Sorts the slice with a key extraction function. /// /// During sorting, the key function is called only once per element. + /// /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)` /// worst-case, where the key function is `O(m)`. /// @@ -1329,7 +1330,10 @@ impl [T] { where F: FnMut(&T) -> B, B: Ord { let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); - indices.sort(); + // The elements of `indices` are unique, as they are indexed, so any sort will be stable + // with respect to the original slice. We use `sort_unstable` here because it requires less + // memory allocation. + indices.sort_unstable(); for i in 0..self.len() { let mut index = indices[i].1; while index < i { @@ -1414,8 +1418,11 @@ impl [T] { /// Sorts the slice with a key extraction function, but may not preserve the order of equal /// elements. /// + /// Note that, currently, the key function for `sort_unstable_by_key` is called multiple times + /// per element, unlike `sort_stable_by_key`. + /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), - /// and `O(n log n)` worst-case. + /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. /// /// # Current implementation /// @@ -1425,8 +1432,8 @@ impl [T] { /// randomization to avoid degenerate cases, but with a fixed seed to always provide /// deterministic behavior. /// - /// It is typically faster than stable sorting, except in a few special cases, e.g. when the - /// slice consists of several concatenated sorted sequences. + /// Due to its key calling strategy, `sort_unstable_by_key` is likely to be slower than + /// `sort_by_key` in cases where the key function is expensive. /// /// # Examples /// From 9fbee359d7eb3a621604bc2067a375f6d4b757e5 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 13:39:52 +0000 Subject: [PATCH 278/830] Add a test for sort_by_key --- src/liballoc/tests/slice.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index d9e9d91cea88..300f6abaa7f1 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -425,6 +425,11 @@ fn test_sort() { v.sort_by(|a, b| b.cmp(a)); assert!(v.windows(2).all(|w| w[0] >= w[1])); + // Sort in lexicographic order. + let mut v = orig.clone(); + v.sort_by_key(|x| x.to_string()); + assert!(v.windows(2).all(|w| w[0].to_string() <= w[1].to_string())); + // Sort with many pre-sorted runs. let mut v = orig.clone(); v.sort(); From 21fde0903b394ca4765b17321a736983c43886cb Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 1 Mar 2018 16:07:58 +0000 Subject: [PATCH 279/830] Update documentation --- src/liballoc/slice.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 63b22bd0f6d8..32ade0b01783 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1314,7 +1314,7 @@ impl [T] { /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of /// two or more sorted sequences concatenated one after another. /// - /// The algorithm allocates temporary storage the size of `self`. + /// The algorithm allocates temporary storage in a `Vec<(K, usize)` the length of the slice. /// /// # Examples /// @@ -1326,8 +1326,8 @@ impl [T] { /// ``` #[stable(feature = "slice_sort_by_key", since = "1.7.0")] #[inline] - pub fn sort_by_key(&mut self, f: F) - where F: FnMut(&T) -> B, B: Ord + pub fn sort_by_key(&mut self, f: F) + where F: FnMut(&T) -> K, K: Ord { let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); // The elements of `indices` are unique, as they are indexed, so any sort will be stable @@ -1418,8 +1418,8 @@ impl [T] { /// Sorts the slice with a key extraction function, but may not preserve the order of equal /// elements. /// - /// Note that, currently, the key function for `sort_unstable_by_key` is called multiple times - /// per element, unlike `sort_stable_by_key`. + /// Note that, currently, the key function for [`sort_unstable_by_key`] is called multiple times + /// per element, unlike [`sort_by_key`]. /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. @@ -1432,8 +1432,8 @@ impl [T] { /// randomization to avoid degenerate cases, but with a fixed seed to always provide /// deterministic behavior. /// - /// Due to its key calling strategy, `sort_unstable_by_key` is likely to be slower than - /// `sort_by_key` in cases where the key function is expensive. + /// Due to its key calling strategy, [`sort_unstable_by_key`] is likely to be slower than + /// [`sort_by_key`] in cases where the key function is expensive. /// /// # Examples /// @@ -1444,12 +1444,13 @@ impl [T] { /// assert!(v == [1, 2, -3, 4, -5]); /// ``` /// + /// [`sort_by_key`]: #method.sort_by_key + /// [`sort_unstable_by_key`]: #method.sort_unstable_by_key /// [pdqsort]: https://github.com/orlp/pdqsort #[stable(feature = "sort_unstable", since = "1.20.0")] #[inline] - pub fn sort_unstable_by_key(&mut self, f: F) - where F: FnMut(&T) -> B, - B: Ord + pub fn sort_unstable_by_key(&mut self, f: F) + where F: FnMut(&T) -> K, K: Ord { core_slice::SliceExt::sort_unstable_by_key(self, f); } From 7dcfc07d2c441e6e18c34dfe844c7bdc1c0137fe Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 2 Mar 2018 15:51:20 +0000 Subject: [PATCH 280/830] Cull the quadratic --- src/liballoc/slice.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 32ade0b01783..3fa5e78c04f4 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1339,6 +1339,7 @@ impl [T] { while index < i { index = indices[index].1; } + indices[i].1 = index; self.swap(i, index); } } From bdcc6f939a10bc23a434b2ef301238650841dec9 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 2 Mar 2018 16:28:55 +0000 Subject: [PATCH 281/830] Index enumeration by minimally sized type --- src/liballoc/slice.rs | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 3fa5e78c04f4..fbd8d8793084 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -102,6 +102,7 @@ use core::mem::size_of; use core::mem; use core::ptr; use core::slice as core_slice; +use core::{u8, u16, u32}; use borrow::{Borrow, BorrowMut, ToOwned}; use boxed::Box; @@ -1329,19 +1330,31 @@ impl [T] { pub fn sort_by_key(&mut self, f: F) where F: FnMut(&T) -> K, K: Ord { - let mut indices: Vec<_> = self.iter().map(f).enumerate().map(|(i, k)| (k, i)).collect(); - // The elements of `indices` are unique, as they are indexed, so any sort will be stable - // with respect to the original slice. We use `sort_unstable` here because it requires less - // memory allocation. - indices.sort_unstable(); - for i in 0..self.len() { - let mut index = indices[i].1; - while index < i { - index = indices[index].1; - } - indices[i].1 = index; - self.swap(i, index); + // Helper macro for indexing our vector by the smallest possible type, to reduce allocation. + macro_rules! sort_by_key { + ($t:ty, $slice:ident, $f:ident) => ({ + let mut indices: Vec<_> = + $slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect(); + // The elements of `indices` are unique, as they are indexed, so any sort will be + // stable with respect to the original slice. We use `sort_unstable` here because it + // requires less memory allocation. + indices.sort_unstable(); + for i in 0..$slice.len() { + let mut index = indices[i].1; + while (index as usize) < i { + index = indices[index as usize].1; + } + indices[i].1 = index; + $slice.swap(i, index as usize); + } + }) } + + let len = self.len(); + if len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) } + if len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) } + if len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) } + sort_by_key!(usize, self, f) } /// Sorts the slice, but may not preserve the order of equal elements. From 3304c76874b42233d9a552576c637acbb40bc8f4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 15 Mar 2018 11:35:07 -0700 Subject: [PATCH 282/830] rustbuild: Add more MinGW libraries to ship Closes #49044 --- src/bootstrap/dist.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c3d8c9f8c010..5e2df80af373 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -203,11 +203,14 @@ fn make_win_dist( "libbcrypt.a", "libcomctl32.a", "libcomdlg32.a", + "libcredui.a", "libcrypt32.a", + "libdbghelp.a", "libgdi32.a", "libimagehlp.a", "libiphlpapi.a", "libkernel32.a", + "libmsimg32.a", "libmsvcrt.a", "libodbc32.a", "libole32.a", @@ -215,6 +218,7 @@ fn make_win_dist( "libopengl32.a", "libpsapi.a", "librpcrt4.a", + "libsecur32.a", "libsetupapi.a", "libshell32.a", "libuser32.a", @@ -225,8 +229,6 @@ fn make_win_dist( "libwinspool.a", "libws2_32.a", "libwsock32.a", - "libdbghelp.a", - "libmsimg32.a", ]; //Find mingw artifacts we want to bundle From f41a26f2040dfa752825a7d1fdfbd5a8ae3310cf Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 16 Mar 2018 14:37:17 +0000 Subject: [PATCH 283/830] Add sort_by_cached_key method --- src/liballoc/slice.rs | 63 ++++++++++++++++++++++++++++++------- src/liballoc/tests/slice.rs | 9 ++++-- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index fbd8d8793084..306c467f048c 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1303,11 +1303,17 @@ impl [T] { /// Sorts the slice with a key extraction function. /// - /// During sorting, the key function is called only once per element. - /// - /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)` + /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log m n)` /// worst-case, where the key function is `O(m)`. /// + /// For expensive key functions (e.g. functions that are not simple property accesses or + /// basic operations), [`sort_by_cached_key`](#method.sort_by_cached_key) is likely to be + /// significantly faster, as it does not recompute element keys. + /// + /// When applicable, unstable sorting is preferred because it is generally faster than stable + /// sorting and it doesn't allocate auxiliary memory. + /// See [`sort_unstable_by_key`](#method.sort_unstable_by_key). + /// /// # Current implementation /// /// The current algorithm is an adaptive, iterative merge sort inspired by @@ -1315,7 +1321,8 @@ impl [T] { /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of /// two or more sorted sequences concatenated one after another. /// - /// The algorithm allocates temporary storage in a `Vec<(K, usize)` the length of the slice. + /// Also, it allocates temporary storage half the size of `self`, but for short slices a + /// non-allocating insertion sort is used instead. /// /// # Examples /// @@ -1327,7 +1334,43 @@ impl [T] { /// ``` #[stable(feature = "slice_sort_by_key", since = "1.7.0")] #[inline] - pub fn sort_by_key(&mut self, f: F) + pub fn sort_by_key(&mut self, mut f: F) + where F: FnMut(&T) -> K, K: Ord + { + merge_sort(self, |a, b| f(a).lt(&f(b))); + } + + /// Sorts the slice with a key extraction function. + /// + /// During sorting, the key function is called only once per element. + /// + /// This sort is stable (i.e. does not reorder equal elements) and `O(m n + n log n)` + /// worst-case, where the key function is `O(m)`. + /// + /// For simple key functions (e.g. functions that are property accesses or + /// basic operations), [`sort_by_key`](#method.sort_by_key) is likely to be + /// faster. + /// + /// # Current implementation + /// + /// The current algorithm is an adaptive, iterative merge sort inspired by + /// [timsort](https://en.wikipedia.org/wiki/Timsort). + /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of + /// two or more sorted sequences concatenated one after another. + /// + /// The algorithm allocates temporary storage in a `Vec<(K, usize)>` the length of the slice. + /// + /// # Examples + /// + /// ``` + /// let mut v = [-5i32, 4, 1, -3, 2]; + /// + /// v.sort_by_cached_key(|k| k.abs()); + /// assert!(v == [1, 2, -3, 4, -5]); + /// ``` + #[unstable(feature = "slice_sort_by_uncached_key", issue = "34447")] + #[inline] + pub fn sort_by_cached_key(&mut self, f: F) where F: FnMut(&T) -> K, K: Ord { // Helper macro for indexing our vector by the smallest possible type, to reduce allocation. @@ -1432,9 +1475,6 @@ impl [T] { /// Sorts the slice with a key extraction function, but may not preserve the order of equal /// elements. /// - /// Note that, currently, the key function for [`sort_unstable_by_key`] is called multiple times - /// per element, unlike [`sort_by_key`]. - /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. /// @@ -1446,8 +1486,9 @@ impl [T] { /// randomization to avoid degenerate cases, but with a fixed seed to always provide /// deterministic behavior. /// - /// Due to its key calling strategy, [`sort_unstable_by_key`] is likely to be slower than - /// [`sort_by_key`] in cases where the key function is expensive. + /// Due to its key calling strategy, [`sort_unstable_by_key`](#method.sort_unstable_by_key) + /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_uncached_key) in + /// cases where the key function is expensive. /// /// # Examples /// @@ -1458,8 +1499,6 @@ impl [T] { /// assert!(v == [1, 2, -3, 4, -5]); /// ``` /// - /// [`sort_by_key`]: #method.sort_by_key - /// [`sort_unstable_by_key`]: #method.sort_unstable_by_key /// [pdqsort]: https://github.com/orlp/pdqsort #[stable(feature = "sort_unstable", since = "1.20.0")] #[inline] diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 300f6abaa7f1..7d4dac1c5ec9 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -426,9 +426,12 @@ fn test_sort() { assert!(v.windows(2).all(|w| w[0] >= w[1])); // Sort in lexicographic order. - let mut v = orig.clone(); - v.sort_by_key(|x| x.to_string()); - assert!(v.windows(2).all(|w| w[0].to_string() <= w[1].to_string())); + let mut v1 = orig.clone(); + let mut v2 = orig.clone(); + v1.sort_by_key(|x| x.to_string()); + v2.sort_by_cached_key(|x| x.to_string()); + assert!(v1.windows(2).all(|w| w[0].to_string() <= w[1].to_string())); + assert!(v1 == v2); // Sort with many pre-sorted runs. let mut v = orig.clone(); From ee4a7eba451cc631a8fb7ab4562d37074ec7b048 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 16 Mar 2018 16:18:14 +0100 Subject: [PATCH 284/830] incr.comp.: Make sanity check in try_mark_green() aware of error conditions. --- src/librustc/dep_graph/graph.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 210bdd8d5ddc..0ad79eacd2b0 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -648,8 +648,15 @@ impl DepGraph { return None } None => { - bug!("try_mark_green() - Forcing the DepNode \ - should have set its color") + if !tcx.sess.has_errors() { + bug!("try_mark_green() - Forcing the DepNode \ + should have set its color") + } else { + // If the query we just forced has resulted + // in some kind of compilation error, we + // don't expect that the corresponding + // dep-node color has been updated. + } } } } else { From 15bab452f30ce6cb67a849f13e9de80586a8b180 Mon Sep 17 00:00:00 2001 From: Andrew Cann Date: Thu, 15 Mar 2018 14:14:48 +0800 Subject: [PATCH 285/830] Add From for TryFromIntError --- src/libcore/num/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index faeb87cf944c..4583e45bb12e 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3595,6 +3595,13 @@ impl fmt::Display for TryFromIntError { } } +#[unstable(feature = "try_from", issue = "33417")] +impl From for TryFromIntError { + fn from(never: !) -> TryFromIntError { + never + } +} + // no possible bounds violation macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( From 49dac83f84e5d134f6aa5e2982f117d4add04f5d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 16 Mar 2018 09:59:42 +0100 Subject: [PATCH 286/830] Cleanup metadata and incremental cache processing of constants --- src/librustc/mir/interpret/mod.rs | 82 ++++++++++- src/librustc/ty/maps/on_disk_cache.rs | 128 +++++++++--------- src/librustc_metadata/decoder.rs | 68 ++++------ src/librustc_metadata/encoder.rs | 44 +++--- .../issue-49081.rs | 18 +++ 5 files changed, 213 insertions(+), 127 deletions(-) create mode 100644 src/test/incremental/static_refering_to_other_static/issue-49081.rs diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 67f30f53a681..04ffb9af29ed 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -15,11 +15,13 @@ pub use self::value::{PrimVal, PrimValKind, Value, Pointer}; use std::collections::BTreeMap; use std::fmt; use mir; -use ty; +use hir::def_id::DefId; +use ty::{self, TyCtxt}; use ty::layout::{self, Align, HasDataLayout}; use middle::region; use std::iter; use syntax::ast::Mutability; +use rustc_serialize::{Encoder, Decoder, Decodable, Encodable}; #[derive(Clone, Debug, PartialEq)] pub enum Lock { @@ -152,6 +154,84 @@ pub struct AllocId(pub u64); impl ::rustc_serialize::UseSpecializedEncodable for AllocId {} impl ::rustc_serialize::UseSpecializedDecodable for AllocId {} +pub const ALLOC_DISCRIMINANT: usize = 0; +pub const FN_DISCRIMINANT: usize = 1; + +pub fn specialized_encode_alloc_id< + 'a, 'tcx, + E: Encoder, +>( + encoder: &mut E, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + alloc_id: AllocId, + shorthand: Option, +) -> Result<(), E::Error> { + if let Some(shorthand) = shorthand { + return shorthand.encode(encoder); + } + if let Some(alloc) = tcx.interpret_interner.get_alloc(alloc_id) { + trace!("encoding {:?} with {:#?}", alloc_id, alloc); + ALLOC_DISCRIMINANT.encode(encoder)?; + alloc.encode(encoder)?; + tcx.interpret_interner + .get_corresponding_static_def_id(alloc_id) + .encode(encoder)?; + } else if let Some(fn_instance) = tcx.interpret_interner.get_fn(alloc_id) { + trace!("encoding {:?} with {:#?}", alloc_id, fn_instance); + FN_DISCRIMINANT.encode(encoder)?; + fn_instance.encode(encoder)?; + } else { + bug!("alloc id without corresponding allocation: {}", alloc_id); + } + Ok(()) +} + +pub fn specialized_decode_alloc_id< + 'a, 'tcx, + D: Decoder, + CACHE: FnOnce(&mut D, usize, AllocId), + SHORT: FnOnce(&mut D, usize) -> Result +>( + decoder: &mut D, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + pos: usize, + cache: CACHE, + short: SHORT, +) -> Result { + match usize::decode(decoder)? { + ALLOC_DISCRIMINANT => { + let alloc_id = tcx.interpret_interner.reserve(); + trace!("creating alloc id {:?} at {}", alloc_id, pos); + // insert early to allow recursive allocs + cache(decoder, pos, alloc_id); + + let allocation = Allocation::decode(decoder)?; + trace!("decoded alloc {:?} {:#?}", alloc_id, allocation); + let allocation = tcx.intern_const_alloc(allocation); + tcx.interpret_interner.intern_at_reserved(alloc_id, allocation); + + if let Some(glob) = Option::::decode(decoder)? { + tcx.interpret_interner.cache(glob, alloc_id); + } + + Ok(alloc_id) + }, + FN_DISCRIMINANT => { + trace!("creating fn alloc id at {}", pos); + let instance = ty::Instance::decode(decoder)?; + trace!("decoded fn alloc instance: {:?}", instance); + let id = tcx.interpret_interner.create_fn_alloc(instance); + trace!("created fn alloc id: {:?}", id); + cache(decoder, pos, id); + Ok(id) + }, + shorthand => { + trace!("loading shorthand {}", shorthand); + short(decoder, shorthand) + }, + } +} + impl fmt::Display for AllocId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index 35e874b74d9a..e56d8f8e818d 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -75,6 +75,13 @@ pub struct OnDiskCache<'sess> { // A map from dep-node to the position of any associated diagnostics in // `serialized_data`. prev_diagnostics_index: FxHashMap, + + // A cache to ensure we don't read allocations twice + interpret_alloc_cache: RefCell>, + + // A map from positions to size of the serialized allocation + // so we can skip over already processed allocations + interpret_alloc_size: RefCell>, } // This type is used only for (de-)serialization. @@ -140,6 +147,8 @@ impl<'sess> OnDiskCache<'sess> { query_result_index: footer.query_result_index.into_iter().collect(), prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(), synthetic_expansion_infos: RefCell::new(FxHashMap()), + interpret_alloc_cache: RefCell::new(FxHashMap::default()), + interpret_alloc_size: RefCell::new(FxHashMap::default()), } } @@ -155,6 +164,8 @@ impl<'sess> OnDiskCache<'sess> { query_result_index: FxHashMap(), prev_diagnostics_index: FxHashMap(), synthetic_expansion_infos: RefCell::new(FxHashMap()), + interpret_alloc_cache: RefCell::new(FxHashMap::default()), + interpret_alloc_size: RefCell::new(FxHashMap::default()), } } @@ -381,7 +392,8 @@ impl<'sess> OnDiskCache<'sess> { file_index_to_file: &self.file_index_to_file, file_index_to_stable_id: &self.file_index_to_stable_id, synthetic_expansion_infos: &self.synthetic_expansion_infos, - interpret_alloc_cache: FxHashMap::default(), + interpret_alloc_cache: &self.interpret_alloc_cache, + interpret_alloc_size: &self.interpret_alloc_size, }; match decode_tagged(&mut decoder, dep_node_index) { @@ -443,7 +455,8 @@ struct CacheDecoder<'a, 'tcx: 'a, 'x> { synthetic_expansion_infos: &'x RefCell>, file_index_to_file: &'x RefCell>>, file_index_to_stable_id: &'x FxHashMap, - interpret_alloc_cache: FxHashMap, + interpret_alloc_cache: &'x RefCell>, + interpret_alloc_size: &'x RefCell>, } impl<'a, 'tcx, 'x> CacheDecoder<'a, 'tcx, 'x> { @@ -565,47 +578,37 @@ implement_ty_decoder!( CacheDecoder<'a, 'tcx, 'x> ); impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { fn specialized_decode(&mut self) -> Result { - const MAX1: usize = usize::max_value() - 1; let tcx = self.tcx; let pos = TyDecoder::position(self); - match usize::decode(self)? { - ::std::usize::MAX => { - let alloc_id = tcx.interpret_interner.reserve(); - trace!("creating alloc id {:?} at {}", alloc_id, pos); - // insert early to allow recursive allocs - self.interpret_alloc_cache.insert(pos, alloc_id); - - let allocation = interpret::Allocation::decode(self)?; - trace!("decoded alloc {:?} {:#?}", alloc_id, allocation); - let allocation = self.tcx.intern_const_alloc(allocation); - tcx.interpret_interner.intern_at_reserved(alloc_id, allocation); - - if let Some(glob) = Option::::decode(self)? { - trace!("connecting alloc {:?} with {:?}", alloc_id, glob); - tcx.interpret_interner.cache(glob, alloc_id); - } - - Ok(alloc_id) - }, - MAX1 => { - trace!("creating fn alloc id at {}", pos); - let instance = ty::Instance::decode(self)?; - trace!("decoded fn alloc instance: {:?}", instance); - let id = tcx.interpret_interner.create_fn_alloc(instance); - trace!("created fn alloc id: {:?}", id); - self.interpret_alloc_cache.insert(pos, id); - Ok(id) - }, - shorthand => { - trace!("loading shorthand {}", shorthand); - if let Some(&alloc_id) = self.interpret_alloc_cache.get(&shorthand) { - return Ok(alloc_id); - } - trace!("shorthand {} not cached, loading entire allocation", shorthand); - // need to load allocation - self.with_position(shorthand, |this| interpret::AllocId::decode(this)) - }, + trace!("specialized_decode_alloc_id: {:?}", pos); + if let Some(cached) = self.interpret_alloc_cache.borrow().get(&pos).cloned() { + // if there's no end position we are currently deserializing a recursive + // allocation + if let Some(end) = self.interpret_alloc_size.borrow().get(&pos).cloned() { + trace!("{} already cached as {:?}", pos, cached); + // skip ahead + self.opaque.set_position(end); + return Ok(cached) + } } + let id = interpret::specialized_decode_alloc_id( + self, + tcx, + pos, + |this, pos, alloc_id| { + assert!(this.interpret_alloc_cache.borrow_mut().insert(pos, alloc_id).is_none()); + }, + |this, shorthand| { + // need to load allocation + this.with_position(shorthand, |this| interpret::AllocId::decode(this)) + } + )?; + assert!(self + .interpret_alloc_size + .borrow_mut() + .insert(pos, TyDecoder::position(self)) + .is_none()); + Ok(id) } } impl<'a, 'tcx, 'x> SpecializedDecoder for CacheDecoder<'a, 'tcx, 'x> { @@ -806,30 +809,27 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder for CacheEncoder< where E: 'enc + ty_codec::TyEncoder { fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> { - trace!("encoding {:?} at {}", alloc_id, self.position()); - if let Some(shorthand) = self.interpret_alloc_shorthands.get(alloc_id).cloned() { - trace!("encoding {:?} as shorthand to {}", alloc_id, shorthand); - return shorthand.encode(self); - } - let start = self.position(); - // cache the allocation shorthand now, because the allocation itself might recursively - // point to itself. - self.interpret_alloc_shorthands.insert(*alloc_id, start); - if let Some(alloc) = self.tcx.interpret_interner.get_alloc(*alloc_id) { - trace!("encoding {:?} with {:#?}", alloc_id, alloc); - usize::max_value().encode(self)?; - alloc.encode(self)?; - self.tcx.interpret_interner - .get_corresponding_static_def_id(*alloc_id) - .encode(self)?; - } else if let Some(fn_instance) = self.tcx.interpret_interner.get_fn(*alloc_id) { - trace!("encoding {:?} with {:#?}", alloc_id, fn_instance); - (usize::max_value() - 1).encode(self)?; - fn_instance.encode(self)?; - } else { - bug!("alloc id without corresponding allocation: {}", alloc_id); - } - Ok(()) + use std::collections::hash_map::Entry; + let tcx = self.tcx; + let pos = self.position(); + let shorthand = match self.interpret_alloc_shorthands.entry(*alloc_id) { + Entry::Occupied(entry) => Some(entry.get().clone()), + Entry::Vacant(entry) => { + // ensure that we don't place any AllocIds at the very beginning + // of the metadata file, because that would end up making our indices + // not special. It is essentially impossible for that to happen, + // but let's make sure + assert!(pos != interpret::ALLOC_DISCRIMINANT && pos != interpret::FN_DISCRIMINANT); + entry.insert(pos); + None + }, + }; + interpret::specialized_encode_alloc_id( + self, + tcx, + *alloc_id, + shorthand, + ) } } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f44703b9335e..320160b4d611 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -58,6 +58,9 @@ pub struct DecodeContext<'a, 'tcx: 'a> { // interpreter allocation cache interpret_alloc_cache: FxHashMap, + // a cache for sizes of interpreter allocations + // needed to skip already deserialized allocations + interpret_alloc_size: FxHashMap, } /// Abstract over the various ways one can create metadata decoders. @@ -77,6 +80,7 @@ pub trait Metadata<'a, 'tcx>: Copy { last_filemap_index: 0, lazy_state: LazyState::NoNode, interpret_alloc_cache: FxHashMap::default(), + interpret_alloc_size: FxHashMap::default(), } } } @@ -282,46 +286,34 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result { - const MAX1: usize = usize::max_value() - 1; - let tcx = self.tcx.unwrap(); + let tcx = self.tcx.expect("need tcx for AllocId decoding"); let pos = self.position(); - match usize::decode(self)? { - ::std::usize::MAX => { - let alloc_id = tcx.interpret_interner.reserve(); - trace!("creating alloc id {:?} at {}", alloc_id, pos); - // insert early to allow recursive allocs - self.interpret_alloc_cache.insert(pos, alloc_id); - - let allocation = interpret::Allocation::decode(self)?; - trace!("decoded alloc {:?} {:#?}", alloc_id, allocation); - let allocation = self.tcx.unwrap().intern_const_alloc(allocation); - tcx.interpret_interner.intern_at_reserved(alloc_id, allocation); - - if let Some(glob) = Option::::decode(self)? { - tcx.interpret_interner.cache(glob, alloc_id); - } - - Ok(alloc_id) - }, - MAX1 => { - trace!("creating fn alloc id at {}", pos); - let instance = ty::Instance::decode(self)?; - trace!("decoded fn alloc instance: {:?}", instance); - let id = tcx.interpret_interner.create_fn_alloc(instance); - trace!("created fn alloc id: {:?}", id); - self.interpret_alloc_cache.insert(pos, id); - Ok(id) - }, - shorthand => { - trace!("loading shorthand {}", shorthand); - if let Some(&alloc_id) = self.interpret_alloc_cache.get(&shorthand) { - return Ok(alloc_id); - } - trace!("shorthand {} not cached, loading entire allocation", shorthand); - // need to load allocation - self.with_position(shorthand, |this| interpret::AllocId::decode(this)) - }, + if let Some(cached) = self.interpret_alloc_cache.get(&pos).cloned() { + // if there's no end position we are currently deserializing a recursive + // allocation + if let Some(end) = self.interpret_alloc_size.get(&pos).cloned() { + trace!("{} already cached as {:?}", pos, cached); + // skip ahead + self.opaque.set_position(end); + return Ok(cached) + } } + let id = interpret::specialized_decode_alloc_id( + self, + tcx, + pos, + |this, pos, alloc_id| { this.interpret_alloc_cache.insert(pos, alloc_id); }, + |this, shorthand| { + // need to load allocation + this.with_position(shorthand, |this| interpret::AllocId::decode(this)) + } + )?; + let end_pos = self.position(); + assert!(self + .interpret_alloc_size + .insert(pos, end_pos) + .is_none()); + Ok(id) } } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d95948241748..0da23c2caf4a 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -196,30 +196,26 @@ impl<'a, 'tcx> SpecializedEncoder> for EncodeContext<'a, 'tcx> { impl<'a, 'tcx> SpecializedEncoder for EncodeContext<'a, 'tcx> { fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> { - trace!("encoding {:?} at {}", alloc_id, self.position()); - if let Some(shorthand) = self.interpret_alloc_shorthands.get(alloc_id).cloned() { - trace!("encoding {:?} as shorthand to {}", alloc_id, shorthand); - return shorthand.encode(self); - } - let start = self.position(); - // cache the allocation shorthand now, because the allocation itself might recursively - // point to itself. - self.interpret_alloc_shorthands.insert(*alloc_id, start); - if let Some(alloc) = self.tcx.interpret_interner.get_alloc(*alloc_id) { - trace!("encoding {:?} with {:#?}", alloc_id, alloc); - usize::max_value().encode(self)?; - alloc.encode(self)?; - self.tcx.interpret_interner - .get_corresponding_static_def_id(*alloc_id) - .encode(self)?; - } else if let Some(fn_instance) = self.tcx.interpret_interner.get_fn(*alloc_id) { - trace!("encoding {:?} with {:#?}", alloc_id, fn_instance); - (usize::max_value() - 1).encode(self)?; - fn_instance.encode(self)?; - } else { - bug!("alloc id without corresponding allocation: {}", alloc_id); - } - Ok(()) + use std::collections::hash_map::Entry; + let tcx = self.tcx; + let pos = self.position(); + let shorthand = match self.interpret_alloc_shorthands.entry(*alloc_id) { + Entry::Occupied(entry) => Some(entry.get().clone()), + Entry::Vacant(entry) => { + // ensure that we don't place any AllocIds at the very beginning + // of the metadata file, because that would end up making our 0 and 1 indices + // not special. This is essentially impossible, but let's make sure + assert!(pos != 0 && pos != 1); + entry.insert(pos); + None + }, + }; + interpret::specialized_encode_alloc_id( + self, + tcx, + *alloc_id, + shorthand, + ) } } diff --git a/src/test/incremental/static_refering_to_other_static/issue-49081.rs b/src/test/incremental/static_refering_to_other_static/issue-49081.rs new file mode 100644 index 000000000000..6345b456523e --- /dev/null +++ b/src/test/incremental/static_refering_to_other_static/issue-49081.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49081 + +// revisions:rpass1 rpass2 + +pub static A: i32 = 42; +pub static B: &i32 = &A; + +fn main() {} From bda584386e2ba4f09118b906abe657b0f679e77f Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 11:38:06 -0500 Subject: [PATCH 287/830] re-enable resting librustdoc --- src/bootstrap/builder.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index fab7a2b3fcc5..46453657ac7e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -309,8 +309,8 @@ impl<'a> Builder<'a> { test::CompileFailFullDeps, test::IncrementalFullDeps, test::Rustdoc, test::Pretty, test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty, test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake, - test::Crate, test::CrateLibrustc, test::Rustdoc, test::Linkcheck, test::Cargotest, - test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck, + test::Crate, test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck, + test::Cargotest, test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck, test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample, test::TheBook, test::UnstableBook, test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme), From f02dc74c2cf1afb049f8978c885589a26fb6676b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 16 Mar 2018 12:45:47 -0400 Subject: [PATCH 288/830] extend stable hasher to support `CanonicalTy` --- src/librustc/ich/impls_ty.rs | 50 +++++++++++++++++++- src/librustc/macros.rs | 2 +- src/librustc/traits/query/dropck_outlives.rs | 1 + src/test/incremental/issue-49043.rs | 22 +++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 src/test/incremental/issue-49043.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index bb3051b546e6..3d5b65d5ac87 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -902,13 +902,59 @@ for ty::TypeVariants<'gcx> TyForeign(def_id) => { def_id.hash_stable(hcx, hasher); } - TyInfer(..) => { - bug!("ty::TypeVariants::hash_stable() - Unexpected variant {:?}.", *self) + TyInfer(infer_ty) => { + infer_ty.hash_stable(hcx, hasher); } } } } +impl_stable_hash_for!(enum ty::InferTy { + TyVar(a), + IntVar(a), + FloatVar(a), + FreshTy(a), + FreshIntTy(a), + FreshFloatTy(a), + CanonicalTy(a), +}); + +impl<'a, 'gcx> HashStable> +for ty::TyVid +{ + fn hash_stable(&self, + _hcx: &mut StableHashingContext<'a>, + _hasher: &mut StableHasher) { + // TyVid values are confined to an inference context and hence + // should not be hashed. + bug!("ty::TypeVariants::hash_stable() - can't hash a TyVid {:?}.", *self) + } +} + +impl<'a, 'gcx> HashStable> +for ty::IntVid +{ + fn hash_stable(&self, + _hcx: &mut StableHashingContext<'a>, + _hasher: &mut StableHasher) { + // IntVid values are confined to an inference context and hence + // should not be hashed. + bug!("ty::TypeVariants::hash_stable() - can't hash an IntVid {:?}.", *self) + } +} + +impl<'a, 'gcx> HashStable> +for ty::FloatVid +{ + fn hash_stable(&self, + _hcx: &mut StableHashingContext<'a>, + _hasher: &mut StableHasher) { + // FloatVid values are confined to an inference context and hence + // should not be hashed. + bug!("ty::TypeVariants::hash_stable() - can't hash a FloatVid {:?}.", *self) + } +} + impl_stable_hash_for!(struct ty::ParamTy { idx, name diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index d8a723e184d2..7dc84b9ca295 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -72,7 +72,7 @@ macro_rules! __impl_stable_hash_field { #[macro_export] macro_rules! impl_stable_hash_for { - (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* }) => { + (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* $(,)* }) => { impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name { #[inline] fn hash_stable(&self, diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1caab6fd89ef..017c4f5262e2 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -51,6 +51,7 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { let gcx = tcx.global_tcx(); let (c_ty, orig_values) = self.infcx.canonicalize_query(&self.param_env.and(ty)); let span = self.cause.span; + debug!("c_ty = {:?}", c_ty); match &gcx.dropck_outlives(c_ty) { Ok(result) if result.is_proven() => { match self.infcx.instantiate_query_result( diff --git a/src/test/incremental/issue-49043.rs b/src/test/incremental/issue-49043.rs new file mode 100644 index 000000000000..118027b190e2 --- /dev/null +++ b/src/test/incremental/issue-49043.rs @@ -0,0 +1,22 @@ +// 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 hashing involving canonical variables. In this +// test -- which has an intensional error -- the type of the value +// being dropped winds up including a type variable. Canonicalization +// would then produce a `?0` which -- in turn -- triggered an ICE in +// hashing. + +// revisions:cfail1 + +fn main() { + println!("Hello, world! {}",*thread_rng().choose(&[0, 1, 2, 3]).unwrap()); + //[cfail1]~^ ERROR cannot find function `thread_rng` +} From 02ac15cb898a3c74b1bd2453e5ff9fdb35e03157 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 9 Feb 2018 18:53:41 +0100 Subject: [PATCH 289/830] Automatically enable the `clippy` feature of `rls` if clippy builds --- src/Cargo.lock | 194 ++++++------------------------------------ src/Cargo.toml | 1 + src/bootstrap/dist.rs | 6 +- src/bootstrap/lib.rs | 1 + src/bootstrap/test.rs | 18 +++- src/bootstrap/tool.rs | 24 +++++- src/tools/clippy | 2 +- src/tools/miri | 2 +- src/tools/rls | 2 +- 9 files changed, 67 insertions(+), 183 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 63a6b3c66a6a..5c912ef6d1f4 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -296,15 +296,16 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.186" +version = "0.0.188" dependencies = [ - "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "clippy-mini-macro-test 0.2.0", - "clippy_lints 0.0.186", - "compiletest_rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.188", + "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -315,36 +316,16 @@ version = "0.2.0" [[package]] name = "clippy_lints" -version = "0.0.186" +version = "0.0.188" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.2 (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.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clippy_lints" -version = "0.0.187" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)", - "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -404,18 +385,20 @@ dependencies = [ [[package]] name = "compiletest_rs" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 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)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -578,17 +561,6 @@ name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "duct" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "os_pipe 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "shared_child 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "either" version = "1.4.0" @@ -645,14 +617,6 @@ dependencies = [ "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "error-chain" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "error-chain" version = "0.11.0" @@ -921,14 +885,6 @@ name = "is-match" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "itertools" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itertools" version = "0.7.6" @@ -980,7 +936,7 @@ dependencies = [ [[package]] name = "languageserver-types" -version = "0.30.0" +version = "0.31.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)", @@ -1001,11 +957,6 @@ name = "lazy_static" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "lazycell" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "lazycell" version = "0.6.0" @@ -1161,17 +1112,6 @@ dependencies = [ "libc 0.2.39 (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.32 (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 = "miow" version = "0.3.1" @@ -1187,7 +1127,7 @@ version = "0.1.0" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "compiletest_rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1196,32 +1136,11 @@ dependencies = [ name = "multiple_bins" version = "0.1.0" -[[package]] -name = "net2" -version = "0.2.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "nibble_vec" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "nix" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "nodrop" version = "0.1.12" @@ -1308,16 +1227,6 @@ dependencies = [ "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "os_pipe" -version = "0.5.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)", - "nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "owning_ref" version = "0.3.3" @@ -1405,15 +1314,6 @@ dependencies = [ "core 0.0.0", ] -[[package]] -name = "pulldown-cmark" -version = "0.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "pulldown-cmark" version = "0.1.2" @@ -1550,11 +1450,6 @@ name = "regex-syntax" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "regex-syntax" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "regex-syntax" version = "0.5.0" @@ -1586,12 +1481,12 @@ version = "0.126.0" dependencies = [ "cargo 0.27.0", "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.187 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.188", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "languageserver-types 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", + "languageserver-types 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2259,14 +2154,6 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -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" version = "0.8.0" @@ -2338,16 +2225,6 @@ dependencies = [ name = "serialize" version = "0.0.0" -[[package]] -name = "shared_child" -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)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "shell-escape" version = "0.1.3" @@ -2831,15 +2708,6 @@ dependencies = [ name = "workspace_symbol" version = "0.1.0" -[[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" @@ -2883,11 +2751,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" -"checksum clippy_lints 0.0.187 (registry+https://github.com/rust-lang/crates.io-index)" = "f2227eeb80d00b3e6f67d27953224b2087a65e40597e3253b2a25493aac63859" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum compiletest_rs 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6c5aafb5d4a77c6b5fa384fe93c7a9a3561bd88c4b8b8e45187cf5e779b1badc" +"checksum compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d47ca9a69772587159e1c7e20ee1e43dfe5f184d59591eac70e7d3603bdfe57a" "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" @@ -2901,7 +2768,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" -"checksum duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e45aa15fe0a8a8f511e6d834626afd55e49b62e5c8802e18328a87e8a8f6065c" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834" "checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" @@ -2910,7 +2776,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -"checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f" @@ -2935,17 +2800,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" "checksum ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "245bea0ba52531a3739cb8ba99f8689eda13d7faf8c36b6a73ce4421aab42588" "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" -"checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21" "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2abd9fd3242accb0e2e30986f2cf30cda3e19eec5cc6d584b218ce2b1c0e3c" "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483" "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum languageserver-types 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1541f9b22687f060511d213036e1f058797c48e3501e177f01cb6e88de802f5b" +"checksum languageserver-types 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d25086d59f44b80253d5ff96c66a692fb69de8485cf7a25b28677e89126de0d" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" "checksum libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecbd6428006c321c29b6c8a895f0d90152f1cf4fd8faab69fc436a3d9594f63" @@ -2961,11 +2824,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d" -"checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" "checksum nibble_vec 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "62e678237a4c70c5f2b917cefd7d080dfbf800421f06e8a59d4e28ef5130fd9e" -"checksum nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47e49f6982987135c5e9620ab317623e723bd06738fd85377e8d55f57c8b6487" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" "checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" @@ -2977,7 +2837,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1636c9f1d78af9cbcc50e523bfff4a30274108aad5e86761afd4d31e4e184fa7" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" "checksum openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdc5c4a02e69ce65046f1763a0181107038e02176233acb0b3351d7cc588f9" -"checksum os_pipe 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "998bfbb3042e715190fe2a41abfa047d7e8cb81374d2977d7f100eacd8619cb1" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e7f7c9857874e54afeb950eebeae662b1e51a2493666d2ea4c0a5d91dcf0412" "checksum parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "538ef00b7317875071d5e00f603f24d16f0b474c1a5fc0ccb8b454ca72eafa79" @@ -2985,7 +2844,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" -"checksum pulldown-cmark 0.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "378e941dbd392c101f2cb88097fa4d7167bc421d4b88de3ff7dbee503bc3233b" "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" @@ -3001,7 +2859,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" "checksum regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a62bf8bb734ab90b7f234b681b01af396e5d39b028906c210dc04fa1d5e9e5b3" "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" -"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48d7391e7e90e06eaf3aefbe4652464153ecfec64806f3bf77ffc59638a63e77" "checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" "checksum rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4b9a3a3f2345854e39768e6425d1c893855da217183d1c0b3ff6f1664b6b6d" @@ -3024,7 +2881,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" "checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" @@ -3033,7 +2889,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc848d073be32cd982380c06587ea1d433bc1a4c4a111de07ec2286a3ddade8" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" "checksum serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57781ed845b8e742fc2bf306aba8e3b408fe8c366b900e3769fbc39f49eb8b39" -"checksum shared_child 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "099b38928dbe4a0a01fcd8c233183072f14a7d126a34bed05880869be66e14cc" "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" @@ -3084,7 +2939,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767" -"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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df591c3504d014dd791d998123ed00a476c7e26dc6b2e873cb55c6ac9e59fa" "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 c03301852cd3..814c054c51e4 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -72,3 +72,4 @@ cargo = { path = "tools/cargo" } # RLS depends on `rustfmt` from crates.io, so we put this in a `[patch]` section # for crates.io rustfmt-nightly = { path = "tools/rustfmt" } +clippy_lints = { path = "tools/clippy/clippy_lints" } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c3d8c9f8c010..814615790363 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1120,7 +1120,7 @@ impl Step for Rls { // state for RLS isn't testing. let rls = builder.ensure(tool::Rls { compiler: builder.compiler(stage, build.build), - target + target, extra_features: Vec::new() }).or_else(|| { println!("Unable to build RLS, skipping dist"); None })?; install(&rls, &image.join("bin"), 0o755); @@ -1199,11 +1199,11 @@ impl Step for Rustfmt { // Prepare the image directory let rustfmt = builder.ensure(tool::Rustfmt { compiler: builder.compiler(stage, build.build), - target + target, extra_features: Vec::new() }).or_else(|| { println!("Unable to build Rustfmt, skipping dist"); None })?; let cargofmt = builder.ensure(tool::Cargofmt { compiler: builder.compiler(stage, build.build), - target + target, extra_features: Vec::new() }).or_else(|| { println!("Unable to build Cargofmt, skipping dist"); None })?; install(&rustfmt, &image.join("bin"), 0o755); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 938237dd82d5..10a2fc7f58a7 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -115,6 +115,7 @@ #![deny(warnings)] #![feature(core_intrinsics)] +#![feature(slice_concat_ext)] #[macro_use] extern crate build_helper; diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index d5c837c12749..de938ec8e830 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -245,7 +245,7 @@ impl Step for Rls { let host = self.host; let compiler = builder.compiler(stage, host); - builder.ensure(tool::Rls { compiler, target: self.host }); + builder.ensure(tool::Rls { compiler, target: self.host, extra_features: Vec::new() }); let mut cargo = tool::prepare_tool_cargo(builder, compiler, host, @@ -291,7 +291,7 @@ impl Step for Rustfmt { let host = self.host; let compiler = builder.compiler(stage, host); - builder.ensure(tool::Rustfmt { compiler, target: self.host }); + builder.ensure(tool::Rustfmt { compiler, target: self.host, extra_features: Vec::new() }); let mut cargo = tool::prepare_tool_cargo(builder, compiler, host, @@ -339,7 +339,12 @@ impl Step for Miri { let host = self.host; let compiler = builder.compiler(stage, host); - if let Some(miri) = builder.ensure(tool::Miri { compiler, target: self.host }) { + let miri = builder.ensure(tool::Miri { + compiler, + target: self.host, + extra_features: Vec::new(), + }); + if let Some(miri) = miri { let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test"); cargo.arg("--manifest-path").arg(build.src.join("src/tools/miri/Cargo.toml")); @@ -391,7 +396,12 @@ impl Step for Clippy { let host = self.host; let compiler = builder.compiler(stage, host); - if let Some(clippy) = builder.ensure(tool::Clippy { compiler, target: self.host }) { + let clippy = builder.ensure(tool::Clippy { + compiler, + target: self.host, + extra_features: Vec::new(), + }); + if let Some(clippy) = clippy { let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test"); cargo.arg("--manifest-path").arg(build.src.join("src/tools/clippy/Cargo.toml")); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 9036eb044b5a..5f5b10a07b86 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -12,6 +12,7 @@ use std::fs; use std::env; use std::path::PathBuf; use std::process::{Command, exit}; +use std::slice::SliceConcatExt; use Mode; use Compiler; @@ -74,7 +75,7 @@ impl Step for CleanTools { } } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] struct ToolBuild { compiler: Compiler, target: Interned, @@ -82,6 +83,7 @@ struct ToolBuild { path: &'static str, mode: Mode, is_ext_tool: bool, + extra_features: Vec, } impl Step for ToolBuild { @@ -114,6 +116,7 @@ impl Step for ToolBuild { println!("Building stage{} tool {} ({})", compiler.stage, tool, target); let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path); + cargo.arg("--features").arg(self.extra_features.join(" ")); let is_expected = build.try_run(&mut cargo); build.save_toolstate(tool, if is_expected { ToolState::TestFail @@ -242,6 +245,7 @@ macro_rules! tool { mode: $mode, path: $path, is_ext_tool: false, + extra_features: Vec::new(), }).expect("expected to build -- essential tool") } } @@ -291,6 +295,7 @@ impl Step for RemoteTestServer { mode: Mode::Libstd, path: "src/tools/remote-test-server", is_ext_tool: false, + extra_features: Vec::new(), }).expect("expected to build -- essential tool") } } @@ -409,6 +414,7 @@ impl Step for Cargo { mode: Mode::Librustc, path: "src/tools/cargo", is_ext_tool: false, + extra_features: Vec::new(), }).expect("expected to build -- essential tool") } } @@ -421,10 +427,11 @@ macro_rules! tool_extended { $tool_name:expr, $extra_deps:block;)+) => { $( - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $name { pub compiler: Compiler, pub target: Interned, + pub extra_features: Vec, } impl Step for $name { @@ -441,10 +448,12 @@ macro_rules! tool_extended { run.builder.ensure($name { compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build), target: run.target, + extra_features: Vec::new(), }); } - fn run($sel, $builder: &Builder) -> Option { + #[allow(unused_mut)] + fn run(mut $sel, $builder: &Builder) -> Option { $extra_deps $builder.ensure(ToolBuild { compiler: $sel.compiler, @@ -452,6 +461,7 @@ macro_rules! tool_extended { tool: $tool_name, mode: Mode::Librustc, path: $path, + extra_features: $sel.extra_features, is_ext_tool: true, }) } @@ -472,6 +482,14 @@ tool_extended!((self, builder), }; Miri, miri, "src/tools/miri", "miri", {}; Rls, rls, "src/tools/rls", "rls", { + let clippy = builder.ensure(Clippy { + compiler: self.compiler, + target: self.target, + extra_features: Vec::new(), + }); + if clippy.is_some() { + self.extra_features.push("clippy".to_owned()); + } builder.ensure(native::Openssl { target: self.target, }); diff --git a/src/tools/clippy b/src/tools/clippy index d5e233a72049..6f3f25878f22 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit d5e233a720495c52af25d8f6dcc9e55e1193beb9 +Subproject commit 6f3f25878f2271911e4b6de4d0cf86accc397455 diff --git a/src/tools/miri b/src/tools/miri index 61833b9aeab8..d4712ca37500 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 61833b9aeab8bf8f0c0c0e42b7c96b6eceb37d0d +Subproject commit d4712ca37500f26bbcbf97edcb27820717f769f7 diff --git a/src/tools/rls b/src/tools/rls index b6c524434249..fc4db0a5e99e 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit b6c52443424977bd92cf7ed127f7771fe9c285da +Subproject commit fc4db0a5e99e426fd97de370c6f36f585b6af13a From 50f2884dcdc0c9ba8f24b0c2014f60cb85b0e717 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 16 Mar 2018 12:43:22 -0500 Subject: [PATCH 290/830] Replace many of the last references to readmes --- src/librustc/dep_graph/README.md | 297 +----------------- src/librustc/infer/higher_ranked/mod.rs | 5 +- .../infer/lexical_region_resolve/README.md | 8 +- .../infer/region_constraints/README.md | 9 +- src/librustc/infer/region_constraints/mod.rs | 6 +- src/librustc/middle/liveness.rs | 8 +- src/librustc/middle/region.rs | 6 +- src/librustc/mir/mod.rs | 4 +- src/librustc/ty/sty.rs | 3 +- src/librustc_back/README.md | 8 +- src/librustc_borrowck/borrowck/README.md | 5 + src/librustc_driver/README.md | 6 +- src/librustc_trans/README.md | 8 +- src/libsyntax/README.md | 10 +- 14 files changed, 56 insertions(+), 327 deletions(-) diff --git a/src/librustc/dep_graph/README.md b/src/librustc/dep_graph/README.md index c8d0362f17c8..f1f383d7ad12 100644 --- a/src/librustc/dep_graph/README.md +++ b/src/librustc/dep_graph/README.md @@ -1,295 +1,4 @@ -# Dependency graph for incremental compilation +To learn more about how dependency tracking works in rustc, see the [rustc +guide]. -This module contains the infrastructure for managing the incremental -compilation dependency graph. This README aims to explain how it ought -to be used. In this document, we'll first explain the overall -strategy, and then share some tips for handling specific scenarios. - -The high-level idea is that we want to instrument the compiler to -track which parts of the AST and other IR are read/written by what. -This way, when we come back later, we can look at this graph and -determine what work needs to be redone. - -### The dependency graph - -The nodes of the graph are defined by the enum `DepNode`. They represent -one of three things: - -1. HIR nodes (like `Hir(DefId)`) represent the HIR input itself. -2. Data nodes (like `TypeOfItem(DefId)`) represent some computed - information about a particular item. -3. Procedure nodes (like `CoherenceCheckTrait(DefId)`) represent some - procedure that is executing. Usually this procedure is - performing some kind of check for errors. You can think of them as - computed values where the value being computed is `()` (and the - value may fail to be computed, if an error results). - -An edge `N1 -> N2` is added between two nodes if either: - -- the value of `N1` is used to compute `N2`; -- `N1` is read by the procedure `N2`; -- the procedure `N1` writes the value `N2`. - -The latter two conditions are equivalent to the first one if you think -of procedures as values. - -### Basic tracking - -There is a very general strategy to ensure that you have a correct, if -sometimes overconservative, dependency graph. The two main things you have -to do are (a) identify shared state and (b) identify the current tasks. - -### Identifying shared state - -Identify "shared state" that will be written by one pass and read by -another. In particular, we need to identify shared state that will be -read "across items" -- that is, anything where changes in one item -could invalidate work done for other items. So, for example: - -1. The signature for a function is "shared state". -2. The computed type of some expression in the body of a function is - not shared state, because if it changes it does not itself - invalidate other functions (though it may be that it causes new - monomorphizations to occur, but that's handled independently). - -Put another way: if the HIR for an item changes, we are going to -recompile that item for sure. But we need the dep tracking map to tell -us what *else* we have to recompile. Shared state is anything that is -used to communicate results from one item to another. - -### Identifying the current task, tracking reads/writes, etc - -FIXME(#42293). This text needs to be rewritten for the new red-green -system, which doesn't fully exist yet. - -#### Dependency tracking map - -`DepTrackingMap` is a particularly convenient way to correctly store -shared state. A `DepTrackingMap` is a special hashmap that will add -edges automatically when `get` and `insert` are called. The idea is -that, when you get/insert a value for the key `K`, we will add an edge -from/to the node `DepNode::Variant(K)` (for some variant specific to -the map). - -Each `DepTrackingMap` is parameterized by a special type `M` that -implements `DepTrackingMapConfig`; this trait defines the key and value -types of the map, and also defines a fn for converting from the key to -a `DepNode` label. You don't usually have to muck about with this by -hand, there is a macro for creating it. You can see the complete set -of `DepTrackingMap` definitions in `librustc/middle/ty/maps.rs`. - -As an example, let's look at the `adt_defs` map. The `adt_defs` map -maps from the def-id of a struct/enum to its `AdtDef`. It is defined -using this macro: - -```rust -dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> } -// ~~~~~~~ ~~~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ -// | | Key type Value type -// | DepNode variant -// Name of map id type -``` - -this indicates that a map id type `AdtDefs` will be created. The key -of the map will be a `DefId` and value will be -`ty::AdtDefMaster<'tcx>`. The `DepNode` will be created by -`DepNode::ItemSignature(K)` for a given key. - -Once that is done, you can just use the `DepTrackingMap` like any -other map: - -```rust -let mut map: DepTrackingMap = DepTrackingMap::new(dep_graph); -map.insert(key, value); // registers dep_graph.write -map.get(key; // registers dep_graph.read -``` - -#### Memoization - -One particularly interesting case is memoization. If you have some -shared state that you compute in a memoized fashion, the correct thing -to do is to define a `RefCell` for it and use the -`memoize` helper: - -```rust -map.memoize(key, || /* compute value */) -``` - -This will create a graph that looks like - - ... -> MapVariant(key) -> CurrentTask - -where `MapVariant` is the `DepNode` variant that the map is associated with, -and `...` are whatever edges the `/* compute value */` closure creates. - -In particular, using the memoize helper is much better than writing -the obvious code yourself: - -```rust -if let Some(result) = map.get(key) { - return result; -} -let value = /* compute value */; -map.insert(key, value); -``` - -If you write that code manually, the dependency graph you get will -include artificial edges that are not necessary. For example, imagine that -two tasks, A and B, both invoke the manual memoization code, but A happens -to go first. The resulting graph will be: - - ... -> A -> MapVariant(key) -> B - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // caused by A writing to MapVariant(key) - ~~~~~~~~~~~~~~~~~~~~ // caused by B reading from MapVariant(key) - -This graph is not *wrong*, but it encodes a path from A to B that -should not exist. In contrast, using the memoized helper, you get: - - ... -> MapVariant(key) -> A - | - +----------> B - -which is much cleaner. - -**Be aware though that the closure is executed with `MapVariant(key)` -pushed onto the stack as the current task!** That means that you must -add explicit `read` calls for any shared state that it accesses -implicitly from its environment. See the section on "explicit calls to -read and write when starting a new subtask" above for more details. - -### How to decide where to introduce a new task - -Certainly, you need at least one task on the stack: any attempt to -`read` or `write` shared state will panic if there is no current -task. But where does it make sense to introduce subtasks? The basic -rule is that a subtask makes sense for any discrete unit of work you -may want to skip in the future. Adding a subtask separates out the -reads/writes from *that particular subtask* versus the larger -context. An example: you might have a 'meta' task for all of borrow -checking, and then subtasks for borrow checking individual fns. (Seen -in this light, memoized computations are just a special case where we -may want to avoid redoing the work even within the context of one -compilation.) - -The other case where you might want a subtask is to help with refining -the reads/writes for some later bit of work that needs to be memoized. -For example, we create a subtask for type-checking the body of each -fn. However, in the initial version of incr. comp. at least, we do -not expect to actually *SKIP* type-checking -- we only expect to skip -trans. However, it's still useful to create subtasks for type-checking -individual items, because, otherwise, if a fn sig changes, we won't -know which callers are affected -- in fact, because the graph would be -so coarse, we'd just have to retrans everything, since we can't -distinguish which fns used which fn sigs. - -### Testing the dependency graph - -There are various ways to write tests against the dependency graph. -The simplest mechanism are the -`#[rustc_if_this_changed]` and `#[rustc_then_this_would_need]` -annotations. These are used in compile-fail tests to test whether the -expected set of paths exist in the dependency graph. As an example, -see `src/test/compile-fail/dep-graph-caller-callee.rs`. - -The idea is that you can annotate a test like: - -```rust -#[rustc_if_this_changed] -fn foo() { } - -#[rustc_then_this_would_need(TypeckTables)] //~ ERROR OK -fn bar() { foo(); } - -#[rustc_then_this_would_need(TypeckTables)] //~ ERROR no path -fn baz() { } -``` - -This will check whether there is a path in the dependency graph from -`Hir(foo)` to `TypeckTables(bar)`. An error is reported for each -`#[rustc_then_this_would_need]` annotation that indicates whether a -path exists. `//~ ERROR` annotations can then be used to test if a -path is found (as demonstrated above). - -### Debugging the dependency graph - -#### Dumping the graph - -The compiler is also capable of dumping the dependency graph for your -debugging pleasure. To do so, pass the `-Z dump-dep-graph` flag. The -graph will be dumped to `dep_graph.{txt,dot}` in the current -directory. You can override the filename with the `RUST_DEP_GRAPH` -environment variable. - -Frequently, though, the full dep graph is quite overwhelming and not -particularly helpful. Therefore, the compiler also allows you to filter -the graph. You can filter in three ways: - -1. All edges originating in a particular set of nodes (usually a single node). -2. All edges reaching a particular set of nodes. -3. All edges that lie between given start and end nodes. - -To filter, use the `RUST_DEP_GRAPH_FILTER` environment variable, which should -look like one of the following: - -``` -source_filter // nodes originating from source_filter --> target_filter // nodes that can reach target_filter -source_filter -> target_filter // nodes in between source_filter and target_filter -``` - -`source_filter` and `target_filter` are a `&`-separated list of strings. -A node is considered to match a filter if all of those strings appear in its -label. So, for example: - -``` -RUST_DEP_GRAPH_FILTER='-> TypeckTables' -``` - -would select the predecessors of all `TypeckTables` nodes. Usually though you -want the `TypeckTables` node for some particular fn, so you might write: - -``` -RUST_DEP_GRAPH_FILTER='-> TypeckTables & bar' -``` - -This will select only the `TypeckTables` nodes for fns with `bar` in their name. - -Perhaps you are finding that when you change `foo` you need to re-type-check `bar`, -but you don't think you should have to. In that case, you might do: - -``` -RUST_DEP_GRAPH_FILTER='Hir&foo -> TypeckTables & bar' -``` - -This will dump out all the nodes that lead from `Hir(foo)` to -`TypeckTables(bar)`, from which you can (hopefully) see the source -of the erroneous edge. - -#### Tracking down incorrect edges - -Sometimes, after you dump the dependency graph, you will find some -path that should not exist, but you will not be quite sure how it came -to be. **When the compiler is built with debug assertions,** it can -help you track that down. Simply set the `RUST_FORBID_DEP_GRAPH_EDGE` -environment variable to a filter. Every edge created in the dep-graph -will be tested against that filter -- if it matches, a `bug!` is -reported, so you can easily see the backtrace (`RUST_BACKTRACE=1`). - -The syntax for these filters is the same as described in the previous -section. However, note that this filter is applied to every **edge** -and doesn't handle longer paths in the graph, unlike the previous -section. - -Example: - -You find that there is a path from the `Hir` of `foo` to the type -check of `bar` and you don't think there should be. You dump the -dep-graph as described in the previous section and open `dep-graph.txt` -to see something like: - - Hir(foo) -> Collect(bar) - Collect(bar) -> TypeckTables(bar) - -That first edge looks suspicious to you. So you set -`RUST_FORBID_DEP_GRAPH_EDGE` to `Hir&foo -> Collect&bar`, re-run, and -then observe the backtrace. Voila, bug fixed! +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/query.html diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index a317e0699b4b..d44f2ec95492 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -580,7 +580,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// the pop occurs as part of the rollback, so an explicit call is not /// needed (but is also permitted). /// - /// See `README.md` for more details. + /// For more information about how skolemization for HRTBs works, see + /// the [rustc guide]. + /// + /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html pub fn skolemize_late_bound_regions(&self, binder: &ty::Binder, snapshot: &CombinedSnapshot<'a, 'tcx>) diff --git a/src/librustc/infer/lexical_region_resolve/README.md b/src/librustc/infer/lexical_region_resolve/README.md index a90230870a6c..0086aed3e7c9 100644 --- a/src/librustc/infer/lexical_region_resolve/README.md +++ b/src/librustc/infer/lexical_region_resolve/README.md @@ -1,14 +1,16 @@ # Region inference +> WARNING: This README is obsolete and will be removed soon! For +> more info on how the current borrowck works, see the [rustc guide]. + +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html + ## Terminology Note that we use the terms region and lifetime interchangeably. ## Introduction -See the [general inference README](../README.md) for an overview of -how lexical-region-solving fits into the bigger picture. - Region inference uses a somewhat more involved algorithm than type inference. It is not the most efficient thing ever written though it seems to work well enough in practice (famous last words). The reason diff --git a/src/librustc/infer/region_constraints/README.md b/src/librustc/infer/region_constraints/README.md index 95f9c8c83539..07b87e2012dd 100644 --- a/src/librustc/infer/region_constraints/README.md +++ b/src/librustc/infer/region_constraints/README.md @@ -1,18 +1,25 @@ # Region constraint collection +> WARNING: This README is obsolete and will be removed soon! For +> more info on how the current borrowck works, see the [rustc guide]. + +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html + ## Terminology Note that we use the terms region and lifetime interchangeably. ## Introduction -As described in the [inference README](../README.md), and unlike +As described in the rustc guide [chapter on type inference][ti], and unlike normal type inference, which is similar in spirit to H-M and thus works progressively, the region type inference works by accumulating constraints over the course of a function. Finally, at the end of processing a function, we process and solve the constraints all at once. +[ti]: https://rust-lang-nursery.github.io/rustc-guide/type-inference.html + The constraints are always of one of three possible forms: - `ConstrainVarSubVar(Ri, Rj)` states that region variable Ri must be diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 0c8e49fda184..e864485539b2 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -468,8 +468,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> { /// the APIs in `higher_ranked/mod.rs`, such as /// `skolemize_late_bound_regions` and `plug_leaks`, which will /// guide you on this path (ensure that the `SkolemizationMap` is - /// consumed and you are good). There are also somewhat extensive - /// comments in `higher_ranked/README.md`. + /// consumed and you are good). For more info on how skolemization + /// for HRTBs works, see the [rustc guide]. + /// + /// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html /// /// The `snapshot` argument to this function is not really used; /// it's just there to make it explicit which snapshot bounds the diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d13b16dce898..966353b53a95 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -402,12 +402,10 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) { fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) { for pat in &arm.pats { - // for struct patterns, take note of which fields used shorthand (`x` - // rather than `x: x`) + // for struct patterns, take note of which fields used shorthand (`x` rather than `x: x`) // - // FIXME: according to the rust-lang-nursery/rustc-guide book and - // librustc/README.md, `NodeId`s are to be phased out in favor of - // `HirId`s; however, we need to match the signature of `each_binding`, + // FIXME: according to the rust-lang-nursery/rustc-guide book, `NodeId`s are to be phased + // out in favor of `HirId`s; however, we need to match the signature of `each_binding`, // which uses `NodeIds`. let mut shorthand_field_ids = NodeSet(); if let hir::PatKind::Struct(_, ref fields, _) = pat.node { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index c73930553cde..c7396b34c468 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -11,8 +11,10 @@ //! This file builds up the `ScopeTree`, which describes //! the parent links in the region hierarchy. //! -//! Most of the documentation on regions can be found in -//! `middle/infer/region_constraints/README.md` +//! For more information about how MIR-based region-checking works, +//! see the [rustc guide]. +//! +//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html use ich::{StableHashingContext, NodeIdHashingMode}; use util::nodemap::{FxHashMap, FxHashSet}; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 939710ffd2b8..64a1729982a3 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -8,9 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! MIR datatypes and passes. See the module-level [README] for details. +//! MIR datatypes and passes. See the [rustc guide] for more info. //! -//! [README]: https://github.com/rust-lang/rust/blob/master/src/librustc/mir/README.md +//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir.html use graphviz::IntoCow; use middle::const_val::ConstVal; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index ae053d7f4f58..bb5c7b5fd2a5 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -991,10 +991,11 @@ pub type Region<'tcx> = &'tcx RegionKind; /// the inference variable is supposed to satisfy the relation /// *for every value of the skolemized region*. To ensure that doesn't /// happen, you can use `leak_check`. This is more clearly explained -/// by infer/higher_ranked/README.md. +/// by the [rustc guide]. /// /// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/ /// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ +/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trait-hrtb.html #[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)] pub enum RegionKind { // Region bound in a type or fn declaration which will be diff --git a/src/librustc_back/README.md b/src/librustc_back/README.md index bd99c687bb6a..3c01692c12b3 100644 --- a/src/librustc_back/README.md +++ b/src/librustc_back/README.md @@ -1,6 +1,6 @@ -NB: This crate is part of the Rust compiler. For an overview of the -compiler as a whole, see -[the README.md file found in `librustc`](../librustc/README.md). - `librustc_back` contains some very low-level details that are specific to different LLVM targets and so forth. + +For more information about how trans works, see the [rustc guide]. + +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trans.html diff --git a/src/librustc_borrowck/borrowck/README.md b/src/librustc_borrowck/borrowck/README.md index da2b1ef0b1c0..29f03c06ab75 100644 --- a/src/librustc_borrowck/borrowck/README.md +++ b/src/librustc_borrowck/borrowck/README.md @@ -1,5 +1,10 @@ % The Borrow Checker +> WARNING: This README is more or less obsolete, and will be removed +> soon! The new system is described in the [rustc guide]. + +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir-borrowck.html + This pass has the job of enforcing memory safety. This is a subtle topic. This docs aim to explain both the practice and the theory behind the borrow checker. They start with a high-level overview of diff --git a/src/librustc_driver/README.md b/src/librustc_driver/README.md index 839d1831f954..fef249a9e4eb 100644 --- a/src/librustc_driver/README.md +++ b/src/librustc_driver/README.md @@ -1,7 +1,3 @@ -NB: This crate is part of the Rust compiler. For an overview of the -compiler as a whole, see -[the README.md file found in `librustc`](../librustc/README.md). - The `driver` crate is effectively the "main" function for the rust compiler. It orchestrates the compilation process and "knits together" the code from the other crates within rustc. This crate itself does @@ -9,4 +5,6 @@ not contain any of the "main logic" of the compiler (though it does have some code related to pretty printing or other minor compiler options). +For more information about how the driver works, see the [rustc guide]. +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustc-driver.html diff --git a/src/librustc_trans/README.md b/src/librustc_trans/README.md index b69d632a6a0d..d1868ba2abb1 100644 --- a/src/librustc_trans/README.md +++ b/src/librustc_trans/README.md @@ -1,7 +1,7 @@ -NB: This crate is part of the Rust compiler. For an overview of the -compiler as a whole, see -[the README.md file found in `librustc`](../librustc/README.md). - The `trans` crate contains the code to convert from MIR into LLVM IR, and then from LLVM IR into machine code. In general it contains code that runs towards the end of the compilation process. + +For more information about how trans works, see the [rustc guide]. + +[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/trans.html diff --git a/src/libsyntax/README.md b/src/libsyntax/README.md index 3bf735ee8680..7214203830e7 100644 --- a/src/libsyntax/README.md +++ b/src/libsyntax/README.md @@ -1,7 +1,9 @@ -NB: This crate is part of the Rust compiler. For an overview of the -compiler as a whole, see -[the README.md file found in `librustc`](../librustc/README.md). - The `syntax` crate contains those things concerned purely with syntax – that is, the AST ("abstract syntax tree"), parser, pretty-printer, lexer, macro expander, and utilities for traversing ASTs. + +For more information about how these things work in rustc, see the +rustc guide: + +- [Parsing](https://rust-lang-nursery.github.io/rustc-guide/the-parser.html) +- [Macro Expansion](https://rust-lang-nursery.github.io/rustc-guide/macro-expansion.html) From 6a38e6176be6ed1d6903ec08258220cb67e91e29 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 13:29:20 -0500 Subject: [PATCH 291/830] fix doctest --- src/librustdoc/html/markdown.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index ae28e5a0923e..5e55353a26e6 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -21,7 +21,7 @@ //! use rustdoc::html::markdown::Markdown; //! //! let s = "My *markdown* _text_"; -//! let html = format!("{}", Markdown(s)); +//! let html = format!("{}", Markdown(s, &[])); //! // ... something using html //! ``` From f9d38451382017a6cd053e25011e4c096d545d17 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 13:38:06 -0500 Subject: [PATCH 292/830] talk about --crate-version --- src/doc/rustdoc/src/unstable-features.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 9cb5760ec379..867e4585d9c1 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -254,3 +254,15 @@ If both `--playground-url` and `--markdown-playground-url` are present when rend Markdown file, the URL given to `--markdown-playground-url` will take precedence. If both `--playground-url` and `#![doc(html_playground_url = "url")]` are present when rendering crate docs, the attribute will take precedence. + +### `--crate-version`: control the crate version + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --crate-version 1.3.37 +``` + +When `rustdoc` receives this flag, it will print an extra "Version (version)" into the sidebar of +the crate root's docs. You can use this flag to differentiate between different versions of your +library's documentation. From 33ed787b495477f2cc859b275a1deb6dc1a396a0 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 13:46:10 -0500 Subject: [PATCH 293/830] talk about --linker --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 867e4585d9c1..870d77895fd6 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -266,3 +266,16 @@ $ rustdoc src/lib.rs -Z unstable-options --crate-version 1.3.37 When `rustdoc` receives this flag, it will print an extra "Version (version)" into the sidebar of the crate root's docs. You can use this flag to differentiate between different versions of your library's documentation. + +### `--linker`: control the linker used for documentation tests + +Using this flag looks like this: + +```bash +$ rustdoc --test src/lib.rs -Z unstable-options --linker foo +$ rustdoc --test README.md -Z unstable-options --linker foo +``` + +When `rustdoc` runs your documentation tests, it needs to compile and link the tests as executables +before running them. This flag can be used to change the linker used on these executables. It's +equivalent to passing `-C linker=foo` to `rustc`. From cc4f97e88354bea5d07c3ae762ac0466e5c9888c Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 14:30:56 -0500 Subject: [PATCH 294/830] talk about --sort-modules-by-appearance --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 870d77895fd6..80b59166503f 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -279,3 +279,16 @@ $ rustdoc --test README.md -Z unstable-options --linker foo When `rustdoc` runs your documentation tests, it needs to compile and link the tests as executables before running them. This flag can be used to change the linker used on these executables. It's equivalent to passing `-C linker=foo` to `rustc`. + +### `--sort-modules-by-appearance`: control how items on module pages are sorted + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --sort-modules-by-appearance +``` + +Ordinarily, when `rustdoc` prints items in module pages, it will sort them alphabetically (taking +some consideration for their stability, and names that end in a number). Giving this flag to +`rustdoc` will disable this sorting and instead make it print the items in the order they appear in +the source. From 6b2906018f93a9813392056da4c3de855d92f619 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 14:41:51 -0500 Subject: [PATCH 295/830] talk about --themes and --theme-checker --- src/doc/rustdoc/src/unstable-features.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 80b59166503f..3ebc2fa466cb 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -292,3 +292,27 @@ Ordinarily, when `rustdoc` prints items in module pages, it will sort them alpha some consideration for their stability, and names that end in a number). Giving this flag to `rustdoc` will disable this sorting and instead make it print the items in the order they appear in the source. + +### `--themes`: provide additional themes + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --themes theme.css +``` + +Giving this flag to `rustdoc` will make it copy your theme into the generated crate docs and enable +it in the theme selector. Note that `rustdoc` will reject your theme file if it doesn't style +everything the "main" theme does. See `--theme-checker` below for details. + +### `--theme-checker`: verify theme CSS for validity + +Using this flag looks like this: + +```bash +$ rustdoc -Z unstable-options --theme-checker theme.css +``` + +Before including your theme in crate docs, `rustdoc` will compare all the CSS rules it contains +against the "main" theme included by default. Using this flag will allow you to see which rules are +missing if `rustdoc` rejects your theme. From 1c4b9c103496d876ee4254ce5259c89c725c4c5e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 16 Mar 2018 11:42:42 -0700 Subject: [PATCH 296/830] ci: Disable optimized tests for asm.js Since all tests are compiled with LTO effectively in Emscripten this commit disables optimizations to hopefully squeeze some more time out of the CI builders. Closes #48826 --- src/ci/docker/asmjs/Dockerfile | 2 +- src/test/run-pass/deep.rs | 4 +--- src/test/run-pass/float-int-invalid-const-cast.rs | 2 ++ src/test/run-pass/intrinsics-integer.rs | 2 ++ src/test/run-pass/intrinsics-math.rs | 2 ++ src/test/run-pass/issue-32947.rs | 2 ++ src/test/run-pass/issue-38074.rs | 2 ++ src/test/run-pass/issue-39720.rs | 2 ++ src/test/run-pass/mir_heavy_promoted.rs | 2 ++ src/test/run-pass/next-power-of-two-overflow-debug.rs | 1 + src/test/run-pass/next-power-of-two-overflow-ndebug.rs | 1 + src/test/run-pass/packed-struct-borrow-element.rs | 1 + src/test/run-pass/simd-intrinsic-generic-arithmetic.rs | 2 ++ src/test/run-pass/simd-intrinsic-generic-comparison.rs | 2 ++ src/test/run-pass/simd-intrinsic-generic-elements.rs | 2 ++ 15 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile index 2a0901691a55..be1b161f33e0 100644 --- a/src/ci/docker/asmjs/Dockerfile +++ b/src/ci/docker/asmjs/Dockerfile @@ -29,6 +29,6 @@ ENV EM_CONFIG=/emsdk-portable/.emscripten ENV TARGETS=asmjs-unknown-emscripten -ENV RUST_CONFIGURE_ARGS --enable-emscripten +ENV RUST_CONFIGURE_ARGS --enable-emscripten --disable-optimize-tests ENV SCRIPT python2.7 ../x.py test --target $TARGETS diff --git a/src/test/run-pass/deep.rs b/src/test/run-pass/deep.rs index 9ae4f2c1e708..d59fe8d813d2 100644 --- a/src/test/run-pass/deep.rs +++ b/src/test/run-pass/deep.rs @@ -8,9 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - - - +// ignore-emscripten apparently blows the stack fn f(x: isize) -> isize { if x == 1 { return 1; } else { let y: isize = 1 + f(x - 1); return y; } diff --git a/src/test/run-pass/float-int-invalid-const-cast.rs b/src/test/run-pass/float-int-invalid-const-cast.rs index 80ab12482cbb..d44f78922c70 100644 --- a/src/test/run-pass/float-int-invalid-const-cast.rs +++ b/src/test/run-pass/float-int-invalid-const-cast.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten no i128 support + #![feature(i128_type)] #![deny(const_err)] diff --git a/src/test/run-pass/intrinsics-integer.rs b/src/test/run-pass/intrinsics-integer.rs index bfa3a1e128a9..cdfad51e648a 100644 --- a/src/test/run-pass/intrinsics-integer.rs +++ b/src/test/run-pass/intrinsics-integer.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten no i128 support + #![feature(intrinsics, i128_type)] mod rusti { diff --git a/src/test/run-pass/intrinsics-math.rs b/src/test/run-pass/intrinsics-math.rs index a2c55634749c..5132405a9d58 100644 --- a/src/test/run-pass/intrinsics-math.rs +++ b/src/test/run-pass/intrinsics-math.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten fma not implemented in emscripten + macro_rules! assert_approx_eq { ($a:expr, $b:expr) => ({ let (a, b) = (&$a, &$b); diff --git a/src/test/run-pass/issue-32947.rs b/src/test/run-pass/issue-32947.rs index d0fef36efb9c..d059a46b4df1 100644 --- a/src/test/run-pass/issue-32947.rs +++ b/src/test/run-pass/issue-32947.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten FIXME(#45351) + #![feature(repr_simd, test)] extern crate test; diff --git a/src/test/run-pass/issue-38074.rs b/src/test/run-pass/issue-38074.rs index 5c9a63b86166..2368ba8a110b 100644 --- a/src/test/run-pass/issue-38074.rs +++ b/src/test/run-pass/issue-38074.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten FIXME(#45351) + #![feature(platform_intrinsics, repr_simd)] extern "platform-intrinsic" { diff --git a/src/test/run-pass/issue-39720.rs b/src/test/run-pass/issue-39720.rs index f90696e3cdf1..9873a8c2bf44 100644 --- a/src/test/run-pass/issue-39720.rs +++ b/src/test/run-pass/issue-39720.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten FIXME(#45351) + #![feature(repr_simd, platform_intrinsics)] #[repr(C)] diff --git a/src/test/run-pass/mir_heavy_promoted.rs b/src/test/run-pass/mir_heavy_promoted.rs index 9e033421574b..b50852175776 100644 --- a/src/test/run-pass/mir_heavy_promoted.rs +++ b/src/test/run-pass/mir_heavy_promoted.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten apparently only works in optimized mode + const TEST_DATA: [u8; 32 * 1024 * 1024] = [42; 32 * 1024 * 1024]; // Check that the promoted copy of TEST_DATA doesn't diff --git a/src/test/run-pass/next-power-of-two-overflow-debug.rs b/src/test/run-pass/next-power-of-two-overflow-debug.rs index 2782f8c2a598..599c6dfd31d9 100644 --- a/src/test/run-pass/next-power-of-two-overflow-debug.rs +++ b/src/test/run-pass/next-power-of-two-overflow-debug.rs @@ -10,6 +10,7 @@ // compile-flags: -C debug_assertions=yes // ignore-wasm32-bare compiled with panic=abort by default +// ignore-emscripten dies with an LLVM error #![feature(i128_type)] diff --git a/src/test/run-pass/next-power-of-two-overflow-ndebug.rs b/src/test/run-pass/next-power-of-two-overflow-ndebug.rs index f8bcb961c683..f2312b70be67 100644 --- a/src/test/run-pass/next-power-of-two-overflow-ndebug.rs +++ b/src/test/run-pass/next-power-of-two-overflow-ndebug.rs @@ -9,6 +9,7 @@ // except according to those terms. // compile-flags: -C debug_assertions=no +// ignore-emscripten dies with an LLVM error #![feature(i128_type)] diff --git a/src/test/run-pass/packed-struct-borrow-element.rs b/src/test/run-pass/packed-struct-borrow-element.rs index 3041c73afba8..e725b25efee5 100644 --- a/src/test/run-pass/packed-struct-borrow-element.rs +++ b/src/test/run-pass/packed-struct-borrow-element.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten weird assertion? #[repr(packed)] struct Foo { diff --git a/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs b/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs index 1894cd0084bc..ac6d0c697ecc 100644 --- a/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs +++ b/src/test/run-pass/simd-intrinsic-generic-arithmetic.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten FIXME(#45351) hits an LLVM assert + #![feature(repr_simd, platform_intrinsics)] #[repr(simd)] diff --git a/src/test/run-pass/simd-intrinsic-generic-comparison.rs b/src/test/run-pass/simd-intrinsic-generic-comparison.rs index 5802fb30bd68..d27378ba8930 100644 --- a/src/test/run-pass/simd-intrinsic-generic-comparison.rs +++ b/src/test/run-pass/simd-intrinsic-generic-comparison.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten FIXME(#45351) hits an LLVM assert + #![feature(repr_simd, platform_intrinsics, concat_idents)] #![allow(non_camel_case_types)] diff --git a/src/test/run-pass/simd-intrinsic-generic-elements.rs b/src/test/run-pass/simd-intrinsic-generic-elements.rs index f0444c271705..72fcef27a665 100644 --- a/src/test/run-pass/simd-intrinsic-generic-elements.rs +++ b/src/test/run-pass/simd-intrinsic-generic-elements.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten FIXME(#45351) hits an LLVM assert + #![feature(repr_simd, platform_intrinsics)] #[repr(simd)] From 60eb308b421a471fa3ecc2848fb93c6527ec409c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 16 Mar 2018 12:53:51 -0700 Subject: [PATCH 297/830] ci: Run fewer tests on asmjs Many tests run on the asmjs builder like compile-fail, ui, parse-fail, etc, aren't actually specific to asm.js. Instead of running redundant test suites this commit changes things up to only run tests that actually emit JS we then pass to node. --- src/ci/docker/asmjs/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/asmjs/Dockerfile b/src/ci/docker/asmjs/Dockerfile index be1b161f33e0..cb85cf3d9e9f 100644 --- a/src/ci/docker/asmjs/Dockerfile +++ b/src/ci/docker/asmjs/Dockerfile @@ -31,4 +31,9 @@ ENV TARGETS=asmjs-unknown-emscripten ENV RUST_CONFIGURE_ARGS --enable-emscripten --disable-optimize-tests -ENV SCRIPT python2.7 ../x.py test --target $TARGETS +ENV SCRIPT python2.7 ../x.py test --target $TARGETS \ + src/test/run-pass \ + src/test/run-fail \ + src/libstd \ + src/liballoc \ + src/libcore From b5ab5ceb4b2aa733366ed9453c0e714d6f0cd9f0 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Fri, 16 Mar 2018 15:06:36 -0500 Subject: [PATCH 298/830] talk about --resource-suffix --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 3ebc2fa466cb..93489f89626f 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -316,3 +316,16 @@ $ rustdoc -Z unstable-options --theme-checker theme.css Before including your theme in crate docs, `rustdoc` will compare all the CSS rules it contains against the "main" theme included by default. Using this flag will allow you to see which rules are missing if `rustdoc` rejects your theme. + +### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --resource-suffix suf +``` + +When rendering docs, `rustdoc` creates several CSS and JavaScript files as part of the output. Since +all these files are linked from every page, changing where they are can be cumbersome if you need to +specially cache them. This flag will rename all these files in the output to include the suffix in +the filename. For example, `main.css` would become `main-suf.css` with the above command. From b15b023226176d4fc0ceef6cfd5698b7df6787f2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 16 Mar 2018 13:37:14 +0300 Subject: [PATCH 299/830] Update Cargo This notably includes * https://github.com/rust-lang/cargo/pull/5152 * https://github.com/rust-lang/cargo/pull/5188 The first one switches cargo from docopt to clap ( we also update to the latest calp in this repository), the second one should help us to unify feature flags for Cargo itself and RLS, and build Cargo libray only once. --- src/Cargo.lock | 43 +++++++++++++++++-------------------------- src/tools/cargo | 2 +- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 5c912ef6d1f4..c82588e41125 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -56,8 +56,11 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "ar" @@ -181,12 +184,12 @@ version = "0.27.0" dependencies = [ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.16.0", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -205,6 +208,7 @@ dependencies = [ "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -281,13 +285,13 @@ dependencies = [ [[package]] name = "clap" -version = "2.29.0" +version = "2.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.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.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -544,18 +548,6 @@ dependencies = [ "core 0.0.0", ] -[[package]] -name = "docopt" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (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.2" @@ -869,7 +861,7 @@ version = "0.1.0" name = "installer" version = "0.0.0" dependencies = [ - "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1062,7 +1054,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1351,7 +1343,7 @@ name = "racer" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1562,7 +1554,7 @@ dependencies = [ name = "rustbook" version = "0.1.0" dependencies = [ - "clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2287,7 +2279,7 @@ dependencies = [ [[package]] name = "strsim" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2733,7 +2725,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4" @@ -2750,7 +2742,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f" +"checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" @@ -2766,7 +2758,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f46e49c7125131f5afaded06944d6888b55cbdf8eba05dae73c954019b907961" "checksum derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "92f8b8e1d6c8a5f5ea0849a0e4c55941576115c62d3fc425e96918bbbeb3d3c2" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" -"checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834" @@ -2894,7 +2885,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" "checksum socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78e4c1cde1adbc6bc4c394da2e7727c916b9b7d0b53d6984c890c65c1f4e6437" "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 strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)" = "8c5bc2d6ff27891209efa5f63e9de78648d7801f085e4653701a692ce938d6fd" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" diff --git a/src/tools/cargo b/src/tools/cargo index 5f83bb4044f3..d6c3983fe3bd 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 5f83bb4044f32b60d06717c609610f67411fc671 +Subproject commit d6c3983fe3bd8fa06b54712e53fb23645598188b From 9e6268191205c42bc7958d949fa48811d60857f9 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 17 Mar 2018 10:32:29 +0900 Subject: [PATCH 300/830] Remove core::fmt::num::Decimal Before ebf9e1aaf6, it was used for Display::fmt, but ebf9e1aaf6 replaced that with a faster implementation, and nothing else uses it. --- src/libcore/fmt/num.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 2992e7cf8db3..57e3b849ae1e 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -107,10 +107,6 @@ struct Binary; #[derive(Clone, PartialEq)] struct Octal; -/// A decimal (base 10) radix -#[derive(Clone, PartialEq)] -struct Decimal; - /// A hexadecimal (base 16) radix, formatted with lower-case characters #[derive(Clone, PartialEq)] struct LowerHex; @@ -136,7 +132,6 @@ macro_rules! radix { radix! { Binary, 2, "0b", x @ 0 ... 1 => b'0' + x } radix! { Octal, 8, "0o", x @ 0 ... 7 => b'0' + x } -radix! { Decimal, 10, "", x @ 0 ... 9 => b'0' + x } radix! { LowerHex, 16, "0x", x @ 0 ... 9 => b'0' + x, x @ 10 ... 15 => b'a' + (x - 10) } radix! { UpperHex, 16, "0x", x @ 0 ... 9 => b'0' + x, From 38cbdcd0b1791e68c9485d8db6e81cf2d6765572 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 17 Mar 2018 10:42:32 +0900 Subject: [PATCH 301/830] Use an uninitialized buffer in GenericRadix::fmt_int, like in Display::fmt for numeric types The code using a slice of that buffer is only ever going to use bytes that are subsequently initialized. --- src/libcore/fmt/num.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 2992e7cf8db3..c3843cae27af 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -65,7 +65,7 @@ trait GenericRadix { // characters for a base 2 number. let zero = T::zero(); let is_nonnegative = x >= zero; - let mut buf = [0; 128]; + let mut buf: [u8; 128] = unsafe { mem::uninitialized() }; let mut curr = buf.len(); let base = T::from_u8(self.base()); if is_nonnegative { From b910d6b93cdbe075b157621432d271e6afcaa20f Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Sat, 17 Mar 2018 09:45:03 +0900 Subject: [PATCH 302/830] Use associated consts for GenericRadix base and prefix --- src/libcore/fmt/num.rs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 2992e7cf8db3..6378358c2ddc 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -49,15 +49,13 @@ doit! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize } #[doc(hidden)] trait GenericRadix { /// The number of digits. - fn base(&self) -> u8; + const BASE: u8; /// A radix-specific prefix string. - fn prefix(&self) -> &'static str { - "" - } + const PREFIX: &'static str; /// Converts an integer to corresponding radix digit. - fn digit(&self, x: u8) -> u8; + fn digit(x: u8) -> u8; /// Format an integer using the radix using a formatter. fn fmt_int(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { @@ -67,14 +65,14 @@ trait GenericRadix { let is_nonnegative = x >= zero; let mut buf = [0; 128]; let mut curr = buf.len(); - let base = T::from_u8(self.base()); + let base = T::from_u8(Self::BASE); if is_nonnegative { // Accumulate each digit of the number from the least significant // to the most significant figure. for byte in buf.iter_mut().rev() { - let n = x % base; // Get the current place value. - x = x / base; // Deaccumulate the number. - *byte = self.digit(n.to_u8()); // Store the digit in the buffer. + let n = x % base; // Get the current place value. + x = x / base; // Deaccumulate the number. + *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -84,9 +82,9 @@ trait GenericRadix { } else { // Do the same as above, but accounting for two's complement. for byte in buf.iter_mut().rev() { - let n = zero - (x % base); // Get the current place value. - x = x / base; // Deaccumulate the number. - *byte = self.digit(n.to_u8()); // Store the digit in the buffer. + let n = zero - (x % base); // Get the current place value. + x = x / base; // Deaccumulate the number. + *byte = Self::digit(n.to_u8()); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -95,7 +93,7 @@ trait GenericRadix { } } let buf = unsafe { str::from_utf8_unchecked(&buf[curr..]) }; - f.pad_integral(is_nonnegative, self.prefix(), buf) + f.pad_integral(is_nonnegative, Self::PREFIX, buf) } } @@ -122,12 +120,12 @@ struct UpperHex; macro_rules! radix { ($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => { impl GenericRadix for $T { - fn base(&self) -> u8 { $base } - fn prefix(&self) -> &'static str { $prefix } - fn digit(&self, x: u8) -> u8 { + const BASE: u8 = $base; + const PREFIX: &'static str = $prefix; + fn digit(x: u8) -> u8 { match x { $($x => $conv,)+ - x => panic!("number not in the range 0..{}: {}", self.base() - 1, x), + x => panic!("number not in the range 0..{}: {}", Self::BASE - 1, x), } } } From c5f020a64014d461ce997ea6e2e801f17aa44b08 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 17 Mar 2018 10:40:49 +0100 Subject: [PATCH 303/830] Make the deprecated unstable SipHasher24 type private. It is still used by the deprecated *stable* `SipHasher` type. --- src/libcore/hash/mod.rs | 2 +- src/libcore/hash/sip.rs | 45 +++++------------------------------ src/libcore/tests/hash/sip.rs | 12 +++++----- 3 files changed, 13 insertions(+), 46 deletions(-) diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 15545a04b64d..90d9ab3644a8 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -101,7 +101,7 @@ pub use self::sip::SipHasher; #[unstable(feature = "sip_hash_13", issue = "34767")] #[allow(deprecated)] -pub use self::sip::{SipHasher13, SipHasher24}; +pub use self::sip::SipHasher13; mod sip; diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index 4e4d9b3f1e2f..7790118fbde1 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -38,7 +38,7 @@ pub struct SipHasher13 { #[rustc_deprecated(since = "1.13.0", reason = "use `std::collections::hash_map::DefaultHasher` instead")] #[derive(Debug, Clone, Default)] -pub struct SipHasher24 { +struct SipHasher24 { hasher: Hasher, } @@ -156,7 +156,9 @@ impl SipHasher { #[rustc_deprecated(since = "1.13.0", reason = "use `std::collections::hash_map::DefaultHasher` instead")] pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher { - SipHasher(SipHasher24::new_with_keys(key0, key1)) + SipHasher(SipHasher24 { + hasher: Hasher::new_with_keys(key0, key1) + }) } } @@ -182,28 +184,6 @@ impl SipHasher13 { } } -impl SipHasher24 { - /// Creates a new `SipHasher24` with the two initial keys set to 0. - #[inline] - #[unstable(feature = "sip_hash_13", issue = "34767")] - #[rustc_deprecated(since = "1.13.0", - reason = "use `std::collections::hash_map::DefaultHasher` instead")] - pub fn new() -> SipHasher24 { - SipHasher24::new_with_keys(0, 0) - } - - /// Creates a `SipHasher24` that is keyed off the provided keys. - #[inline] - #[unstable(feature = "sip_hash_13", issue = "34767")] - #[rustc_deprecated(since = "1.13.0", - reason = "use `std::collections::hash_map::DefaultHasher` instead")] - pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher24 { - SipHasher24 { - hasher: Hasher::new_with_keys(key0, key1) - } - } -} - impl Hasher { #[inline] fn new_with_keys(key0: u64, key1: u64) -> Hasher { @@ -271,12 +251,12 @@ impl Hasher { impl super::Hasher for SipHasher { #[inline] fn write(&mut self, msg: &[u8]) { - self.0.write(msg) + self.0.hasher.write(msg) } #[inline] fn finish(&self) -> u64 { - self.0.finish() + self.0.hasher.finish() } } @@ -293,19 +273,6 @@ impl super::Hasher for SipHasher13 { } } -#[unstable(feature = "sip_hash_13", issue = "34767")] -impl super::Hasher for SipHasher24 { - #[inline] - fn write(&mut self, msg: &[u8]) { - self.hasher.write(msg) - } - - #[inline] - fn finish(&self) -> u64 { - self.hasher.finish() - } -} - impl super::Hasher for Hasher { // see short_write comment for explanation #[inline] diff --git a/src/libcore/tests/hash/sip.rs b/src/libcore/tests/hash/sip.rs index c6dd41798f2a..bad858011e96 100644 --- a/src/libcore/tests/hash/sip.rs +++ b/src/libcore/tests/hash/sip.rs @@ -11,7 +11,7 @@ #![allow(deprecated)] use core::hash::{Hash, Hasher}; -use core::hash::{SipHasher, SipHasher13, SipHasher24}; +use core::hash::{SipHasher, SipHasher13}; use core::{slice, mem}; // Hash just the bytes of the slice, without length prefix @@ -224,14 +224,14 @@ fn test_siphash_2_4() { let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08; let mut buf = Vec::new(); let mut t = 0; - let mut state_inc = SipHasher24::new_with_keys(k0, k1); + let mut state_inc = SipHasher::new_with_keys(k0, k1); while t < 64 { let vec = u8to64_le!(vecs[t], 0); - let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf)); + let out = hash_with(SipHasher::new_with_keys(k0, k1), &Bytes(&buf)); assert_eq!(vec, out); - let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf)); + let full = hash_with(SipHasher::new_with_keys(k0, k1), &Bytes(&buf)); let i = state_inc.finish(); assert_eq!(full, i); @@ -322,13 +322,13 @@ fn test_hash_no_concat_alias() { #[test] fn test_write_short_works() { let test_usize = 0xd0c0b0a0usize; - let mut h1 = SipHasher24::new(); + let mut h1 = SipHasher::new(); h1.write_usize(test_usize); h1.write(b"bytes"); h1.write(b"string"); h1.write_u8(0xFFu8); h1.write_u8(0x01u8); - let mut h2 = SipHasher24::new(); + let mut h2 = SipHasher::new(); h2.write(unsafe { slice::from_raw_parts(&test_usize as *const _ as *const u8, mem::size_of::()) From e09dbbc39eeecbf6a8122d86297a1e8701aca26b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 17 Mar 2018 10:05:23 +0100 Subject: [PATCH 304/830] Add an example of lossy decoding to str::Utf8Error docs --- src/libcore/str/mod.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 9cf862bd9362..1185b7acaae1 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -165,6 +165,37 @@ Section: Creating a string /// /// [`String`]: ../../std/string/struct.String.html#method.from_utf8 /// [`&str`]: ../../std/str/fn.from_utf8.html +/// +/// # Examples +/// +/// This error type’s methods can be used to create functionality +/// similar to `String::from_utf8_lossy` without allocating heap memory: +/// +/// ``` +/// fn from_utf8_lossy(mut input: &[u8], mut push: F) where F: FnMut(&str) { +/// loop { +/// match ::std::str::from_utf8(input) { +/// Ok(valid) => { +/// push(valid); +/// break +/// } +/// Err(error) => { +/// let (valid, after_valid) = input.split_at(error.valid_up_to()); +/// unsafe { +/// push(::std::str::from_utf8_unchecked(valid)) +/// } +/// push("\u{FFFD}"); +/// +/// if let Some(invalid_sequence_length) = error.error_len() { +/// input = &after_valid[invalid_sequence_length..] +/// } else { +/// break +/// } +/// } +/// } +/// } +/// } +/// ``` #[derive(Copy, Eq, PartialEq, Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Utf8Error { From 89ecb0d5424f4eb72de70c0b7b0c3fb819273728 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 17 Mar 2018 11:07:50 +0100 Subject: [PATCH 305/830] Mark deprecated unstable SipHasher13 as a doc-hidden impl detail of HashMap. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It stays in libcore rather than being private in HashMap’s module because it shares code with the deprecated *stable* `SipHasher` type. --- src/libcore/hash/mod.rs | 3 ++- src/libcore/hash/sip.rs | 11 ++++++----- src/libcore/tests/lib.rs | 2 +- src/libstd/lib.rs | 3 +-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 90d9ab3644a8..ab714645675a 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -99,8 +99,9 @@ use mem; #[allow(deprecated)] pub use self::sip::SipHasher; -#[unstable(feature = "sip_hash_13", issue = "34767")] +#[unstable(feature = "hashmap_internals", issue = "0")] #[allow(deprecated)] +#[doc(hidden)] pub use self::sip::SipHasher13; mod sip; diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs index 7790118fbde1..e3bdecdc4b1f 100644 --- a/src/libcore/hash/sip.rs +++ b/src/libcore/hash/sip.rs @@ -23,10 +23,11 @@ use mem; /// (eg. `collections::HashMap` uses it by default). /// /// See: -#[unstable(feature = "sip_hash_13", issue = "34767")] +#[unstable(feature = "hashmap_internals", issue = "0")] #[rustc_deprecated(since = "1.13.0", reason = "use `std::collections::hash_map::DefaultHasher` instead")] #[derive(Debug, Clone, Default)] +#[doc(hidden)] pub struct SipHasher13 { hasher: Hasher, } @@ -34,7 +35,7 @@ pub struct SipHasher13 { /// An implementation of SipHash 2-4. /// /// See: -#[unstable(feature = "sip_hash_13", issue = "34767")] +#[unstable(feature = "hashmap_internals", issue = "0")] #[rustc_deprecated(since = "1.13.0", reason = "use `std::collections::hash_map::DefaultHasher` instead")] #[derive(Debug, Clone, Default)] @@ -165,7 +166,7 @@ impl SipHasher { impl SipHasher13 { /// Creates a new `SipHasher13` with the two initial keys set to 0. #[inline] - #[unstable(feature = "sip_hash_13", issue = "34767")] + #[unstable(feature = "hashmap_internals", issue = "0")] #[rustc_deprecated(since = "1.13.0", reason = "use `std::collections::hash_map::DefaultHasher` instead")] pub fn new() -> SipHasher13 { @@ -174,7 +175,7 @@ impl SipHasher13 { /// Creates a `SipHasher13` that is keyed off the provided keys. #[inline] - #[unstable(feature = "sip_hash_13", issue = "34767")] + #[unstable(feature = "hashmap_internals", issue = "0")] #[rustc_deprecated(since = "1.13.0", reason = "use `std::collections::hash_map::DefaultHasher` instead")] pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher13 { @@ -260,7 +261,7 @@ impl super::Hasher for SipHasher { } } -#[unstable(feature = "sip_hash_13", issue = "34767")] +#[unstable(feature = "hashmap_internals", issue = "0")] impl super::Hasher for SipHasher13 { #[inline] fn write(&mut self, msg: &[u8]) { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index e53964b5769b..1c876fa0bd7d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -21,6 +21,7 @@ #![feature(fixed_size_array)] #![feature(flt2dec)] #![feature(fmt_internals)] +#![feature(hashmap_internals)] #![feature(iterator_step_by)] #![feature(i128_type)] #![cfg_attr(stage0, feature(inclusive_range_syntax))] @@ -35,7 +36,6 @@ #![feature(range_is_empty)] #![feature(raw)] #![feature(refcell_replace_swap)] -#![feature(sip_hash_13)] #![feature(slice_patterns)] #![feature(sort_internals)] #![feature(specialization)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70a1f82c9a15..62bef4bc4991 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -267,7 +267,7 @@ #![feature(fn_traits)] #![feature(fnbox)] #![feature(generic_param_attrs)] -#![feature(hashmap_hasher)] +#![feature(hashmap_internals)] #![feature(heap_api)] #![feature(i128)] #![feature(i128_type)] @@ -298,7 +298,6 @@ #![feature(raw)] #![feature(rustc_attrs)] #![feature(stdsimd)] -#![feature(sip_hash_13)] #![feature(slice_bytes)] #![feature(slice_concat_ext)] #![feature(slice_internals)] From f53d4af223a5301daa6123c7b1e4cba108700db4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Feb 2018 10:40:02 +0100 Subject: [PATCH 306/830] Remove unused imports --- src/test/run-pass-fulldeps/issue-35829.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/run-pass-fulldeps/issue-35829.rs b/src/test/run-pass-fulldeps/issue-35829.rs index c42024332503..798c214bc471 100644 --- a/src/test/run-pass-fulldeps/issue-35829.rs +++ b/src/test/run-pass-fulldeps/issue-35829.rs @@ -20,8 +20,7 @@ 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::ast::{ExprKind, LitKind, RangeLimits}; use syntax::ptr::P; use rustc_data_structures::sync::Lrc; From 5bef034b198c58fd02a9e8a584a24fd516dc969c Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Sat, 17 Mar 2018 14:05:24 +0100 Subject: [PATCH 307/830] Bring back the phrase 'borrowing as' for what Borrow does. --- src/libcore/borrow.rs | 47 ++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index c0f1989f8794..0014bddb55cd 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -12,7 +12,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -/// A trait identifying how borrowed data behaves. +/// A trait for borrowing data. /// /// In Rust, it is common to provide different representations of a type for /// different use cases. For instance, storage location and management for a @@ -24,40 +24,37 @@ /// [`str`]. This requires keeping additional information unnecessary for a /// simple, immutable string. /// -/// These types signal that they are a specialized representation of a basic -/// type `T` by implementing `Borrow`. The method `borrow` provides a way -/// to convert a reference to the type into a reference to this basic type -/// `T`. +/// These types provide access to the underlying data through references +/// to the type of that data. They are said to be ‘borrowed as’ that type. +/// For instance, a [`Box`] can be borrowed as `T` while a [`String`] +/// can be borrowed as `str`. +/// +/// Types express that they can be borrowed as some type `T` by implementing +/// `Borrow`, providing a reference to a `T` in the trait’s +/// [`borrow`] method. A type is free to borrow as several different types. +/// If it wishes to mutably borrow as the type – allowing the underlying data +/// to be modified, it can additionally implement [`BorrowMut`]. /// /// Further, when providing implementations for additional traits, it needs /// to be considered whether they should behave identical to those of the /// underlying type as a consequence of acting as a representation of that -/// underlying type. -/// -/// Generic code typically uses `Borrow` when it not only needs access -/// to a reference of the underlying type but relies on the identical -/// behavior of these additional trait implementations. These traits are -/// likely to appear as additional trait bounds. +/// underlying type. Generic code typically uses `Borrow` when it relies +/// on the identical behavior of these additional trait implementations. +/// These traits will likely appear as additional trait bounds. /// /// If generic code merely needs to work for all types that can /// provide a reference to related type `T`, it is often better to use /// [`AsRef`] as more types can safely implement it. /// -/// If a type implementing `Borrow` also wishes to allow mutable access -/// to the underlying type `T`, it can do so by implementing the companion -/// trait [`BorrowMut`]. -/// -/// Note also that it is perfectly fine for a single type to have multiple -/// implementations of `Borrow` for different `T`s. In fact, a blanket -/// implementation lets every type be at least a borrow of itself. -/// /// [`AsRef`]: ../../std/convert/trait.AsRef.html -/// [`BorrowMut`]: trait.BorrowMut.html +/// [`BorrowMut`]: trait.BorrowMut.html /// [`Box`]: ../../std/boxed/struct.Box.html /// [`Mutex`]: ../../std/sync/struct.Mutex.html /// [`Rc`]: ../../std/rc/struct.Rc.html /// [`str`]: ../../std/primitive.str.html /// [`String`]: ../../std/string/struct.String.html +/// [`borrow`]: #tymethod.borrow +/// /// /// # Examples /// @@ -113,10 +110,10 @@ /// `str` is available. /// /// Instead, the `get` method is generic over the type of the underlying key -/// data, called `Q` in the method signature above. It states that `K` is a -/// representation of `Q` by requiring that `K: Borrow`. By additionally -/// requiring `Q: Hash + Eq`, it demands that `K` and `Q` have -/// implementations of the `Hash` and `Eq` traits that produce identical +/// data, called `Q` in the method signature above. It states that `K` +/// borrows as a `Q` by requiring that `K: Borrow`. By additionally +/// requiring `Q: Hash + Eq`, it signals the requirement that `K` and `Q` +/// have implementations of the `Hash` and `Eq` traits that produce identical /// results. /// /// The implementation of `get` relies in particular on identical @@ -141,7 +138,7 @@ /// ``` /// /// Because two equal values need to produce the same hash value, the -/// implementation of `Hash` needs to reflect that, too: +/// implementation of `Hash` needs to ignore ASCII case, too: /// /// ``` /// # use std::hash::{Hash, Hasher}; From d664b8954e83e74870a90b871161942d6e827aa6 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Sat, 17 Mar 2018 14:09:45 +0100 Subject: [PATCH 308/830] Rewrite the documentation for BorrowMut. --- src/libcore/borrow.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 0014bddb55cd..7470512e2b2d 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -191,7 +191,11 @@ pub trait Borrow { /// A trait for mutably borrowing data. /// -/// Similar to `Borrow`, but for mutable borrows. +/// As a companion to [`Borrow`] this trait allows a type to borrow as +/// an underlying type by providing a mutable reference. See [`Borrow`] +/// for more information on borrowing as another type. +/// +/// [`Borrow`]: trait.Borrow.html #[stable(feature = "rust1", since = "1.0.0")] pub trait BorrowMut : Borrow { /// Mutably borrows from an owned value. From 9f5a356c1d01e971b1fe33f7afb2b81d0eec2b1c Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sat, 17 Mar 2018 13:46:45 +0800 Subject: [PATCH 309/830] improve attribute trailing semicolon error --- src/libsyntax/parse/attr.rs | 11 +---------- src/test/ui/issue-49040.rs | 12 ++++++++++++ src/test/ui/issue-49040.stderr | 8 ++++++++ 3 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/issue-49040.rs create mode 100644 src/test/ui/issue-49040.stderr diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 053746b579dc..4c3f42d9c6b7 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -90,7 +90,7 @@ impl<'a> Parser<'a> { debug!("parse_attribute_with_inner_parse_policy: inner_parse_policy={:?} self.token={:?}", inner_parse_policy, self.token); - let (span, path, tokens, mut style) = match self.token { + let (span, path, tokens, style) = match self.token { token::Pound => { let lo = self.span; self.bump(); @@ -129,15 +129,6 @@ impl<'a> Parser<'a> { } }; - if inner_parse_policy == InnerAttributeParsePolicy::Permitted && - self.token == token::Semi { - self.bump(); - self.span_warn(span, - "this inner attribute syntax is deprecated. The new syntax is \ - `#![foo]`, with a bang and no semicolon"); - style = ast::AttrStyle::Inner; - } - Ok(ast::Attribute { id: attr::mk_attr_id(), style, diff --git a/src/test/ui/issue-49040.rs b/src/test/ui/issue-49040.rs new file mode 100644 index 000000000000..866ecd9e1d95 --- /dev/null +++ b/src/test/ui/issue-49040.rs @@ -0,0 +1,12 @@ +// Copyright 2015 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. + +#![allow(unused_variables)]; //~ ERROR expected item, found `;` +fn main() {} diff --git a/src/test/ui/issue-49040.stderr b/src/test/ui/issue-49040.stderr new file mode 100644 index 000000000000..b6f624dac7db --- /dev/null +++ b/src/test/ui/issue-49040.stderr @@ -0,0 +1,8 @@ +error: expected item, found `;` + --> $DIR/issue-49040.rs:11:28 + | +LL | #![allow(unused_variables)]; //~ ERROR expected item, found `;` + | ^ help: consider removing this semicolon + +error: aborting due to previous error + From b430cba343743783cee517bf93c7f255827cccc5 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 16 Mar 2018 16:35:27 +0000 Subject: [PATCH 310/830] Fix use of unstable feature in test --- src/liballoc/lib.rs | 1 + src/liballoc/slice.rs | 4 ++-- src/liballoc/tests/lib.rs | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index b93e128d5081..253b8acc16c4 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -113,6 +113,7 @@ #![feature(slice_get_slice)] #![feature(slice_patterns)] #![feature(slice_rsplit)] +#![feature(slice_sort_by_cached_key)] #![feature(specialization)] #![feature(staged_api)] #![feature(str_internals)] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 306c467f048c..db8900664476 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1368,7 +1368,7 @@ impl [T] { /// v.sort_by_cached_key(|k| k.abs()); /// assert!(v == [1, 2, -3, 4, -5]); /// ``` - #[unstable(feature = "slice_sort_by_uncached_key", issue = "34447")] + #[unstable(feature = "slice_sort_by_cached_key", issue = "34447")] #[inline] pub fn sort_by_cached_key(&mut self, f: F) where F: FnMut(&T) -> K, K: Ord @@ -1487,7 +1487,7 @@ impl [T] { /// deterministic behavior. /// /// Due to its key calling strategy, [`sort_unstable_by_key`](#method.sort_unstable_by_key) - /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_uncached_key) in + /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_cached_key) in /// cases where the key function is expensive. /// /// # Examples diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 285cba0270c0..27f3028a5134 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -23,6 +23,7 @@ #![feature(pattern)] #![feature(placement_in_syntax)] #![feature(rand)] +#![feature(slice_sort_by_cached_key)] #![feature(splice)] #![feature(str_escape)] #![feature(string_retain)] From 6fd4d67819a6eb8273768b6c3789ca70582cd703 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 16 Mar 2018 08:35:03 -0700 Subject: [PATCH 311/830] rustbuild: Tweak where timing information goes This commit tweaks where timing and step information is printed out as part of the build, ensuring that we do it as close to the location where work happens as possible. In rustbuild various functions may perform long blocking work as dependencies are assembled, so if we print out timing information early on we may accidentally time more than just the step we were intending to time! --- src/bootstrap/check.rs | 20 +++++++++------ src/bootstrap/compile.rs | 27 ++++++++++---------- src/bootstrap/test.rs | 55 ++++++++++++++++++++-------------------- src/bootstrap/tool.rs | 12 ++++----- 4 files changed, 60 insertions(+), 54 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 33bcfaa80ca3..a9dccea827b6 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -40,17 +40,18 @@ impl Step for Std { let target = self.target; let compiler = builder.compiler(0, build.build); - let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); - println!("Checking std artifacts ({} -> {})", &compiler.host, target); - let out_dir = build.stage_out(compiler, Mode::Libstd); build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "check"); std_cargo(builder, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); + println!("Checking std artifacts ({} -> {})", &compiler.host, target); run_cargo(build, &mut cargo, &libstd_stamp(build, compiler, target), true); + let libdir = builder.sysroot_libdir(compiler, target); add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target)); } @@ -86,19 +87,20 @@ impl Step for Rustc { let compiler = builder.compiler(0, build.build); let target = self.target; - let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); - println!("Checking compiler artifacts ({} -> {})", &compiler.host, target); - let stage_out = builder.stage_out(compiler, Mode::Librustc); build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target)); build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check"); rustc_cargo(build, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); + println!("Checking compiler artifacts ({} -> {})", &compiler.host, target); run_cargo(build, &mut cargo, &librustc_stamp(build, compiler, target), true); + let libdir = builder.sysroot_libdir(compiler, target); add_to_sysroot(&libdir, &librustc_stamp(build, compiler, target)); } @@ -128,16 +130,18 @@ impl Step for Test { let target = self.target; let compiler = builder.compiler(0, build.build); - let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); - println!("Checking test artifacts ({} -> {})", &compiler.host, target); let out_dir = build.stage_out(compiler, Mode::Libtest); build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "check"); test_cargo(build, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); + println!("Checking test artifacts ({} -> {})", &compiler.host, target); run_cargo(build, &mut cargo, &libtest_stamp(build, compiler, target), true); + let libdir = builder.sysroot_libdir(compiler, target); add_to_sysroot(&libdir, &libtest_stamp(build, compiler, target)); } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 86263c8fa073..d697403180c1 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -93,10 +93,6 @@ impl Step for Std { return; } - let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); - println!("Building stage{} std artifacts ({} -> {})", compiler.stage, - &compiler.host, target); - if target.contains("musl") { let libdir = builder.sysroot_libdir(compiler, target); copy_musl_third_party_objects(build, target, &libdir); @@ -106,6 +102,10 @@ impl Step for Std { build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build"); std_cargo(builder, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage)); + println!("Building stage{} std artifacts ({} -> {})", compiler.stage, + &compiler.host, target); run_cargo(build, &mut cargo, &libstd_stamp(build, compiler, target), @@ -360,13 +360,14 @@ impl Step for Test { return; } - let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); - println!("Building stage{} test artifacts ({} -> {})", compiler.stage, - &compiler.host, target); let out_dir = build.stage_out(compiler, Mode::Libtest); build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build"); test_cargo(build, &compiler, target, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage)); + println!("Building stage{} test artifacts ({} -> {})", compiler.stage, + &compiler.host, target); run_cargo(build, &mut cargo, &libtest_stamp(build, compiler, target), @@ -482,16 +483,16 @@ impl Step for Rustc { target: build.build, }); - let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); - println!("Building stage{} compiler artifacts ({} -> {})", - compiler.stage, &compiler.host, target); - let stage_out = builder.stage_out(compiler, Mode::Librustc); build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target)); build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build"); rustc_cargo(build, &mut cargo); + + let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage)); + println!("Building stage{} compiler artifacts ({} -> {})", + compiler.stage, &compiler.host, target); run_cargo(build, &mut cargo, &librustc_stamp(build, compiler, target), @@ -634,8 +635,6 @@ impl Step for CodegenBackend { .arg(build.src.join("src/librustc_trans/Cargo.toml")); rustc_cargo_env(build, &mut cargo); - let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); - match &*self.backend { "llvm" | "emscripten" => { // Build LLVM for our target. This will implicitly build the @@ -685,6 +684,8 @@ impl Step for CodegenBackend { let tmp_stamp = build.cargo_out(compiler, Mode::Librustc, target) .join(".tmp.stamp"); + + let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); let files = run_cargo(build, cargo.arg("--features").arg(features), &tmp_stamp, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index de938ec8e830..e129ae8c5210 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -530,8 +530,6 @@ impl Step for Tidy { fn run(self, builder: &Builder) { let build = builder.build; - let _folder = build.fold_output(|| "tidy"); - println!("tidy check"); let mut cmd = builder.tool_cmd(Tool::Tidy); cmd.arg(build.src.join("src")); cmd.arg(&build.initial_cargo); @@ -541,6 +539,9 @@ impl Step for Tidy { if build.config.quiet_tests { cmd.arg("--quiet"); } + + let _folder = build.fold_output(|| "tidy"); + println!("tidy check"); try_run(build, &mut cmd); } @@ -836,9 +837,6 @@ impl Step for Compiletest { builder.ensure(native::TestHelpers { target }); builder.ensure(RemoteCopyLibs { compiler, target }); - let _folder = build.fold_output(|| format!("test_{}", suite)); - println!("Check compiletest suite={} mode={} ({} -> {})", - suite, mode, &compiler.host, target); let mut cmd = builder.tool_cmd(Tool::Compiletest); // compiletest currently has... a lot of arguments, so let's just pass all @@ -998,6 +996,9 @@ impl Step for Compiletest { build.ci_env.force_coloring_in_ci(&mut cmd); + let _folder = build.fold_output(|| format!("test_{}", suite)); + println!("Check compiletest suite={} mode={} ({} -> {})", + suite, mode, &compiler.host, target); let _time = util::timeit(); try_run(build, &mut cmd); } @@ -1142,20 +1143,21 @@ impl Step for ErrorIndex { builder.ensure(compile::Std { compiler, target: compiler.host }); - let _folder = build.fold_output(|| "test_error_index"); - println!("Testing error-index stage{}", compiler.stage); - let dir = testdir(build, compiler.host); t!(fs::create_dir_all(&dir)); let output = dir.join("error-index.md"); - let _time = util::timeit(); - build.run(builder.tool_cmd(Tool::ErrorIndex) - .arg("markdown") - .arg(&output) - .env("CFG_BUILD", &build.build) - .env("RUSTC_ERROR_METADATA_DST", build.extended_error_dir())); + let mut tool = builder.tool_cmd(Tool::ErrorIndex); + tool.arg("markdown") + .arg(&output) + .env("CFG_BUILD", &build.build) + .env("RUSTC_ERROR_METADATA_DST", build.extended_error_dir()); + + let _folder = build.fold_output(|| "test_error_index"); + println!("Testing error-index stage{}", compiler.stage); + let _time = util::timeit(); + build.run(&mut tool); markdown_test(builder, compiler, &output); } } @@ -1400,11 +1402,6 @@ impl Step for Crate { } _ => panic!("can only test libraries"), }; - let _folder = build.fold_output(|| { - format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate) - }); - println!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage, - &compiler.host, target); // Build up the base `cargo test` command. // @@ -1436,8 +1433,6 @@ impl Step for Crate { cargo.arg("--quiet"); } - let _time = util::timeit(); - if target.contains("emscripten") { cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)), build.config.nodejs.as_ref().expect("nodejs not configured")); @@ -1465,6 +1460,13 @@ impl Step for Crate { format!("{} run", builder.tool_exe(Tool::RemoteTestClient).display())); } + + let _folder = build.fold_output(|| { + format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate) + }); + println!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage, + &compiler.host, target); + let _time = util::timeit(); try_run(build, &mut cargo); } } @@ -1513,12 +1515,6 @@ impl Step for CrateRustdoc { target, test_kind.subcommand(), "src/tools/rustdoc"); - let _folder = build.fold_output(|| { - format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage) - }); - println!("{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage, - &compiler.host, target); - if test_kind.subcommand() == "test" && !build.fail_fast { cargo.arg("--no-fail-fast"); } @@ -1532,6 +1528,11 @@ impl Step for CrateRustdoc { cargo.arg("--quiet"); } + let _folder = build.fold_output(|| { + format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage) + }); + println!("{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage, + &compiler.host, target); let _time = util::timeit(); try_run(build, &mut cargo); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 5f5b10a07b86..d308cecb2752 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -112,11 +112,11 @@ impl Step for ToolBuild { Mode::Tool => panic!("unexpected Mode::Tool for tool build") } - let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); - println!("Building stage{} tool {} ({})", compiler.stage, tool, target); - let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path); cargo.arg("--features").arg(self.extra_features.join(" ")); + + let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); + println!("Building stage{} tool {} ({})", compiler.stage, tool, target); let is_expected = build.try_run(&mut cargo); build.save_toolstate(tool, if is_expected { ToolState::TestFail @@ -339,9 +339,6 @@ impl Step for Rustdoc { builder.ensure(compile::Rustc { compiler: build_compiler, target }); - let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage)); - println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host); - let mut cargo = prepare_tool_cargo(builder, build_compiler, target, @@ -352,7 +349,10 @@ impl Step for Rustdoc { cargo.env("RUSTC_DEBUGINFO", builder.config.rust_debuginfo.to_string()) .env("RUSTC_DEBUGINFO_LINES", builder.config.rust_debuginfo_lines.to_string()); + let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage)); + println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host); build.run(&mut cargo); + // Cargo adds a number of paths to the dylib search path on windows, which results in // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" // rustdoc a different name. From 7278e37d38226734dabf07b4453580868847edf6 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 9 Dec 2017 22:16:54 +0200 Subject: [PATCH 312/830] update FIXME(#6393) to point to issue 43234 (tracking issue for non-lexical lifetimes) --- src/libcore/iter/mod.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index b1b783b47c72..1e8476d3880c 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -1872,7 +1872,7 @@ impl Iterator for Peekable { #[inline] fn nth(&mut self, n: usize) -> Option { - // FIXME(#6393): merge these when borrow-checking gets better. + // FIXME(#43234): merge these when borrow-checking gets better. if n == 0 { match self.peeked.take() { Some(v) => v, diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index e95126c8a1a0..19f33ef5d45a 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -177,7 +177,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> }); } DropStyle::Conditional => { - let unwind = self.unwind; // FIXME(#6393) + let unwind = self.unwind; // FIXME(#43234) let succ = self.succ; let drop_bb = self.complete_drop(Some(DropFlagMode::Deep), succ, unwind); self.elaborator.patch().patch_terminator(bb, TerminatorKind::Goto { @@ -268,7 +268,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> // Clear the "master" drop flag at the end. This is needed // because the "master" drop protects the ADT's discriminant, // which is invalidated after the ADT is dropped. - let (succ, unwind) = (self.succ, self.unwind); // FIXME(#6393) + let (succ, unwind) = (self.succ, self.unwind); // FIXME(#43234) ( self.drop_flag_reset_block(DropFlagMode::Shallow, succ, unwind), unwind.map(|unwind| { @@ -344,7 +344,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let interior = self.place.clone().deref(); let interior_path = self.elaborator.deref_subpath(self.path); - let succ = self.succ; // FIXME(#6393) + let succ = self.succ; // FIXME(#43234) let unwind = self.unwind; let succ = self.box_free_block(ty, succ, unwind); let unwind_succ = self.unwind.map(|unwind| { @@ -717,7 +717,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> ptr_based) }); - let succ = self.succ; // FIXME(#6393) + let succ = self.succ; // FIXME(#43234) let loop_block = self.drop_loop( succ, cur, @@ -798,7 +798,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> self.open_drop_for_adt(def, substs) } ty::TyDynamic(..) => { - let unwind = self.unwind; // FIXME(#6393) + let unwind = self.unwind; // FIXME(#43234) let succ = self.succ; self.complete_drop(Some(DropFlagMode::Deep), succ, unwind) } @@ -849,7 +849,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> fn elaborated_drop_block<'a>(&mut self) -> BasicBlock { debug!("elaborated_drop_block({:?})", self); - let unwind = self.unwind; // FIXME(#6393) + let unwind = self.unwind; // FIXME(#43234) let succ = self.succ; let blk = self.drop_block(succ, unwind); self.elaborate_drop(blk); @@ -882,7 +882,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> args: vec![Operand::Move(self.place.clone())], destination: Some((unit_temp, target)), cleanup: None - }; // FIXME(#6393) + }; // FIXME(#43234) let free_block = self.new_block(unwind, call); let block_start = Location { block: free_block, statement_index: 0 }; From ba836f4b5fedf09418a6dbe9fb1f59b0ef7bd587 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 00:44:58 +0200 Subject: [PATCH 313/830] update FIXME(#15760) to point to issue 27336 (tracking issue for Default Type Parameter Fallback) --- src/librustc_typeck/check/mod.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dc9455487ede..f0f1064752d4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2869,7 +2869,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let origin = self.misc(call_span); let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret); - // FIXME(#15760) can't use try! here, FromError doesn't default + // FIXME(#27336) can't use ? here, Try::from_error doesn't default // to identity so the resulting type is not constrained. match ures { Ok(ok) => { @@ -2877,19 +2877,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // we can. We don't care if some things turn // out unconstrained or ambiguous, as we're // just trying to get hints here. - let result = self.save_and_restore_in_snapshot_flag(|_| { + self.save_and_restore_in_snapshot_flag(|_| { let mut fulfill = FulfillmentContext::new(); let ok = ok; // FIXME(#30046) for obligation in ok.obligations { fulfill.register_predicate_obligation(self, obligation); } fulfill.select_where_possible(self) - }); - - match result { - Ok(()) => { } - Err(_) => return Err(()), - } + }).map_err(|_| ())?; } Err(_) => return Err(()), } From d1dacddfc7e1b0d897b8d6a4153c2fb8758eaee1 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 02:08:09 +0200 Subject: [PATCH 314/830] update FIXME(#7622) to point to issue 44580 (tracking issue for const generics) --- src/test/run-pass/issue-28561.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/issue-28561.rs b/src/test/run-pass/issue-28561.rs index 8c73830f4d77..e21e487fedd1 100644 --- a/src/test/run-pass/issue-28561.rs +++ b/src/test/run-pass/issue-28561.rs @@ -45,7 +45,7 @@ struct Array { f32: [T; 32], } -// FIXME(#7622): merge with `Array` once `[T; N]: Clone` where `T: Clone` +// FIXME(#44580): merge with `Array` once `[T; N]: Clone` where `T: Clone` #[derive(Clone, Copy)] struct CopyArray { f00: [T; 00], From e1b9bf07022d18fb44aeb3dd3870952f1bc17619 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 11:04:33 +0200 Subject: [PATCH 315/830] update FIXME(#23442) to point to issue 45742 (Blanket impl of AsRef for Deref) --- src/libcore/convert.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index d3a83dc795c8..2206910c93f6 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -382,7 +382,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsRef for &'a mut T where T: AsRef } } -// FIXME (#23442): replace the above impls for &/&mut with the following more general one: +// FIXME (#45742): replace the above impls for &/&mut with the following more general one: // // As lifts over Deref // impl AsRef for D where D::Target: AsRef { // fn as_ref(&self) -> &U { @@ -399,7 +399,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsMut for &'a mut T where T: AsMut } } -// FIXME (#23442): replace the above impl for &mut with the following more general one: +// FIXME (#45742): replace the above impl for &mut with the following more general one: // // AsMut lifts over DerefMut // impl AsMut for D where D::Target: AsMut { // fn as_mut(&mut self) -> &mut U { From 3753e1a55a2ed118121779e05f77164da3269a86 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 01:09:36 +0200 Subject: [PATCH 316/830] update FIXME(#5244) to point to RFC 1109 (Non-Copy array creation ergonomics) --- src/liballoc/tests/slice.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index d9e9d91cea88..3f679d81f08d 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1351,7 +1351,7 @@ fn test_copy_from_slice_dst_shorter() { const MAX_LEN: usize = 80; static DROP_COUNTS: [AtomicUsize; MAX_LEN] = [ - // FIXME #5244: AtomicUsize is not Copy. + // FIXME(RFC 1109): AtomicUsize is not Copy. AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), AtomicUsize::new(0), From 4a06708d30cc744583a3bce5508347977de6ac8c Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 9 Dec 2017 21:46:25 +0200 Subject: [PATCH 317/830] remove FIXME(#39119) and allow running test on emscripten --- src/libstd/num.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/num.rs b/src/libstd/num.rs index a2c133954a32..33d705385224 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -169,7 +169,6 @@ mod tests { macro_rules! test_checked_next_power_of_two { ($test_name:ident, $T:ident) => ( - #[cfg_attr(target_os = "emscripten", ignore)] // FIXME(#39119) fn $test_name() { #![test] assert_eq!((0 as $T).checked_next_power_of_two(), Some(1)); From 622c44510fcc65ad4038beb1714cf8950f96a2a0 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sun, 10 Dec 2017 00:10:43 +0200 Subject: [PATCH 318/830] remove FIXME(#37712) and implement ItemLikeVisitor instead of Visitor --- src/librustc_trans_utils/symbol_names_test.rs | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/librustc_trans_utils/symbol_names_test.rs b/src/librustc_trans_utils/symbol_names_test.rs index 267c8d2bd03c..47bbd67fb5c7 100644 --- a/src/librustc_trans_utils/symbol_names_test.rs +++ b/src/librustc_trans_utils/symbol_names_test.rs @@ -15,7 +15,6 @@ //! paths etc in all kinds of annoying scenarios. use rustc::hir; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::ty::TyCtxt; use syntax::ast; @@ -34,8 +33,7 @@ pub fn report_symbol_names<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.dep_graph.with_ignore(|| { let mut visitor = SymbolNamesTest { tcx: tcx }; - // FIXME(#37712) could use ItemLikeVisitor if trait items were item-like - tcx.hir.krate().visit_all_item_likes(&mut visitor.as_deep_visitor()); + tcx.hir.krate().visit_all_item_likes(&mut visitor); }) } @@ -66,23 +64,16 @@ impl<'a, 'tcx> SymbolNamesTest<'a, 'tcx> { } } -impl<'a, 'tcx> Visitor<'tcx> for SymbolNamesTest<'a, 'tcx> { - fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::None - } - +impl<'a, 'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for SymbolNamesTest<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { self.process_attrs(item.id); - intravisit::walk_item(self, item); } - fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem) { - self.process_attrs(ti.id); - intravisit::walk_trait_item(self, ti) + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { + self.process_attrs(trait_item.id); } - fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem) { - self.process_attrs(ii.id); - intravisit::walk_impl_item(self, ii) + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { + self.process_attrs(impl_item.id); } } From 69d12a2b97f4f09dba2e09542c74da48ea88ba08 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 01:00:40 +0200 Subject: [PATCH 319/830] remove FIXME(#30046) and infer moves on pattern matching --- src/librustc_mir/build/block.rs | 5 ++--- src/librustc_typeck/check/mod.rs | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index ef30b1e45223..7281fb596638 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -117,10 +117,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // Evaluate the initializer, if present. if let Some(init) = initializer { unpack!(block = this.in_opt_scope( - opt_destruction_scope.map(|de|(de, source_info)), block, move |this| { + opt_destruction_scope.map(|de|(de, source_info)), block, |this| { let scope = (init_scope, source_info); - this.in_scope(scope, lint_level, block, move |this| { - // FIXME #30046 ^~~~ + this.in_scope(scope, lint_level, block, |this| { this.expr_into_pattern(block, pattern, init) }) })); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f0f1064752d4..c99e49256faa 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2879,7 +2879,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // just trying to get hints here. self.save_and_restore_in_snapshot_flag(|_| { let mut fulfill = FulfillmentContext::new(); - let ok = ok; // FIXME(#30046) for obligation in ok.obligations { fulfill.register_predicate_obligation(self, obligation); } From fd007559dbb9b149244cfb1184002971ea04a6cd Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 03:26:35 +0200 Subject: [PATCH 320/830] remove FIXME(#11094) and allow make tests to run on targets besides host --- src/tools/compiletest/src/runtest.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 953a13a3f582..ee348cddb3cf 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2358,11 +2358,6 @@ impl<'test> TestCx<'test> { } fn run_rmake_test(&self) { - // FIXME(#11094): we should fix these tests - if self.config.host != self.config.target { - return; - } - let cwd = env::current_dir().unwrap(); let src_root = self.config .src_base From 2c6b7b93230d4dcc99608538b43530e9e520215b Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 17:28:44 +0200 Subject: [PATCH 321/830] remove FIXME(#2543) and avoid bad copies --- src/libsyntax/test.rs | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 39306229c82b..69213f236e1d 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -627,8 +627,15 @@ fn path_node(ids: Vec) -> ast::Path { } fn path_name_i(idents: &[Ident]) -> String { - // FIXME: Bad copies (#2543 -- same for everything else that says "bad") - idents.iter().map(|i| i.to_string()).collect::>().join("::") + let mut path_name = "".to_string(); + let mut idents_iter = idents.iter().peekable(); + while let Some(ident) = idents_iter.next() { + path_name.push_str(&ident.name.as_str()); + if let Some(_) = idents_iter.peek() { + path_name.push_str("::") + } + } + path_name } fn mk_tests(cx: &TestCtxt) -> P { @@ -681,7 +688,6 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { // gensym information. let span = ignored_span(cx, test.span); - let path = test.path.clone(); let ecx = &cx.ext_cx; let self_id = ecx.ident_of("self"); let test_id = ecx.ident_of("test"); @@ -693,10 +699,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { // creates $name: $expr let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr); - debug!("encoding {}", path_name_i(&path[..])); - // path to the #[test] function: "foo::bar::baz" - let path_string = path_name_i(&path[..]); + let path_string = path_name_i(&test.path[..]); + + debug!("encoding {}", path_string); + let name_expr = ecx.expr_str(span, Symbol::intern(&path_string)); // self::test::StaticTestName($name_expr) @@ -743,7 +750,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { diag.bug("expected to find top-level re-export name, but found None"); } }; - visible_path.extend(path); + visible_path.extend_from_slice(&test.path[..]); // Rather than directly give the test function to the test // harness, we create a wrapper like one of the following: From 0d8fa82eab070481d7ac82da4735dd651dfa9a00 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 01:28:55 +0200 Subject: [PATCH 322/830] remove FIXME(#48116) and remove the logic to debug the issue --- src/librustc_resolve/resolve_imports.rs | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 01c1ded94578..a73f660c4059 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1026,28 +1026,9 @@ fn import_path_to_string(names: &[SpannedIdent], if names.is_empty() { import_directive_subclass_to_string(subclass) } else { - // FIXME: Remove this entire logic after #48116 is fixed. - // - // Note that this code looks a little wonky, it's currently here to - // hopefully help debug #48116, but otherwise isn't intended to - // cause any problems. - let x = format!( - "{}::{}", - names_to_string(names), - import_directive_subclass_to_string(subclass), - ); - if names.is_empty() || x.starts_with("::") { - span_bug!( - span, - "invalid name `{}` at {:?}; global = {}, names = {:?}, subclass = {:?}", - x, - span, - global, - names, - subclass - ); - } - return x + format!("{}::{}", + names_to_string(names), + import_directive_subclass_to_string(subclass)) } } } From be73a1f963e7830de2dbfbea6b362673ab7e6ded Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 02:19:01 +0200 Subject: [PATCH 323/830] remove FIXME(#33435) and remove the spurious failures counter measure --- src/tools/compiletest/src/main.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index e65c03a6e571..cf87062f6bee 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -452,11 +452,6 @@ pub fn run_tests(config: &Config) { _ => { /* proceed */ } } - // FIXME(#33435) Avoid spurious failures in codegen-units/partitioning tests. - if let Mode::CodegenUnits = config.mode { - let _ = fs::remove_dir_all("tmp/partitioning-tests"); - } - let opts = test_opts(config); let tests = make_tests(config); // sadly osx needs some file descriptor limits raised for running tests in From c8be5c3174f3cf2856a19db23cba1b7313068690 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 14:49:40 +0200 Subject: [PATCH 324/830] remove FIXME(#8372) since for-loops wont support borrowing iterators --- src/libsyntax/parse/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ff097c362fe6..fdb3b91fbbf0 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -298,7 +298,6 @@ pub fn str_lit(lit: &str, diag: Option<(Span, &Handler)>) -> String { debug!("parse_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 error = |i| format!("lexer should have rejected {} at {}", lit, i); /// Eat everything up to a non-whitespace @@ -503,7 +502,6 @@ pub fn byte_lit(lit: &str) -> (u8, usize) { pub fn byte_str_lit(lit: &str) -> Lrc> { let mut res = Vec::with_capacity(lit.len()); - // FIXME #8372: This could be a for-loop if it didn't borrow the iterator let error = |i| format!("lexer should have rejected {} at {}", lit, i); /// Eat everything up to a non-whitespace From d5b55c1159c57cee0118df23626cb786e19ca1e5 Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Sat, 17 Mar 2018 18:24:11 +0200 Subject: [PATCH 325/830] remove FIXME(#27889) since the issue is already fixed --- src/test/run-pass/issue-27889.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/run-pass/issue-27889.rs b/src/test/run-pass/issue-27889.rs index 3f7d0400c884..29a5f6dd24bd 100644 --- a/src/test/run-pass/issue-27889.rs +++ b/src/test/run-pass/issue-27889.rs @@ -10,7 +10,6 @@ // Test that a field can have the same name in different variants // of an enum -// FIXME #27889 pub enum Foo { X { foo: u32 }, From fab7020bd95c695be4f3c06dce236fada0dabb8e Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Fri, 9 Feb 2018 19:04:12 +0100 Subject: [PATCH 326/830] Add span_suggestion while removing TyRefs based on the snippet String. --- src/librustc/traits/error_reporting.rs | 87 ++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7e5dc02798df..c90a6d0709db 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -575,6 +575,44 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { = self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); + // { + // let ty::Binder(trait_ref) = trait_ref; + // println!("TraitRef: {:?}", trait_ref); + // println!("TraitRef: id:{:?}; subst:{:?}", trait_ref.def_id, trait_ref.substs); + + // if let ty::Predicate::Trait(trait_predicate_binder) = + // trait_ref.to_predicate() { + // let trait_predicate = trait_predicate_binder.skip_binder(); + // println!("TraitPredicateBinder: {:?}", trait_predicate_binder); + // println!("TraitPredicate: {:?}", trait_predicate); + + // let trait_ty = trait_ref.self_ty(); + // println!("TraitPredicateTy: {:?}", trait_ty); + // println!("TraitPredicateTy: sty:{:?}; flags{:?}", trait_ty.sty, trait_ty.flags); + // } + + // for in_ty in trait_ref.input_types() { + // println!("\t- {:?}", in_ty); + // println!("\t\t- sty:{:?}; flags:{:?}", in_ty.sty, in_ty.flags); + // } + + // println!("Message: {:?}", message); + // println!("Label: {:?}", label); + // println!("Obligation: {:?}", obligation); + // println!("Span: {:?}", self.tcx.sess.codemap().span_to_string(span)); + + // let body_id = obligation.cause.body_id; + // println!("BodyId: {:?}", body_id); + // println!("BodyIdSpan: {:?}", self.tcx.hir.span(body_id)); + + // match self.tcx.hir.find(body_id) { + // Some(node) => println!("Node: {:?}", node), + // None => println!("Node not found."), + // } + + // println!("=------------------------------="); + // } + let mut err = struct_span_err!( self.tcx.sess, span, @@ -606,6 +644,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); + self.suggest_remove_reference(&obligation, &mut err, &trait_ref); // Try to report a help message if !trait_ref.has_infer_types() && @@ -844,6 +883,54 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + fn suggest_remove_reference(&self, + obligation: &PredicateObligation<'tcx>, + err: &mut DiagnosticBuilder<'tcx>, + trait_ref: &ty::Binder>) { + let ty::Binder(trait_ref) = trait_ref; + + let span = obligation.cause.span; + let mut snippet = match self.tcx.sess.codemap().span_to_snippet(span) { + Ok(s) => s, + Err(_) => String::from(""), + }; + + let mut refs_number = 0; + + for c in snippet.chars() { + if c == '&' { + refs_number += 1; + } + } + + let mut refs_remaining = refs_number; + let mut trait_type = trait_ref.self_ty(); + let mut selcx = SelectionContext::new(self); + + while refs_remaining > 0 { + if let ty::TypeVariants::TyRef(_, ty::TypeAndMut{ ty: t_type, mutbl: _ }) = + trait_type.sty { + trait_type = t_type; + refs_remaining -= 1; + + let substs = self.tcx.mk_substs_trait(trait_type, &[]); + let new_trait_ref = ty::TraitRef::new(trait_ref.def_id, substs); + let new_obligation = Obligation::new(ObligationCause::dummy(), + obligation.param_env, + new_trait_ref.to_predicate()); + + if selcx.evaluate_obligation(&new_obligation) { + for i in 0..refs_number { + snippet.remove(i); + } + err.span_suggestion(span, "consider removing `&`s like", format!("{}", snippet)); + } + } else { + break; + } + } + } + /// Given some node representing a fn-like thing in the HIR map, /// returns a span and `ArgKind` information that describes the /// arguments it expects. This can be supplied to From 5d06c890fececc6f6779cd65ca83cef4647b8fdd Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 8 Mar 2018 14:27:23 +0300 Subject: [PATCH 327/830] syntax: Make `_` an identifier --- src/libproc_macro/lib.rs | 2 - src/librustc/hir/mod.rs | 2 +- src/librustc/ich/impls_syntax.rs | 1 - src/librustc_passes/ast_validation.rs | 6 +- src/librustdoc/html/highlight.rs | 2 +- src/libsyntax/diagnostics/plugin.rs | 4 +- src/libsyntax/ext/quote.rs | 1 - src/libsyntax/ext/tt/macro_parser.rs | 3 +- src/libsyntax/feature_gate.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 14 +- src/libsyntax/parse/parser.rs | 36 +++-- src/libsyntax/parse/token.rs | 9 +- src/libsyntax/print/pprust.rs | 1 - src/libsyntax_ext/env.rs | 6 +- src/libsyntax_pos/symbol.rs | 126 +++++++++--------- src/test/parse-fail/issue-32501.rs | 4 +- src/test/parse-fail/recover-enum2.rs | 2 +- .../parse-fail/underscore-suffix-for-float.rs | 3 +- src/test/run-pass/macro-pat.rs | 2 + src/test/ui/cross-file-errors/main.stderr | 2 +- 20 files changed, 109 insertions(+), 119 deletions(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 1163c1a98d5a..b239f8018beb 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -680,7 +680,6 @@ impl TokenTree { Pound => op!('#'), Dollar => op!('$'), Question => op!('?'), - Underscore => op!('_'), Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)), @@ -743,7 +742,6 @@ impl TokenTree { '#' => Pound, '$' => Dollar, '?' => Question, - '_' => Underscore, _ => panic!("unsupported character {}", op), }; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f4638c23c5f4..83e855178dbe 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -214,7 +214,7 @@ impl LifetimeName { use self::LifetimeName::*; match *self { Implicit => keywords::Invalid.name(), - Underscore => Symbol::intern("'_"), + Underscore => keywords::UnderscoreLifetime.name(), Static => keywords::StaticLifetime.name(), Name(name) => name, } diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 289bc753d7fe..513b6c835f98 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -287,7 +287,6 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>( token::Token::Pound | token::Token::Dollar | token::Token::Question | - token::Token::Underscore | token::Token::Whitespace | token::Token::Comment | token::Token::Eof => {} diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 55d00f92e4da..4215bf306a4f 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -37,7 +37,9 @@ impl<'a> AstValidator<'a> { } fn check_lifetime(&self, lifetime: &Lifetime) { - let valid_names = [keywords::StaticLifetime.name(), keywords::Invalid.name()]; + let valid_names = [keywords::UnderscoreLifetime.name(), + keywords::StaticLifetime.name(), + keywords::Invalid.name()]; if !valid_names.contains(&lifetime.ident.name) && token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() { self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names"); @@ -45,7 +47,7 @@ impl<'a> AstValidator<'a> { } fn check_label(&self, label: Ident, span: Span) { - if token::Ident(label.without_first_quote()).is_reserved_ident() || label.name == "'_" { + if token::Ident(label.without_first_quote()).is_reserved_ident() { self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name)); } } diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index ef01c3e6bdb0..659ec8a993dc 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -352,7 +352,7 @@ impl<'a> Classifier<'a> { token::Lifetime(..) => Class::Lifetime, - token::Underscore | token::Eof | token::Interpolated(..) | + token::Eof | token::Interpolated(..) | token::Tilde | token::At | token::DotEq => Class::None, }; diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index e8c2d325bd65..6c0fe525f55b 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -19,7 +19,7 @@ use ext::base::{ExtCtxt, MacEager, MacResult}; use ext::build::AstBuilder; use parse::token; use ptr::P; -use symbol::Symbol; +use symbol::{keywords, Symbol}; use tokenstream::{TokenTree}; use util::small_vector::SmallVector; @@ -192,7 +192,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, (descriptions.len(), ecx.expr_vec(span, descriptions)) }); - let static_ = ecx.lifetime(span, Ident::from_str("'static")); + let static_ = ecx.lifetime(span, keywords::StaticLifetime.ident()); let ty_str = ecx.ty_rptr( span, ecx.ty_ident(span, ecx.ident_of("str")), diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 7a024dbad883..d6642b7b6c26 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -709,7 +709,6 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { token::Pound => "Pound", token::Dollar => "Dollar", token::Question => "Question", - token::Underscore => "Underscore", token::Eof => "Eof", token::Whitespace | token::Comment | token::Shebang(_) => { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 0621f728e2a9..beefdb3a6eac 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -765,8 +765,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { Token::DotDotDot | // range pattern (future compat) Token::ModSep | // path Token::Lt | // path (UFCS constant) - Token::BinOp(token::Shl) | // path (double UFCS) - Token::Underscore => true, // placeholder + Token::BinOp(token::Shl) => true, // path (double UFCS) Token::Interpolated(ref nt) => may_be_ident(&nt.0), _ => false, }, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f42cb8a25831..0098f2ae89b5 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1790,7 +1790,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) { - if lt.ident.name == "'_" { + if lt.ident.name == keywords::UnderscoreLifetime.name() { gate_feature_post!(&self, underscore_lifetimes, lt.span, "underscore lifetimes are unstable"); } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 815ba49a60a7..9d1bfba7b944 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -34,7 +34,7 @@ pub struct TokenAndSpan { impl Default for TokenAndSpan { fn default() -> Self { - TokenAndSpan { tok: token::Underscore, sp: syntax_pos::DUMMY_SP } + TokenAndSpan { tok: token::Whitespace, sp: syntax_pos::DUMMY_SP } } } @@ -126,7 +126,7 @@ impl<'a> StringReader<'a> { pub fn try_next_token(&mut self) -> Result { assert!(self.fatal_errs.is_empty()); let ret_val = TokenAndSpan { - tok: replace(&mut self.peek_tok, token::Underscore), + tok: replace(&mut self.peek_tok, token::Whitespace), sp: self.peek_span, }; self.advance_token()?; @@ -1133,14 +1133,8 @@ impl<'a> StringReader<'a> { self.bump(); } - return Ok(self.with_str_from(start, |string| { - if string == "_" { - token::Underscore - } else { - // FIXME: perform NFKC normalization here. (Issue #2253) - token::Ident(self.mk_ident(string)) - } - })); + // FIXME: perform NFKC normalization here. (Issue #2253) + return Ok(self.with_str_from(start, |string| token::Ident(self.mk_ident(string)))); } if is_dec_digit(c) { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a3a6489fe8b1..aa2a6f1cb47f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -549,7 +549,7 @@ impl<'a> Parser<'a> { -> Self { let mut parser = Parser { sess, - token: token::Underscore, + token: token::Whitespace, span: syntax_pos::DUMMY_SP, prev_span: syntax_pos::DUMMY_SP, meta_var_span: None, @@ -800,11 +800,7 @@ impl<'a> Parser<'a> { Err(if self.prev_token_kind == PrevTokenKind::DocComment { self.span_fatal_err(self.prev_span, Error::UselessDocComment) } else { - let mut err = self.expected_ident_found(); - if self.token == token::Underscore { - err.note("`_` is a wildcard pattern, not an identifier"); - } - err + self.expected_ident_found() }) } } @@ -1602,7 +1598,7 @@ impl<'a> Parser<'a> { let e = self.parse_expr()?; self.expect(&token::CloseDelim(token::Paren))?; TyKind::Typeof(e) - } else if self.eat(&token::Underscore) { + } else if self.eat_keyword(keywords::Underscore) { // A type to be inferred `_` TyKind::Infer } else if self.token_is_bare_fn_keyword() { @@ -1796,7 +1792,7 @@ impl<'a> Parser<'a> { _ => 0, }; - self.look_ahead(offset, |t| t.is_ident() || t == &token::Underscore) && + self.look_ahead(offset, |t| t.is_ident()) && self.look_ahead(offset + 1, |t| t == &token::Colon) } @@ -2782,7 +2778,7 @@ impl<'a> Parser<'a> { }, token::CloseDelim(_) | token::Eof => unreachable!(), _ => { - let (token, span) = (mem::replace(&mut self.token, token::Underscore), self.span); + let (token, span) = (mem::replace(&mut self.token, token::Whitespace), self.span); self.bump(); TokenTree::Token(span, token) } @@ -3815,11 +3811,6 @@ impl<'a> Parser<'a> { let lo = self.span; let pat; match self.token { - token::Underscore => { - // Parse _ - self.bump(); - pat = PatKind::Wild; - } token::BinOp(token::And) | token::AndAnd => { // Parse &pat / &mut pat self.expect_and()?; @@ -3849,8 +3840,11 @@ impl<'a> Parser<'a> { self.expect(&token::CloseDelim(token::Bracket))?; pat = PatKind::Slice(before, slice, after); } - // At this point, token != _, &, &&, (, [ - _ => if self.eat_keyword(keywords::Mut) { + // At this point, token != &, &&, (, [ + _ => if self.eat_keyword(keywords::Underscore) { + // Parse _ + pat = PatKind::Wild; + } else if self.eat_keyword(keywords::Mut) { // Parse mut ident @ pat / mut ref ident @ pat let mutref_span = self.prev_span.to(self.span); let binding_mode = if self.eat_keyword(keywords::Ref) { @@ -7065,10 +7059,12 @@ impl<'a> Parser<'a> { fn parse_rename(&mut self) -> PResult<'a, Option> { if self.eat_keyword(keywords::As) { - if self.eat(&token::Underscore) { - Ok(Some(Ident::with_empty_ctxt(Symbol::gensym("_")))) - } else { - self.parse_ident().map(Some) + match self.token { + token::Ident(ident) if ident.name == keywords::Underscore.name() => { + self.bump(); // `_` + Ok(Some(Ident { name: ident.name.gensymed(), ..ident })) + } + _ => self.parse_ident().map(Some), } } else { Ok(None) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 097a2eb89fdf..5c051e9b3584 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -122,6 +122,7 @@ fn ident_can_begin_type(ident: ast::Ident) -> bool { !ident_token.is_reserved_ident() || ident_token.is_path_segment_keyword() || [ + keywords::Underscore.name(), keywords::For.name(), keywords::Impl.name(), keywords::Fn.name(), @@ -175,7 +176,6 @@ pub enum Token { /* Name components */ Ident(ast::Ident), - Underscore, Lifetime(ast::Ident), // The `LazyTokenStream` is a pure function of the `Nonterminal`, @@ -242,7 +242,6 @@ impl Token { Ident(ident) => ident_can_begin_type(ident), // type name or keyword OpenDelim(Paren) | // tuple OpenDelim(Bracket) | // array - Underscore | // placeholder Not | // never BinOp(Star) | // raw pointer BinOp(And) | // reference @@ -371,7 +370,7 @@ impl Token { // unnamed method parameters, crate root module, error recovery etc. pub fn is_special_ident(&self) -> bool { match self.ident() { - Some(id) => id.name <= keywords::DollarCrate.name(), + Some(id) => id.name <= keywords::Underscore.name(), _ => false, } } @@ -441,7 +440,7 @@ impl Token { Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotEq | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | - Question | OpenDelim(..) | CloseDelim(..) | Underscore => return None, + Question | OpenDelim(..) | CloseDelim(..) => return None, Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) | Whitespace | Comment | Shebang(..) | Eof => return None, @@ -573,7 +572,7 @@ impl fmt::Debug for Nonterminal { pub fn is_op(tok: &Token) -> bool { match *tok { OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | - Ident(..) | Underscore | Lifetime(..) | Interpolated(..) | + Ident(..) | Lifetime(..) | Interpolated(..) | Whitespace | Comment | Shebang(..) | Eof => false, _ => true, } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1cf2b7a44bc1..36698a863745 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -252,7 +252,6 @@ pub fn token_to_string(tok: &Token) -> String { /* Name components */ token::Ident(s) => s.to_string(), token::Lifetime(s) => s.to_string(), - token::Underscore => "_".to_string(), /* Other */ token::DocComment(s) => s.to_string(), diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index fcad065be52b..ba6d25f7a60a 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -17,7 +17,7 @@ use syntax::ast::{self, Ident}; use syntax::ext::base::*; use syntax::ext::base; use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; +use syntax::symbol::{keywords, Symbol}; use syntax_pos::Span; use syntax::tokenstream; @@ -35,14 +35,14 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, let sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark)); let e = match env::var(&*var.as_str()) { Err(..) => { + let lt = cx.lifetime(sp, keywords::StaticLifetime.ident()); cx.expr_path(cx.path_all(sp, true, cx.std_path(&["option", "Option", "None"]), Vec::new(), vec![cx.ty_rptr(sp, cx.ty_ident(sp, Ident::from_str("str")), - Some(cx.lifetime(sp, - Ident::from_str("'static"))), + Some(lt), ast::Mutability::Immutable)], Vec::new())) } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index e95079f7c88d..0cba094da641 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -261,73 +261,77 @@ macro_rules! declare_keywords {( declare_keywords! { // Special reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. - (0, Invalid, "") - (1, CrateRoot, "{{root}}") - (2, DollarCrate, "$crate") + (0, Invalid, "") + (1, CrateRoot, "{{root}}") + (2, DollarCrate, "$crate") + (3, Underscore, "_") // Keywords used in the language. - (3, As, "as") - (4, Box, "box") - (5, Break, "break") - (6, Const, "const") - (7, Continue, "continue") - (8, Crate, "crate") - (9, Else, "else") - (10, Enum, "enum") - (11, Extern, "extern") - (12, False, "false") - (13, Fn, "fn") - (14, For, "for") - (15, If, "if") - (16, Impl, "impl") - (17, In, "in") - (18, Let, "let") - (19, Loop, "loop") - (20, Match, "match") - (21, Mod, "mod") - (22, Move, "move") - (23, Mut, "mut") - (24, Pub, "pub") - (25, Ref, "ref") - (26, Return, "return") - (27, SelfValue, "self") - (28, SelfType, "Self") - (29, Static, "static") - (30, Struct, "struct") - (31, Super, "super") - (32, Trait, "trait") - (33, True, "true") - (34, Type, "type") - (35, Unsafe, "unsafe") - (36, Use, "use") - (37, Where, "where") - (38, While, "while") + (4, As, "as") + (5, Box, "box") + (6, Break, "break") + (7, Const, "const") + (8, Continue, "continue") + (9, Crate, "crate") + (10, Else, "else") + (11, Enum, "enum") + (12, Extern, "extern") + (13, False, "false") + (14, Fn, "fn") + (15, For, "for") + (16, If, "if") + (17, Impl, "impl") + (18, In, "in") + (19, Let, "let") + (20, Loop, "loop") + (21, Match, "match") + (22, Mod, "mod") + (23, Move, "move") + (24, Mut, "mut") + (25, Pub, "pub") + (26, Ref, "ref") + (27, Return, "return") + (28, SelfValue, "self") + (29, SelfType, "Self") + (30, Static, "static") + (31, Struct, "struct") + (32, Super, "super") + (33, Trait, "trait") + (34, True, "true") + (35, Type, "type") + (36, Unsafe, "unsafe") + (37, Use, "use") + (38, Where, "where") + (39, While, "while") // Keywords reserved for future use. - (39, Abstract, "abstract") - (40, Alignof, "alignof") - (41, Become, "become") - (42, Do, "do") - (43, Final, "final") - (44, Macro, "macro") - (45, Offsetof, "offsetof") - (46, Override, "override") - (47, Priv, "priv") - (48, Proc, "proc") - (49, Pure, "pure") - (50, Sizeof, "sizeof") - (51, Typeof, "typeof") - (52, Unsized, "unsized") - (53, Virtual, "virtual") - (54, Yield, "yield") + (40, Abstract, "abstract") + (41, Alignof, "alignof") + (42, Become, "become") + (43, Do, "do") + (44, Final, "final") + (45, Macro, "macro") + (46, Offsetof, "offsetof") + (47, Override, "override") + (48, Priv, "priv") + (49, Proc, "proc") + (50, Pure, "pure") + (51, Sizeof, "sizeof") + (52, Typeof, "typeof") + (53, Unsized, "unsized") + (54, Virtual, "virtual") + (55, Yield, "yield") + + // Special lifetime names + (56, UnderscoreLifetime, "'_") + (57, StaticLifetime, "'static") // Weak keywords, have special meaning only in specific contexts. - (55, Auto, "auto") - (56, Catch, "catch") - (57, Default, "default") - (58, Dyn, "dyn") - (59, StaticLifetime, "'static") - (60, Union, "union") + (58, Auto, "auto") + (59, Catch, "catch") + (60, Default, "default") + (61, Dyn, "dyn") + (62, Union, "union") } // If an interner exists, return it. Otherwise, prepare a fresh one. diff --git a/src/test/parse-fail/issue-32501.rs b/src/test/parse-fail/issue-32501.rs index f29c1fa27940..21db2f505170 100644 --- a/src/test/parse-fail/issue-32501.rs +++ b/src/test/parse-fail/issue-32501.rs @@ -16,7 +16,5 @@ fn main() { let _ = 0; let mut b = 0; let mut _b = 0; - let mut _ = 0; //~ ERROR expected identifier, found `_` - //~^ NOTE `_` is a wildcard pattern, not an identifier - //~| NOTE expected identifier + let mut _ = 0; //~ ERROR expected identifier, found reserved identifier `_` } diff --git a/src/test/parse-fail/recover-enum2.rs b/src/test/parse-fail/recover-enum2.rs index 49380a03e156..6fd32f842f13 100644 --- a/src/test/parse-fail/recover-enum2.rs +++ b/src/test/parse-fail/recover-enum2.rs @@ -39,5 +39,5 @@ fn main() { } } // still recover later - let bad_syntax = _; //~ ERROR: found `_` + let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_` } diff --git a/src/test/parse-fail/underscore-suffix-for-float.rs b/src/test/parse-fail/underscore-suffix-for-float.rs index df7d9aa374dc..8327217e6f28 100644 --- a/src/test/parse-fail/underscore-suffix-for-float.rs +++ b/src/test/parse-fail/underscore-suffix-for-float.rs @@ -9,5 +9,6 @@ // except according to those terms. fn main() { - let a = 42._; //~ ERROR unexpected token: `_` + let a = 42._; //~ ERROR expected identifier, found reserved identifier `_` + //~^ ERROR `{integer}` is a primitive type and therefore doesn't have fields } diff --git a/src/test/run-pass/macro-pat.rs b/src/test/run-pass/macro-pat.rs index 48e521de57e9..8de3996245f8 100644 --- a/src/test/run-pass/macro-pat.rs +++ b/src/test/run-pass/macro-pat.rs @@ -71,4 +71,6 @@ pub fn main() { let ident_pat!(x) = 2; x+1 }); + + let ident_pat!(_) = 2; // OK } diff --git a/src/test/ui/cross-file-errors/main.stderr b/src/test/ui/cross-file-errors/main.stderr index a9db5214e6a2..41a2172d2958 100644 --- a/src/test/ui/cross-file-errors/main.stderr +++ b/src/test/ui/cross-file-errors/main.stderr @@ -1,4 +1,4 @@ -error: expected expression, found `_` +error: expected expression, found reserved identifier `_` --> $DIR/underscore.rs:18:9 | LL | _ From ed5ea5c705ccea7d2eef1558530e87d2dbb88be7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 17 Mar 2018 22:08:18 +0300 Subject: [PATCH 328/830] Reject `_` in `ident` matcher --- src/libsyntax/ext/tt/macro_parser.rs | 36 +++++++++++---------- src/test/run-pass/macro-pat.rs | 2 -- src/test/ui/underscore-ident-matcher.rs | 19 +++++++++++ src/test/ui/underscore-ident-matcher.stderr | 8 +++++ 4 files changed, 46 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/underscore-ident-matcher.rs create mode 100644 src/test/ui/underscore-ident-matcher.stderr diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index beefdb3a6eac..667653b5f7f2 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -86,7 +86,7 @@ use self::TokenTreeOrTokenTreeVec::*; use ast::Ident; use syntax_pos::{self, BytePos, Span}; -use codemap::Spanned; +use codemap::respan; use errors::FatalError; use ext::tt::quoted::{self, TokenTree}; use parse::{Directory, ParseSess}; @@ -709,6 +709,15 @@ pub fn parse( } } +/// The token is an identifier, but not `_`. +/// We prohibit passing `_` to macros expecting `ident` for now. +fn get_macro_ident(token: &Token) -> Option { + match *token { + token::Ident(ident) if ident.name != keywords::Underscore.name() => Some(ident), + _ => None, + } +} + /// Checks whether a non-terminal may begin with a particular token. /// /// Returning `false` is a *stability guarantee* that such a matcher will *never* begin with that @@ -725,7 +734,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { match name { "expr" => token.can_begin_expr(), "ty" => token.can_begin_type(), - "ident" => token.is_ident(), + "ident" => get_macro_ident(token).is_some(), "vis" => match *token { // The follow-set of :vis + "priv" keyword + interpolated Token::Comma | Token::Ident(_) | Token::Interpolated(_) => true, @@ -814,21 +823,14 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { "expr" => token::NtExpr(panictry!(p.parse_expr())), "ty" => token::NtTy(panictry!(p.parse_ty())), // this could be handled like a token, since it is one - "ident" => match p.token { - token::Ident(sn) => { - p.bump(); - token::NtIdent(Spanned:: { - node: sn, - span: p.prev_span, - }) - } - _ => { - let token_str = pprust::token_to_string(&p.token); - p.fatal(&format!("expected ident, found {}", &token_str[..])) - .emit(); - FatalError.raise() - } - }, + "ident" => if let Some(ident) = get_macro_ident(&p.token) { + p.bump(); + token::NtIdent(respan(p.prev_span, ident)) + } else { + let token_str = pprust::token_to_string(&p.token); + p.fatal(&format!("expected ident, found {}", &token_str)).emit(); + FatalError.raise() + } "path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))), "meta" => token::NtMeta(panictry!(p.parse_meta_item())), "vis" => token::NtVis(panictry!(p.parse_visibility(true))), diff --git a/src/test/run-pass/macro-pat.rs b/src/test/run-pass/macro-pat.rs index 8de3996245f8..48e521de57e9 100644 --- a/src/test/run-pass/macro-pat.rs +++ b/src/test/run-pass/macro-pat.rs @@ -71,6 +71,4 @@ pub fn main() { let ident_pat!(x) = 2; x+1 }); - - let ident_pat!(_) = 2; // OK } diff --git a/src/test/ui/underscore-ident-matcher.rs b/src/test/ui/underscore-ident-matcher.rs new file mode 100644 index 000000000000..eee99296c794 --- /dev/null +++ b/src/test/ui/underscore-ident-matcher.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +macro_rules! identity { + ($i: ident) => ( + $i + ) +} + +fn main() { + let identity!(_) = 10; //~ ERROR no rules expected the token `_` +} diff --git a/src/test/ui/underscore-ident-matcher.stderr b/src/test/ui/underscore-ident-matcher.stderr new file mode 100644 index 000000000000..7f2b6ac30b0d --- /dev/null +++ b/src/test/ui/underscore-ident-matcher.stderr @@ -0,0 +1,8 @@ +error: no rules expected the token `_` + --> $DIR/underscore-ident-matcher.rs:18:19 + | +LL | let identity!(_) = 10; //~ ERROR no rules expected the token `_` + | ^ + +error: aborting due to previous error + From c6c6cf9515b330551b04f36025bc72e1288a96d9 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 9 Mar 2018 18:51:48 +0300 Subject: [PATCH 329/830] AST/HIR: Clarify what the optional name in extern crate items mean --- src/librustc/hir/intravisit.rs | 6 +++--- src/librustc/hir/lowering.rs | 2 +- src/librustc/hir/mod.rs | 4 ++-- src/librustc/hir/print.rs | 11 +++-------- src/librustc/ich/impls_hir.rs | 2 +- src/librustc/session/config.rs | 2 +- src/librustc_driver/driver.rs | 2 +- src/librustc_metadata/creader.rs | 16 +++++++++------- src/librustc_resolve/build_reduced_graph.rs | 4 ++-- src/librustdoc/visit_ast.rs | 4 ++-- src/libsyntax/ast.rs | 2 +- src/libsyntax/fold.rs | 2 +- src/libsyntax/parse/parser.rs | 20 +++++++------------- src/libsyntax/print/pprust.rs | 11 +++-------- src/libsyntax/std_inject.rs | 6 ++---- src/libsyntax/visit.rs | 6 +++--- 16 files changed, 42 insertions(+), 58 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index b804cf7bf5a3..972278bdf865 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -444,10 +444,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_vis(&item.vis); visitor.visit_name(item.span, item.name); match item.node { - ItemExternCrate(opt_name) => { + ItemExternCrate(orig_name) => { visitor.visit_id(item.id); - if let Some(name) = opt_name { - visitor.visit_name(item.span, name); + if let Some(orig_name) = orig_name { + visitor.visit_name(item.span, orig_name); } } ItemUse(ref path, _) => { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 49611689fc4a..41950d21c09c 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1904,7 +1904,7 @@ impl<'a> LoweringContext<'a> { i: &ItemKind) -> hir::Item_ { match *i { - ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), + ItemKind::ExternCrate(orig_name) => hir::ItemExternCrate(orig_name), ItemKind::Use(ref use_tree) => { // Start with an empty prefix let prefix = Path { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f4638c23c5f4..46c79d03149e 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2011,9 +2011,9 @@ pub struct Item { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Item_ { - /// An `extern crate` item, with optional original crate name, + /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// - /// e.g. `extern crate foo` or `extern crate foo_bar as foo` + /// E.g. `extern crate foo` or `extern crate foo_bar as foo` ItemExternCrate(Option), /// `use foo::bar::*;` or `use foo::bar::baz as quux;` diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 9e755f366a7d..3d38c0c8ed9e 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -524,15 +524,10 @@ impl<'a> State<'a> { self.print_outer_attributes(&item.attrs)?; self.ann.pre(self, NodeItem(item))?; match item.node { - hir::ItemExternCrate(ref optional_path) => { + hir::ItemExternCrate(orig_name) => { self.head(&visibility_qualified(&item.vis, "extern crate"))?; - if let Some(p) = *optional_path { - let val = p.as_str(); - if val.contains("-") { - self.print_string(&val, ast::StrStyle::Cooked)?; - } else { - self.print_name(p)?; - } + if let Some(orig_name) = orig_name { + self.print_name(orig_name)?; self.s.space()?; self.s.word("as")?; self.s.space()?; diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index c085b803085a..e764cedd658b 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -851,7 +851,7 @@ impl<'a> HashStable> for hir::Item { } impl_stable_hash_for!(enum hir::Item_ { - ItemExternCrate(name), + ItemExternCrate(orig_name), ItemUse(path, use_kind), ItemStatic(ty, mutability, body_id), ItemConst(ty, body_id), diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2cf09a002c9f..0d91074e946b 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -385,7 +385,7 @@ top_level_options!( externs: Externs [UNTRACKED], crate_name: Option [TRACKED], // An optional name to use as the crate for std during std injection, - // written `extern crate std = "name"`. Default to "std". Used by + // written `extern crate name as std`. Defaults to `std`. Used by // out-of-tree drivers. alt_std_name: Option [TRACKED], // Indicates how the compiler should treat unstable features diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index b5e31bdf6686..710fef8db40d 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -683,7 +683,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, }); krate = time(sess, "crate injection", || { - let alt_std_name = sess.opts.alt_std_name.clone(); + let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| &**s); syntax::std_inject::maybe_inject_crates_ref(krate, alt_std_name) }); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 789ecd0f6136..ee372c0bc5d1 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -1052,12 +1052,14 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { fn process_item(&mut self, item: &ast::Item, definitions: &Definitions) { match item.node { - ast::ItemKind::ExternCrate(rename) => { - debug!("resolving extern crate stmt. ident: {} rename: {:?}", item.ident, rename); - let rename = match rename { - Some(rename) => { - validate_crate_name(Some(self.sess), &rename.as_str(), Some(item.span)); - rename + ast::ItemKind::ExternCrate(orig_name) => { + debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", + item.ident, orig_name); + let orig_name = match orig_name { + Some(orig_name) => { + validate_crate_name(Some(self.sess), &orig_name.as_str(), + Some(item.span)); + orig_name } None => item.ident.name, }; @@ -1068,7 +1070,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { }; let (cnum, ..) = self.resolve_crate( - &None, item.ident.name, rename, None, item.span, PathKind::Crate, dep_kind, + &None, item.ident.name, orig_name, None, item.span, PathKind::Crate, dep_kind, ); let def_id = definitions.opt_local_def_id(item.id).unwrap(); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index bf7b81c4d0e4..335064402c47 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -255,7 +255,7 @@ impl<'a> Resolver<'a> { ); } - ItemKind::ExternCrate(as_name) => { + ItemKind::ExternCrate(orig_name) => { self.crate_loader.process_item(item, &self.definitions); // n.b. we don't need to look at the path option here, because cstore already did @@ -274,7 +274,7 @@ impl<'a> Resolver<'a> { id: item.id, parent, imported_module: Cell::new(Some(module)), - subclass: ImportDirectiveSubclass::ExternCrate(as_name), + subclass: ImportDirectiveSubclass::ExternCrate(orig_name), span: item.span, module_path: Vec::new(), vis: Cell::new(vis), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f692e05d6a25..f45a5b030db2 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -406,13 +406,13 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { // If we're inlining, skip private items. _ if self.inlining && item.vis != hir::Public => {} hir::ItemGlobalAsm(..) => {} - hir::ItemExternCrate(ref p) => { + hir::ItemExternCrate(orig_name) => { let def_id = self.cx.tcx.hir.local_def_id(item.id); om.extern_crates.push(ExternCrate { cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id) .unwrap_or(LOCAL_CRATE), name, - path: p.map(|x|x.to_string()), + path: orig_name.map(|x|x.to_string()), vis: item.vis.clone(), attrs: item.attrs.clone(), whence: item.span, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8b3a7164cccb..7ced64248247 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2055,7 +2055,7 @@ pub struct Item { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum ItemKind { - /// An `extern crate` item, with optional original crate name. + /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// /// E.g. `extern crate foo` or `extern crate foo_bar as foo` ExternCrate(Option), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 2cf99e15d1f9..1a65fb7639a4 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -886,7 +886,7 @@ pub fn noop_fold_block(b: P, folder: &mut T) -> P { pub fn noop_fold_item_kind(i: ItemKind, folder: &mut T) -> ItemKind { match i { - ItemKind::ExternCrate(string) => ItemKind::ExternCrate(string), + ItemKind::ExternCrate(orig_name) => ItemKind::ExternCrate(orig_name), ItemKind::Use(use_tree) => { ItemKind::Use(use_tree.map(|tree| folder.fold_use_tree(tree))) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a3a6489fe8b1..d1234d25764d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6291,23 +6291,17 @@ impl<'a> Parser<'a> { lo: Span, visibility: Visibility, attrs: Vec) - -> PResult<'a, P> { - - let crate_name = self.parse_ident()?; - let (maybe_path, ident) = if let Some(ident) = self.parse_rename()? { - (Some(crate_name.name), ident) + -> PResult<'a, P> { + let orig_name = self.parse_ident()?; + let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? { + (rename, Some(orig_name.name)) } else { - (None, crate_name) + (orig_name, None) }; self.expect(&token::Semi)?; - let prev_span = self.prev_span; - - Ok(self.mk_item(lo.to(prev_span), - ident, - ItemKind::ExternCrate(maybe_path), - visibility, - attrs)) + let span = lo.to(self.prev_span); + Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs)) } /// Parse `extern` for foreign ABIs diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1cf2b7a44bc1..097c0fd16d08 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1174,15 +1174,10 @@ impl<'a> State<'a> { self.print_outer_attributes(&item.attrs)?; self.ann.pre(self, NodeItem(item))?; match item.node { - ast::ItemKind::ExternCrate(ref optional_path) => { + ast::ItemKind::ExternCrate(orig_name) => { self.head(&visibility_qualified(&item.vis, "extern crate"))?; - if let Some(p) = *optional_path { - let val = p.as_str(); - if val.contains('-') { - self.print_string(&val, ast::StrStyle::Cooked)?; - } else { - self.print_name(p)?; - } + if let Some(orig_name) = orig_name { + self.print_name(orig_name)?; self.s.space()?; self.s.word("as")?; self.s.space()?; diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index da24107f4c33..59425929f7ed 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -43,7 +43,7 @@ thread_local! { static INJECTED_CRATE_NAME: Cell> = Cell::new(None); } -pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option) -> ast::Crate { +pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str>) -> ast::Crate { let name = if attr::contains_name(&krate.attrs, "no_core") { return krate; } else if attr::contains_name(&krate.attrs, "no_std") { @@ -54,14 +54,12 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option>(visitor: &mut V, item: &'a Item) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.span, item.ident); match item.node { - ItemKind::ExternCrate(opt_name) => { - if let Some(name) = opt_name { - visitor.visit_name(item.span, name); + ItemKind::ExternCrate(orig_name) => { + if let Some(orig_name) = orig_name { + visitor.visit_name(item.span, orig_name); } } ItemKind::Use(ref use_tree) => { From b057c554ab9c7615ebdb3c920010a164ec5bf3ed Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 9 Mar 2018 18:58:44 +0300 Subject: [PATCH 330/830] AST: Make renames in imports closer to the source Fix `unused_import_braces` lint false positive on `use prefix::{self as rename}` --- src/librustc/hir/lowering.rs | 6 +++--- src/librustc_lint/unused.rs | 7 ++++--- src/librustc_resolve/build_reduced_graph.rs | 11 ++++++----- src/librustc_save_analysis/dump_visitor.rs | 3 ++- src/libsyntax/ast.rs | 17 ++++++++++++++--- src/libsyntax/ext/build.rs | 11 +++++------ src/libsyntax/fold.rs | 3 ++- src/libsyntax/parse/parser.rs | 4 +--- src/libsyntax/print/pprust.rs | 7 +++---- src/libsyntax/test.rs | 13 +++++++------ src/libsyntax/visit.rs | 7 ++++--- .../lint-unnecessary-import-braces.rs | 4 ++-- 12 files changed, 53 insertions(+), 40 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 41950d21c09c..1e355bb30cbe 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2047,8 +2047,8 @@ impl<'a> LoweringContext<'a> { let path = &tree.prefix; match tree.kind { - UseTreeKind::Simple(ident) => { - *name = ident.name; + UseTreeKind::Simple(rename) => { + *name = tree.ident().name; // First apply the prefix to the path let mut path = Path { @@ -2064,7 +2064,7 @@ impl<'a> LoweringContext<'a> { if path.segments.len() > 1 && path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() { let _ = path.segments.pop(); - if ident.name == keywords::SelfValue.name() { + if rename.is_none() { *name = path.segments.last().unwrap().identifier.name; } } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index d777f6f19b0f..86f79c553c39 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -377,11 +377,12 @@ impl UnusedImportBraces { // Trigger the lint if the nested item is a non-self single item let node_ident; match items[0].0.kind { - ast::UseTreeKind::Simple(ident) => { - if ident.name == keywords::SelfValue.name() { + ast::UseTreeKind::Simple(rename) => { + let orig_ident = items[0].0.prefix.segments.last().unwrap().identifier; + if orig_ident.name == keywords::SelfValue.name() { return; } else { - node_ident = ident; + node_ident = rename.unwrap_or(orig_ident); } } ast::UseTreeKind::Glob => { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 335064402c47..e6c8dfa83565 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -119,7 +119,8 @@ impl<'a> Resolver<'a> { .collect(); match use_tree.kind { - ast::UseTreeKind::Simple(mut ident) => { + ast::UseTreeKind::Simple(rename) => { + let mut ident = use_tree.ident(); let mut source = module_path.pop().unwrap().node; let mut type_ns_only = false; @@ -142,7 +143,7 @@ impl<'a> Resolver<'a> { // Replace `use foo::self;` with `use foo;` let _ = module_path.pop(); source = last_segment.node; - if ident.name == keywords::SelfValue.name() { + if rename.is_none() { ident = last_segment.node; } } @@ -162,7 +163,7 @@ impl<'a> Resolver<'a> { ModuleKind::Block(..) => unreachable!(), }; source.name = crate_name; - if ident.name == keywords::DollarCrate.name() { + if rename.is_none() { ident.name = crate_name; } @@ -206,8 +207,8 @@ impl<'a> Resolver<'a> { // Ensure there is at most one `self` in the list let self_spans = items.iter().filter_map(|&(ref use_tree, _)| { - if let ast::UseTreeKind::Simple(ident) = use_tree.kind { - if ident.name == keywords::SelfValue.name() { + if let ast::UseTreeKind::Simple(..) = use_tree.kind { + if use_tree.ident().name == keywords::SelfValue.name() { return Some(use_tree.span); } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index d92025a6787d..b9b4186c818a 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1342,7 +1342,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .map(::id_from_def_id); match use_tree.kind { - ast::UseTreeKind::Simple(ident) => { + ast::UseTreeKind::Simple(..) => { + let ident = use_tree.ident(); let path = ast::Path { segments: prefix.segments .iter() diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7ced64248247..fdb32486b5de 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1880,18 +1880,29 @@ pub type Variant = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum UseTreeKind { - Simple(Ident), - Glob, + Simple(Option), Nested(Vec<(UseTree, NodeId)>), + Glob, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct UseTree { - pub kind: UseTreeKind, pub prefix: Path, + pub kind: UseTreeKind, pub span: Span, } +impl UseTree { + pub fn ident(&self) -> Ident { + match self.kind { + UseTreeKind::Simple(Some(rename)) => rename, + UseTreeKind::Simple(None) => + self.prefix.segments.last().expect("empty prefix in a simple import").identifier, + _ => panic!("`UseTree::ident` can only be used on a simple import"), + } + } +} + /// Distinguishes between Attributes that decorate items and Attributes that /// are contained as statements within items. These two cases need to be /// distinguished for pretty-printing. diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index b88e064e7e56..97f784dd6179 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -294,7 +294,7 @@ pub trait AstBuilder { vis: ast::Visibility, vp: P) -> P; fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P; fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, - ident: ast::Ident, path: ast::Path) -> P; + ident: Option, path: ast::Path) -> P; fn item_use_list(&self, sp: Span, vis: ast::Visibility, path: Vec, imports: &[ast::Ident]) -> P; fn item_use_glob(&self, sp: Span, @@ -1159,16 +1159,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P { - let last = path.segments.last().unwrap().identifier; - self.item_use_simple_(sp, vis, last, path) + self.item_use_simple_(sp, vis, None, path) } fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, - ident: ast::Ident, path: ast::Path) -> P { + rename: Option, path: ast::Path) -> P { self.item_use(sp, vis, P(ast::UseTree { span: sp, prefix: path, - kind: ast::UseTreeKind::Simple(ident), + kind: ast::UseTreeKind::Simple(rename), })) } @@ -1178,7 +1177,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { (ast::UseTree { span: sp, prefix: self.path(sp, vec![*id]), - kind: ast::UseTreeKind::Simple(*id), + kind: ast::UseTreeKind::Simple(None), }, ast::DUMMY_NODE_ID) }).collect(); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1a65fb7639a4..146f580e04ee 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -323,7 +323,8 @@ pub fn noop_fold_use_tree(use_tree: UseTree, fld: &mut T) -> UseTree span: fld.new_span(use_tree.span), prefix: fld.fold_path(use_tree.prefix), kind: match use_tree.kind { - UseTreeKind::Simple(ident) => UseTreeKind::Simple(fld.fold_ident(ident)), + UseTreeKind::Simple(rename) => + UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident))), UseTreeKind::Glob => UseTreeKind::Glob, UseTreeKind::Nested(items) => UseTreeKind::Nested(items.move_map(|(tree, id)| { (fld.fold_use_tree(tree), fld.new_id(id)) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d1234d25764d..7a4329304907 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7033,9 +7033,7 @@ impl<'a> Parser<'a> { } } else { // `use path::foo;` or `use path::foo as bar;` - let rename = self.parse_rename()?. - unwrap_or(prefix.segments.last().unwrap().identifier); - UseTreeKind::Simple(rename) + UseTreeKind::Simple(self.parse_rename()?) } }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 097c0fd16d08..18a758ba9684 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2949,13 +2949,12 @@ impl<'a> State<'a> { pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> { match tree.kind { - ast::UseTreeKind::Simple(ref ident) => { + ast::UseTreeKind::Simple(rename) => { self.print_path(&tree.prefix, false, 0, true)?; - - if tree.prefix.segments.last().unwrap().identifier.name != ident.name { + if let Some(rename) = rename { self.s.space()?; self.word_space("as")?; - self.print_ident(*ident)?; + self.print_ident(rename)?; } } ast::UseTreeKind::Glob => { diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 39306229c82b..9edfa767d319 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -78,7 +78,7 @@ pub fn modify_for_testing(sess: &ParseSess, span_diagnostic: &errors::Handler, features: &Features) -> ast::Crate { // Check for #[reexport_test_harness_main = "some_name"] which - // creates a `use some_name = __test::main;`. This needs to be + // creates a `use __test::main as some_name;`. This needs to be // unconditional, so that the attribute is still marked as used in // non-test builds. let reexport_test_harness_main = @@ -240,7 +240,8 @@ fn mk_reexport_mod(cx: &mut TestCtxt, cx.ext_cx.path(DUMMY_SP, vec![super_, r])) }).chain(tested_submods.into_iter().map(|(r, sym)| { let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]); - cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public), r, path) + cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public), + Some(r), path) })).collect(); let reexport_mod = ast::Mod { @@ -502,7 +503,7 @@ fn mk_std(cx: &TestCtxt) -> P { (ast::ItemKind::Use(P(ast::UseTree { span: DUMMY_SP, prefix: path_node(vec![id_test]), - kind: ast::UseTreeKind::Simple(id_test), + kind: ast::UseTreeKind::Simple(None), })), ast::VisibilityKind::Public, keywords::Invalid.ident()) } else { @@ -590,13 +591,13 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P, Option>) { tokens: None, })).pop().unwrap(); let reexport = cx.reexport_test_harness_main.map(|s| { - // building `use = __test::main` - let reexport_ident = Ident::with_empty_ctxt(s); + // building `use __test::main as ;` + let rename = Ident::with_empty_ctxt(s); let use_path = ast::UseTree { span: DUMMY_SP, prefix: path_node(vec![mod_ident, Ident::from_str("main")]), - kind: ast::UseTreeKind::Simple(reexport_ident), + kind: ast::UseTreeKind::Simple(Some(rename)), }; expander.fold_item(P(ast::Item { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3bf9bfab2456..bbf1fe124f1b 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -354,10 +354,11 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>( visitor: &mut V, use_tree: &'a UseTree, id: NodeId, ) { visitor.visit_path(&use_tree.prefix, id); - match use_tree.kind { - UseTreeKind::Simple(ident) => { - visitor.visit_ident(use_tree.span, ident); + UseTreeKind::Simple(rename) => { + if let Some(rename) = rename { + visitor.visit_ident(use_tree.span, rename); + } } UseTreeKind::Glob => {}, UseTreeKind::Nested(ref use_trees) => { diff --git a/src/test/compile-fail/lint-unnecessary-import-braces.rs b/src/test/compile-fail/lint-unnecessary-import-braces.rs index 1c0401ec56b8..214a03c13f4e 100644 --- a/src/test/compile-fail/lint-unnecessary-import-braces.rs +++ b/src/test/compile-fail/lint-unnecessary-import-braces.rs @@ -9,12 +9,12 @@ // except according to those terms. #![deny(unused_import_braces)] -#![allow(dead_code)] -#![allow(unused_imports)] use test::{A}; //~ ERROR braces around A is unnecessary mod test { + use test::{self}; // OK + use test::{self as rename}; // OK pub struct A; } From e5fb13897d947e13a1322a055b71632e30357eff Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 10 Mar 2018 02:02:39 +0300 Subject: [PATCH 331/830] AST: Keep distinction between `path` and `::path` in imports and visibilities Add the root segment for name resolution purposes only --- src/librustc/hir/lowering.rs | 23 ++++------- src/librustc_resolve/build_reduced_graph.rs | 4 +- src/librustc_resolve/lib.rs | 19 +++++---- src/librustc_resolve/resolve_imports.rs | 9 ++--- src/libsyntax/ast.rs | 17 ++++---- src/libsyntax/ext/build.rs | 10 +++-- src/libsyntax/parse/parser.rs | 15 +++---- src/libsyntax/parse/token.rs | 1 + src/libsyntax/print/pprust.rs | 43 +++++++++------------ src/libsyntax/std_inject.rs | 2 +- 10 files changed, 66 insertions(+), 77 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1e355bb30cbe..dd3b9350d916 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1355,17 +1355,11 @@ impl<'a> LoweringContext<'a> { id: NodeId, p: &Path, name: Option, - param_mode: ParamMode, - defaults_to_global: bool) + param_mode: ParamMode) -> hir::Path { - let mut segments = p.segments.iter(); - if defaults_to_global && p.is_global() { - segments.next(); - } - hir::Path { def: self.expect_full_def(id), - segments: segments.map(|segment| { + segments: p.segments.iter().map(|segment| { self.lower_path_segment(p.span, segment, param_mode, 0, ParenthesizedGenericArgs::Err, ImplTraitContext::Disallowed) @@ -1378,10 +1372,9 @@ impl<'a> LoweringContext<'a> { fn lower_path(&mut self, id: NodeId, p: &Path, - param_mode: ParamMode, - defaults_to_global: bool) + param_mode: ParamMode) -> hir::Path { - self.lower_path_extra(id, p, None, param_mode, defaults_to_global) + self.lower_path_extra(id, p, None, param_mode) } fn lower_path_segment(&mut self, @@ -2069,7 +2062,7 @@ impl<'a> LoweringContext<'a> { } } - let path = P(self.lower_path(id, &path, ParamMode::Explicit, true)); + let path = P(self.lower_path(id, &path, ParamMode::Explicit)); hir::ItemUse(path, hir::UseKind::Single) } UseTreeKind::Glob => { @@ -2080,7 +2073,7 @@ impl<'a> LoweringContext<'a> { .cloned() .collect(), span: path.span, - }, ParamMode::Explicit, true)); + }, ParamMode::Explicit)); hir::ItemUse(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { @@ -2136,7 +2129,7 @@ impl<'a> LoweringContext<'a> { // Privatize the degenerate import base, used only to check // the stability of `use a::{};`, to avoid it showing up as // a re-export by accident when `pub`, e.g. in documentation. - let path = P(self.lower_path(id, &prefix, ParamMode::Explicit, true)); + let path = P(self.lower_path(id, &prefix, ParamMode::Explicit)); *vis = hir::Inherited; hir::ItemUse(path, hir::UseKind::ListStem) } @@ -3379,7 +3372,7 @@ impl<'a> LoweringContext<'a> { VisibilityKind::Crate(..) => hir::Visibility::Crate, VisibilityKind::Restricted { ref path, id, .. } => { hir::Visibility::Restricted { - path: P(self.lower_path(id, path, ParamMode::Explicit, true)), + path: P(self.lower_path(id, path, ParamMode::Explicit)), id: if let Some(owner) = explicit_owner { self.lower_node_id_with_owner(id, owner).node_id } else { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e6c8dfa83565..c192f349c201 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -245,9 +245,9 @@ impl<'a> Resolver<'a> { match item.node { ItemKind::Use(ref use_tree) => { - // Just an empty prefix to start out + // Imports are resolved as global by default, add starting root segment. let prefix = ast::Path { - segments: vec![], + segments: use_tree.prefix.make_root().into_iter().collect(), span: use_tree.span, }; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c84caee13e82..23ad27ec2c3d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2164,8 +2164,9 @@ impl<'a> Resolver<'a> { } ItemKind::Use(ref use_tree) => { + // Imports are resolved as global by default, add starting root segment. let path = Path { - segments: vec![], + segments: use_tree.prefix.make_root().into_iter().collect(), span: use_tree.span, }; self.resolve_use_tree(item.id, use_tree, &path); @@ -2300,7 +2301,6 @@ impl<'a> Resolver<'a> { None, &path, trait_ref.path.span, - trait_ref.path.segments.last().unwrap().span, PathSource::Trait(AliasPossibility::No) ).base_def(); if def != Def::Err { @@ -2731,8 +2731,7 @@ impl<'a> Resolver<'a> { let segments = &path.segments.iter() .map(|seg| respan(seg.span, seg.identifier)) .collect::>(); - let ident_span = path.segments.last().map_or(path.span, |seg| seg.span); - self.smart_resolve_path_fragment(id, qself, segments, path.span, ident_span, source) + self.smart_resolve_path_fragment(id, qself, segments, path.span, source) } fn smart_resolve_path_fragment(&mut self, @@ -2740,9 +2739,9 @@ impl<'a> Resolver<'a> { qself: Option<&QSelf>, path: &[SpannedIdent], span: Span, - ident_span: Span, source: PathSource) -> PathResolution { + let ident_span = path.last().map_or(span, |ident| ident.span); let ns = source.namespace(); let is_expected = &|def| source.is_expected(def); let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false }; @@ -3090,7 +3089,7 @@ impl<'a> Resolver<'a> { // Make sure `A::B` in `::B::C` is a trait item. let ns = if qself.position + 1 == path.len() { ns } else { TypeNS }; let res = self.smart_resolve_path_fragment(id, None, &path[..qself.position + 1], - span, span, PathSource::TraitItem(ns)); + span, PathSource::TraitItem(ns)); return Some(PathResolution::with_unresolved_segments( res.base_def(), res.unresolved_segments() + path.len() - qself.position - 1 )); @@ -3941,8 +3940,12 @@ impl<'a> Resolver<'a> { ty::Visibility::Restricted(self.current_module.normal_ancestor_id) } ast::VisibilityKind::Restricted { ref path, id, .. } => { - let def = self.smart_resolve_path(id, None, path, - PathSource::Visibility).base_def(); + // Visibilities are resolved as global by default, add starting root segment. + let segments = path.make_root().iter().chain(path.segments.iter()) + .map(|seg| respan(seg.span, seg.identifier)) + .collect::>(); + let def = self.smart_resolve_path_fragment(id, None, &segments, path.span, + PathSource::Visibility).base_def(); if def == Def::Err { ty::Visibility::Public } else { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 01c1ded94578..4cbebdc3c1c3 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -667,11 +667,10 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } PathResult::Failed(span, msg, true) => { let (mut self_path, mut self_result) = (module_path.clone(), None); - if !self_path.is_empty() && - !token::Ident(self_path[0].node).is_path_segment_keyword() && - !(self_path.len() > 1 && - token::Ident(self_path[1].node).is_path_segment_keyword()) - { + let is_special = |ident| token::Ident(ident).is_path_segment_keyword() && + ident.name != keywords::CrateRoot.name(); + if !self_path.is_empty() && !is_special(self_path[0].node) && + !(self_path.len() > 1 && is_special(self_path[1].node)) { self_path[0].node.name = keywords::SelfValue.name(); self_result = Some(self.resolve_path(&self_path, None, false, span)); } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fdb32486b5de..4ce6c53d3383 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -108,17 +108,16 @@ impl Path { } } - // Add starting "crate root" segment to all paths except those that - // already have it or start with `self`, `super`, `Self` or `$crate`. - pub fn default_to_global(mut self) -> Path { - if !self.is_global() { - let ident = self.segments[0].identifier; - if !::parse::token::Ident(ident).is_path_segment_keyword() || - ident.name == keywords::Crate.name() { - self.segments.insert(0, PathSegment::crate_root(self.span)); + // Make a "crate root" segment for this path unless it already has it + // or starts with something like `self`/`super`/`$crate`/etc. + pub fn make_root(&self) -> Option { + if let Some(ident) = self.segments.get(0).map(|seg| seg.identifier) { + if ::parse::token::Ident(ident).is_path_segment_keyword() && + ident.name != keywords::Crate.name() { + return None; } } - self + Some(PathSegment::crate_root(self.span.with_hi(self.span.lo()))) } pub fn is_global(&self) -> bool { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 97f784dd6179..ee646dc91743 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -329,9 +329,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> { None }; segments.push(ast::PathSegment { identifier: last_identifier, span, parameters }); - let path = ast::Path { span, segments }; - - if global { path.default_to_global() } else { path } + let mut path = ast::Path { span, segments }; + if global { + if let Some(seg) = path.make_root() { + path.segments.insert(0, seg); + } + } + path } /// Constructs a qualified path. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7a4329304907..ca879765b4ef 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5869,7 +5869,7 @@ impl<'a> Parser<'a> { // `pub(in path)` self.bump(); // `(` self.bump(); // `in` - let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `path` + let path = self.parse_path(PathStyle::Mod)?; // `path` self.expect(&token::CloseDelim(token::Paren))?; // `)` let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted { path: P(path), @@ -5882,7 +5882,7 @@ impl<'a> Parser<'a> { { // `pub(self)` or `pub(super)` self.bump(); // `(` - let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `super`/`self` + let path = self.parse_path(PathStyle::Mod)?; // `super`/`self` self.expect(&token::CloseDelim(token::Paren))?; // `)` let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted { path: P(path), @@ -6480,7 +6480,7 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::Use) { // USE ITEM - let item_ = ItemKind::Use(P(self.parse_use_tree(false)?)); + let item_ = ItemKind::Use(P(self.parse_use_tree()?)); self.expect(&token::Semi)?; let prev_span = self.prev_span; @@ -6984,7 +6984,7 @@ impl<'a> Parser<'a> { /// PATH `::` `*` | /// PATH `::` `{` USE_TREE_LIST `}` | /// PATH [`as` IDENT] - fn parse_use_tree(&mut self, nested: bool) -> PResult<'a, UseTree> { + fn parse_use_tree(&mut self) -> PResult<'a, UseTree> { let lo = self.span; let mut prefix = ast::Path { @@ -6998,8 +6998,6 @@ impl<'a> Parser<'a> { // Remove the first `::` if self.eat(&token::ModSep) { prefix.segments.push(PathSegment::crate_root(self.prev_span)); - } else if !nested { - prefix.segments.push(PathSegment::crate_root(self.span)); } if self.eat(&token::BinOp(token::Star)) { @@ -7014,9 +7012,6 @@ impl<'a> Parser<'a> { } else { // `use path::...;` let mut parsed = self.parse_path(PathStyle::Mod)?; - if !nested { - parsed = parsed.default_to_global(); - } prefix.segments.append(&mut parsed.segments); prefix.span = prefix.span.to(parsed.span); @@ -7051,7 +7046,7 @@ impl<'a> Parser<'a> { self.parse_unspanned_seq(&token::OpenDelim(token::Brace), &token::CloseDelim(token::Brace), SeqSep::trailing_allowed(token::Comma), |this| { - Ok((this.parse_use_tree(true)?, ast::DUMMY_NODE_ID)) + Ok((this.parse_use_tree()?, ast::DUMMY_NODE_ID)) }) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 097a2eb89fdf..3c602f1d1a80 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -362,6 +362,7 @@ impl Token { id.name == keywords::SelfType.name() || id.name == keywords::Extern.name() || id.name == keywords::Crate.name() || + id.name == keywords::CrateRoot.name() || id.name == keywords::DollarCrate.name(), None => false, } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 18a758ba9684..319a9a3bbaeb 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -353,7 +353,7 @@ pub fn fn_block_to_string(p: &ast::FnDecl) -> String { } pub fn path_to_string(p: &ast::Path) -> String { - to_string(|s| s.print_path(p, false, 0, false)) + to_string(|s| s.print_path(p, false, 0)) } pub fn path_segment_to_string(p: &ast::PathSegment) -> String { @@ -1051,7 +1051,7 @@ impl<'a> State<'a> { &f.generic_params)?; } ast::TyKind::Path(None, ref path) => { - self.print_path(path, false, 0, false)?; + self.print_path(path, false, 0)?; } ast::TyKind::Path(Some(ref qself), ref path) => { self.print_qpath(path, qself, false)? @@ -1378,7 +1378,7 @@ impl<'a> State<'a> { self.s.word(";")?; } ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => { - self.print_path(&node.path, false, 0, false)?; + self.print_path(&node.path, false, 0)?; self.s.word("! ")?; self.print_ident(item.ident)?; self.cbox(INDENT_UNIT)?; @@ -1403,7 +1403,7 @@ impl<'a> State<'a> { } fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> { - self.print_path(&t.path, false, 0, false) + self.print_path(&t.path, false, 0) } fn print_formal_generic_params( @@ -1460,7 +1460,7 @@ impl<'a> State<'a> { ast::CrateSugar::JustCrate => self.word_nbsp("crate") } ast::VisibilityKind::Restricted { ref path, .. } => { - let path = to_string(|s| s.print_path(path, false, 0, true)); + let path = to_string(|s| s.print_path(path, false, 0)); if path == "self" || path == "super" { self.word_nbsp(&format!("pub({})", path)) } else { @@ -1594,7 +1594,7 @@ impl<'a> State<'a> { } ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => { // code copied from ItemKind::Mac: - self.print_path(&node.path, false, 0, false)?; + self.print_path(&node.path, false, 0)?; self.s.word("! ")?; self.cbox(INDENT_UNIT)?; self.popen()?; @@ -1628,7 +1628,7 @@ impl<'a> State<'a> { } ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => { // code copied from ItemKind::Mac: - self.print_path(&node.path, false, 0, false)?; + self.print_path(&node.path, false, 0)?; self.s.word("! ")?; self.cbox(INDENT_UNIT)?; self.popen()?; @@ -1814,7 +1814,7 @@ impl<'a> State<'a> { pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken) -> io::Result<()> { - self.print_path(&m.node.path, false, 0, false)?; + self.print_path(&m.node.path, false, 0)?; self.s.word("!")?; match delim { token::Paren => self.popen()?, @@ -1915,7 +1915,7 @@ impl<'a> State<'a> { fields: &[ast::Field], wth: &Option>, attrs: &[Attribute]) -> io::Result<()> { - self.print_path(path, true, 0, false)?; + self.print_path(path, true, 0)?; self.s.word("{")?; self.print_inner_attributes_inline(attrs)?; self.commasep_cmnt( @@ -2236,7 +2236,7 @@ impl<'a> State<'a> { } } ast::ExprKind::Path(None, ref path) => { - self.print_path(path, true, 0, false)? + self.print_path(path, true, 0)? } ast::ExprKind::Path(Some(ref qself), ref path) => { self.print_qpath(path, qself, true)? @@ -2396,17 +2396,12 @@ impl<'a> State<'a> { fn print_path(&mut self, path: &ast::Path, colons_before_params: bool, - depth: usize, - defaults_to_global: bool) + depth: usize) -> io::Result<()> { self.maybe_print_comment(path.span.lo())?; - let mut segments = path.segments[..path.segments.len()-depth].iter(); - if defaults_to_global && path.is_global() { - segments.next(); - } - for (i, segment) in segments.enumerate() { + for (i, segment) in path.segments[..path.segments.len() - depth].iter().enumerate() { if i > 0 { self.s.word("::")? } @@ -2445,7 +2440,7 @@ impl<'a> State<'a> { self.s.space()?; self.word_space("as")?; let depth = path.segments.len() - qself.position; - self.print_path(path, false, depth, false)?; + self.print_path(path, false, depth)?; } self.s.word(">")?; self.s.word("::")?; @@ -2548,7 +2543,7 @@ impl<'a> State<'a> { } } PatKind::TupleStruct(ref path, ref elts, ddpos) => { - self.print_path(path, true, 0, false)?; + self.print_path(path, true, 0)?; self.popen()?; if let Some(ddpos) = ddpos { self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p))?; @@ -2566,13 +2561,13 @@ impl<'a> State<'a> { self.pclose()?; } PatKind::Path(None, ref path) => { - self.print_path(path, true, 0, false)?; + self.print_path(path, true, 0)?; } PatKind::Path(Some(ref qself), ref path) => { self.print_qpath(path, qself, false)?; } PatKind::Struct(ref path, ref fields, etc) => { - self.print_path(path, true, 0, false)?; + self.print_path(path, true, 0)?; self.nbsp()?; self.word_space("{")?; self.commasep_cmnt( @@ -2950,7 +2945,7 @@ impl<'a> State<'a> { pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> { match tree.kind { ast::UseTreeKind::Simple(rename) => { - self.print_path(&tree.prefix, false, 0, true)?; + self.print_path(&tree.prefix, false, 0)?; if let Some(rename) = rename { self.s.space()?; self.word_space("as")?; @@ -2959,7 +2954,7 @@ impl<'a> State<'a> { } ast::UseTreeKind::Glob => { if !tree.prefix.segments.is_empty() { - self.print_path(&tree.prefix, false, 0, true)?; + self.print_path(&tree.prefix, false, 0)?; self.s.word("::")?; } self.s.word("*")?; @@ -2968,7 +2963,7 @@ impl<'a> State<'a> { if tree.prefix.segments.is_empty() { self.s.word("{")?; } else { - self.print_path(&tree.prefix, false, 0, true)?; + self.print_path(&tree.prefix, false, 0)?; self.s.word("::{")?; } self.commasep(Inconsistent, &items[..], |this, &(ref tree, _)| { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 59425929f7ed..401183e7c7d5 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -79,7 +79,7 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str> vis: respan(span.empty(), ast::VisibilityKind::Inherited), node: ast::ItemKind::Use(P(ast::UseTree { prefix: ast::Path { - segments: ["{{root}}", name, "prelude", "v1"].into_iter().map(|name| { + segments: [name, "prelude", "v1"].into_iter().map(|name| { ast::PathSegment::from_ident(ast::Ident::from_str(name), DUMMY_SP) }).collect(), span, From f88162654df187923d87254cbb36806976f81771 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 10 Mar 2018 17:45:47 +0300 Subject: [PATCH 332/830] Rename `Span::empty` to `Span::shrink_to_lo`, add `Span::shrink_to_hi` --- src/librustc/hir/lowering.rs | 2 +- src/librustc_allocator/expand.rs | 2 +- src/librustc_lint/builtin.rs | 4 ++-- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_mir/build/mod.rs | 2 +- src/librustc_resolve/lib.rs | 6 +++--- src/librustc_save_analysis/dump_visitor.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 6 +++--- src/librustc_typeck/check/mod.rs | 2 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/diagnostics/plugin.rs | 2 +- src/libsyntax/ext/build.rs | 4 ++-- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/quote.rs | 2 +- src/libsyntax/fold.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax/print/pprust.rs | 4 ++-- src/libsyntax/std_inject.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 4 ++-- src/libsyntax_ext/global_asm.rs | 2 +- src/libsyntax_pos/lib.rs | 11 +++++++++-- 22 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index dd3b9350d916..1439410f7e9a 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -879,7 +879,7 @@ impl<'a> LoweringContext<'a> { TyKind::Slice(ref ty) => hir::TySlice(self.lower_ty(ty, itctx)), TyKind::Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt, itctx)), TyKind::Rptr(ref region, ref mt) => { - let span = t.span.with_hi(t.span.lo()); + let span = t.span.shrink_to_lo(); let lifetime = match *region { Some(ref lt) => self.lower_lifetime(lt), None => self.elided_lifetime(span) diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index c088458c3557..02e704b68418 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -99,7 +99,7 @@ impl<'a> Folder for ExpandAllocatorDirectives<'a> { f.cx.item_extern_crate(f.span, f.alloc), f.cx.item_use_simple( f.span, - respan(f.span.empty(), VisibilityKind::Inherited), + respan(f.span.shrink_to_lo(), VisibilityKind::Inherited), super_path, ), ]; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 031033f7208e..bffa8628ff35 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1082,7 +1082,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { if !cx.access_levels.is_reachable(it.id) { let msg = "function is marked #[no_mangle], but not exported"; let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_FNS, it.span, msg); - let insertion_span = it.span.with_hi(it.span.lo()); + let insertion_span = it.span.shrink_to_lo(); if it.vis == hir::Visibility::Inherited { err.span_suggestion(insertion_span, "try making it public", @@ -1107,7 +1107,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { !cx.access_levels.is_reachable(it.id) { let msg = "static is marked #[no_mangle], but not exported"; let mut err = cx.struct_span_lint(PRIVATE_NO_MANGLE_STATICS, it.span, msg); - let insertion_span = it.span.with_hi(it.span.lo()); + let insertion_span = it.span.shrink_to_lo(); if it.vis == hir::Visibility::Inherited { err.span_suggestion(insertion_span, "try making it public", diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 0b50f5c44962..30ff03a26538 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -523,7 +523,7 @@ impl CrateStore for cstore::CStore { tokens: body.into(), legacy: def.legacy, }), - vis: codemap::respan(local_span.empty(), ast::VisibilityKind::Inherited), + vis: codemap::respan(local_span.shrink_to_lo(), ast::VisibilityKind::Inherited), tokens: None, }) } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 23c5499bb639..8494c043f90f 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -422,7 +422,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, builder.args_and_body(block, &arguments, arg_scope, &body.value) })); // Attribute epilogue to function's closing brace - let fn_end = span.with_lo(span.hi()); + let fn_end = span.shrink_to_hi(); let source_info = builder.source_info(fn_end); let return_block = builder.return_block(); builder.cfg.terminate(block, source_info, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 23ad27ec2c3d..dc22c23271d6 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -756,7 +756,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { // don't suggest placing a use before the prelude // import or other generated ones if item.span.ctxt().outer().expn_info().is_none() { - self.span = Some(item.span.with_hi(item.span.lo())); + self.span = Some(item.span.shrink_to_lo()); self.found_use = true; return; } @@ -768,12 +768,12 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { if item.span.ctxt().outer().expn_info().is_none() { // don't insert between attributes and an item if item.attrs.is_empty() { - self.span = Some(item.span.with_hi(item.span.lo())); + self.span = Some(item.span.shrink_to_lo()); } else { // find the first attribute on the item for attr in &item.attrs { if self.span.map_or(true, |span| attr.span < span) { - self.span = Some(attr.span.with_hi(attr.span.lo())); + self.span = Some(attr.span.shrink_to_lo()); } } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index b9b4186c818a..3d4d8571c6e4 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1209,7 +1209,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId) { self.process_macro_use(trait_item.span); - let vis_span = trait_item.span.empty(); + let vis_span = trait_item.span.shrink_to_lo(); match trait_item.node { ast::TraitItemKind::Const(ref ty, ref expr) => { self.process_assoc_const( diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 5c20490f8230..61afac97d640 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -767,7 +767,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, ' // don't suggest placing a use before the prelude // import or other generated ones if item.span.ctxt().outer().expn_info().is_none() { - self.span = Some(item.span.with_hi(item.span.lo())); + self.span = Some(item.span.shrink_to_lo()); self.found_use = true; return; } @@ -779,12 +779,12 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, ' if item.span.ctxt().outer().expn_info().is_none() { // don't insert between attributes and an item if item.attrs.is_empty() { - self.span = Some(item.span.with_hi(item.span.lo())); + self.span = Some(item.span.shrink_to_lo()); } else { // find the first attribute on the item for attr in &item.attrs { if self.span.map_or(true, |span| attr.span < span) { - self.span = Some(attr.span.with_hi(attr.span.lo())); + self.span = Some(attr.span.shrink_to_lo()); } } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dc9455487ede..4a685cfddb7a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2520,7 +2520,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if sugg_unit { let sugg_span = sess.codemap().end_point(expr_sp); // remove closing `)` from the span - let sugg_span = sugg_span.with_hi(sugg_span.lo()); + let sugg_span = sugg_span.shrink_to_lo(); err.span_suggestion( sugg_span, "expected the unit value `()`; create it with empty parentheses", diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 4ce6c53d3383..eef7a6f8b4d6 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -117,7 +117,7 @@ impl Path { return None; } } - Some(PathSegment::crate_root(self.span.with_hi(self.span.lo()))) + Some(PathSegment::crate_root(self.span.shrink_to_lo())) } pub fn is_global(&self) -> bool { diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index e8c2d325bd65..97cb6b492d73 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -220,7 +220,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, ty, expr, ), - vis: codemap::respan(span.empty(), ast::VisibilityKind::Public), + vis: codemap::respan(span.shrink_to_lo(), ast::VisibilityKind::Public), span, tokens: None, }) diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index ee646dc91743..9b53553bf69d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -987,7 +987,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { attrs, id: ast::DUMMY_NODE_ID, node, - vis: respan(span.empty(), ast::VisibilityKind::Inherited), + vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited), span, tokens: None, }) @@ -1033,7 +1033,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { span: ty.span, ty, ident: None, - vis: respan(span.empty(), ast::VisibilityKind::Inherited), + vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited), attrs: Vec::new(), id: ast::DUMMY_NODE_ID, } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 7ccace014d03..34dd7696168a 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -239,7 +239,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { node: ast::ItemKind::Mod(krate.module), ident: keywords::Invalid.ident(), id: ast::DUMMY_NODE_ID, - vis: respan(krate.span.empty(), ast::VisibilityKind::Public), + vis: respan(krate.span.shrink_to_lo(), ast::VisibilityKind::Public), tokens: None, }))); diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 7a024dbad883..b322fd9df3ec 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -858,7 +858,7 @@ fn expand_wrapper(cx: &ExtCtxt, let path = path.iter().map(|s| s.to_string()).collect(); let use_item = cx.item_use_glob( sp, - respan(sp.empty(), ast::VisibilityKind::Inherited), + respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited), ids_ext(path), ); cx.stmt_item(sp, use_item) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 146f580e04ee..46e6027b094b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1019,7 +1019,7 @@ pub fn noop_fold_crate(Crate {module, attrs, span}: Crate, ident: keywords::Invalid.ident(), attrs, id: ast::DUMMY_NODE_ID, - vis: respan(span.empty(), ast::VisibilityKind::Public), + vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Public), span, node: ast::ItemKind::Mod(module), tokens: None, diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 815ba49a60a7..5b8887f3536e 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -214,7 +214,7 @@ impl<'a> StringReader<'a> { // Make the range zero-length if the span is invalid. if span.lo() > span.hi() || begin.fm.start_pos != end.fm.start_pos { - span = span.with_hi(span.lo()); + span = span.shrink_to_lo(); } let mut sr = StringReader::new_raw_internal(sess, begin.fm); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ca879765b4ef..cb7f165dbd44 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1512,7 +1512,7 @@ impl<'a> Parser<'a> { if self.eat(&token::RArrow) { Ok(FunctionRetTy::Ty(self.parse_ty_common(allow_plus, true)?)) } else { - Ok(FunctionRetTy::Default(self.span.with_hi(self.span.lo()))) + Ok(FunctionRetTy::Default(self.span.shrink_to_lo())) } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 319a9a3bbaeb..e6ed6d7b84ab 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1568,7 +1568,7 @@ impl<'a> State<'a> { ti.ident, ty, default.as_ref().map(|expr| &**expr), - &codemap::respan(ti.span.empty(), ast::VisibilityKind::Inherited), + &codemap::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited), )?; } ast::TraitItemKind::Method(ref sig, ref body) => { @@ -1579,7 +1579,7 @@ impl<'a> State<'a> { ti.ident, &ti.generics, sig, - &codemap::respan(ti.span.empty(), ast::VisibilityKind::Inherited), + &codemap::respan(ti.span.shrink_to_lo(), ast::VisibilityKind::Inherited), )?; if let Some(ref body) = *body { self.nbsp()?; diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 401183e7c7d5..fdbc795b2d36 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -76,7 +76,7 @@ pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<&str> is_sugared_doc: false, span, }], - vis: respan(span.empty(), ast::VisibilityKind::Inherited), + vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited), node: ast::ItemKind::Use(P(ast::UseTree { prefix: ast::Path { segments: [name, "prelude", "v1"].into_iter().map(|name| { diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 1b3917efdd1e..49c372b751b5 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -530,7 +530,7 @@ impl<'a> TraitDef<'a> { id: ast::DUMMY_NODE_ID, span: self.span, ident, - vis: respan(self.span.empty(), ast::VisibilityKind::Inherited), + vis: respan(self.span.shrink_to_lo(), ast::VisibilityKind::Inherited), defaultness: ast::Defaultness::Final, attrs: Vec::new(), generics: Generics::default(), @@ -977,7 +977,7 @@ impl<'a> MethodDef<'a> { attrs: self.attributes.clone(), generics: fn_generics, span: trait_.span, - vis: respan(trait_.span.empty(), ast::VisibilityKind::Inherited), + vis: respan(trait_.span.shrink_to_lo(), ast::VisibilityKind::Inherited), defaultness: ast::Defaultness::Final, ident: method_ident, node: ast::ImplItemKind::Method(ast::MethodSig { diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 9605f6b5c5a9..f01a0aacb0a7 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -60,7 +60,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt, asm, ctxt: cx.backtrace(), })), - vis: respan(sp.empty(), ast::VisibilityKind::Inherited), + vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited), span: sp, tokens: None, }))) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 4711d43bfab1..9b83d5510fb7 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -239,8 +239,15 @@ impl Span { /// Returns a new span representing an empty span at the beginning of this span #[inline] - pub fn empty(self) -> Span { - self.with_hi(self.lo()) + pub fn shrink_to_lo(self) -> Span { + let span = self.data(); + span.with_hi(span.lo) + } + /// Returns a new span representing an empty span at the end of this span + #[inline] + pub fn shrink_to_hi(self) -> Span { + let span = self.data(); + span.with_lo(span.hi) } /// Returns `self` if `self` is not the dummy span, and `other` otherwise. From 636357b09a638661d1ed1473738038d8caa9a02e Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 10 Mar 2018 18:44:44 +0300 Subject: [PATCH 333/830] Cleanup import parsing Fix spans of root segments --- src/libsyntax/parse/mod.rs | 2 +- src/libsyntax/parse/parser.rs | 75 ++++++++++------------------------- 2 files changed, 23 insertions(+), 54 deletions(-) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index ff097c362fe6..f7e5d40b5246 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -713,7 +713,7 @@ mod tests { id: ast::DUMMY_NODE_ID, node: ast::ExprKind::Path(None, ast::Path { span: sp(0, 6), - segments: vec![ast::PathSegment::crate_root(sp(0, 2)), + segments: vec![ast::PathSegment::crate_root(sp(0, 0)), str2seg("a", 2, 3), str2seg("b", 5, 6)] }), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cb7f165dbd44..f1967ebf590d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1990,7 +1990,7 @@ impl<'a> Parser<'a> { let lo = self.meta_var_span.unwrap_or(self.span); let mut segments = Vec::new(); if self.eat(&token::ModSep) { - segments.push(PathSegment::crate_root(lo)); + segments.push(PathSegment::crate_root(lo.shrink_to_lo())); } self.parse_path_segments(&mut segments, style, enable_warning)?; @@ -2025,7 +2025,7 @@ impl<'a> Parser<'a> { loop { segments.push(self.parse_path_segment(style, enable_warning)?); - if self.is_import_coupler(false) || !self.eat(&token::ModSep) { + if self.is_import_coupler() || !self.eat(&token::ModSep) { return Ok(()); } } @@ -6483,9 +6483,8 @@ impl<'a> Parser<'a> { let item_ = ItemKind::Use(P(self.parse_use_tree()?)); self.expect(&token::Semi)?; - let prev_span = self.prev_span; - let invalid = keywords::Invalid.ident(); - let item = self.mk_item(lo.to(prev_span), invalid, item_, visibility, attrs); + let span = lo.to(self.prev_span); + let item = self.mk_item(span, keywords::Invalid.ident(), item_, visibility, attrs); return Ok(Some(item)); } @@ -6960,83 +6959,53 @@ impl<'a> Parser<'a> { })) } - /// `{` or `::{` or `*` or `::*` - /// `::{` or `::*` (also `{` or `*` if unprefixed is true) - fn is_import_coupler(&mut self, unprefixed: bool) -> bool { - self.is_import_coupler_inner(&token::OpenDelim(token::Brace), unprefixed) || - self.is_import_coupler_inner(&token::BinOp(token::Star), unprefixed) - } - - fn is_import_coupler_inner(&mut self, token: &token::Token, unprefixed: bool) -> bool { - if self.check(&token::ModSep) { - self.look_ahead(1, |t| t == token) - } else if unprefixed { - self.check(token) - } else { - false - } + /// `::{` or `::*` + fn is_import_coupler(&mut self) -> bool { + self.check(&token::ModSep) && + self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace) || + *t == token::BinOp(token::Star)) } /// Parse UseTree /// - /// USE_TREE = `*` | - /// `{` USE_TREE_LIST `}` | + /// USE_TREE = [`::`] `*` | + /// [`::`] `{` USE_TREE_LIST `}` | /// PATH `::` `*` | /// PATH `::` `{` USE_TREE_LIST `}` | /// PATH [`as` IDENT] fn parse_use_tree(&mut self) -> PResult<'a, UseTree> { let lo = self.span; - let mut prefix = ast::Path { - segments: vec![], - span: lo.to(self.span), - }; - - let kind = if self.is_import_coupler(true) { - // `use *;` or `use ::*;` or `use {...};` `use ::{...};` - - // Remove the first `::` + let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo() }; + let kind = if self.check(&token::OpenDelim(token::Brace)) || + self.check(&token::BinOp(token::Star)) || + self.is_import_coupler() { + // `use *;` or `use ::*;` or `use {...};` or `use ::{...};` if self.eat(&token::ModSep) { - prefix.segments.push(PathSegment::crate_root(self.prev_span)); + prefix.segments.push(PathSegment::crate_root(lo.shrink_to_lo())); } if self.eat(&token::BinOp(token::Star)) { - // `use *;` UseTreeKind::Glob - } else if self.check(&token::OpenDelim(token::Brace)) { - // `use {...};` - UseTreeKind::Nested(self.parse_use_tree_list()?) } else { - return self.unexpected(); + UseTreeKind::Nested(self.parse_use_tree_list()?) } } else { - // `use path::...;` - let mut parsed = self.parse_path(PathStyle::Mod)?; - - prefix.segments.append(&mut parsed.segments); - prefix.span = prefix.span.to(parsed.span); + // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;` + prefix = self.parse_path(PathStyle::Mod)?; if self.eat(&token::ModSep) { if self.eat(&token::BinOp(token::Star)) { - // `use path::*;` UseTreeKind::Glob - } else if self.check(&token::OpenDelim(token::Brace)) { - // `use path::{...};` - UseTreeKind::Nested(self.parse_use_tree_list()?) } else { - return self.unexpected(); + UseTreeKind::Nested(self.parse_use_tree_list()?) } } else { - // `use path::foo;` or `use path::foo as bar;` UseTreeKind::Simple(self.parse_rename()?) } }; - Ok(UseTree { - span: lo.to(self.prev_span), - kind, - prefix, - }) + Ok(UseTree { prefix, kind, span: lo.to(self.prev_span) }) } /// Parse UseTreeKind::Nested(list) From a02b1d7e2bd329bee0ad2f6a3e281c2004325540 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 12 Mar 2018 23:16:09 +0300 Subject: [PATCH 334/830] Add some docs + Fix rebase --- src/libsyntax/ast.rs | 6 ++++++ src/libsyntax/feature_gate.rs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index eef7a6f8b4d6..1f16b728cd23 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1877,13 +1877,19 @@ pub struct Variant_ { pub type Variant = Spanned; +/// Part of `use` item to the right of its prefix. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum UseTreeKind { + /// `use prefix` or `use prefix as rename` Simple(Option), + /// `use prefix::{...}` Nested(Vec<(UseTree, NodeId)>), + /// `use prefix::*` Glob, } +/// A tree of paths sharing common prefixes. +/// Used in `use` items both at top-level and inside of braces in import groups. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct UseTree { pub prefix: Path, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f42cb8a25831..0aef50453418 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1438,7 +1438,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_use_tree(&mut self, use_tree: &'a ast::UseTree, id: NodeId, _nested: bool) { - if let ast::UseTreeKind::Simple(ident) = use_tree.kind { + if let ast::UseTreeKind::Simple(Some(ident)) = use_tree.kind { if ident.name == "_" { gate_feature_post!(&self, underscore_imports, use_tree.span, "renaming imports with `_` is unstable"); From ca3bed0c66d27fbf30eb48ae3eb5af235669364d Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 17 Mar 2018 20:18:08 +0000 Subject: [PATCH 335/830] Improve and fix documentation for sort_by_cached_key --- src/liballoc/slice.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index db8900664476..bef50a733cc7 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1353,21 +1353,25 @@ impl [T] { /// /// # Current implementation /// - /// The current algorithm is an adaptive, iterative merge sort inspired by - /// [timsort](https://en.wikipedia.org/wiki/Timsort). - /// It is designed to be very fast in cases where the slice is nearly sorted, or consists of - /// two or more sorted sequences concatenated one after another. + /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, + /// which combines the fast average case of randomized quicksort with the fast worst case of + /// heapsort, while achieving linear time on slices with certain patterns. It uses some + /// randomization to avoid degenerate cases, but with a fixed seed to always provide + /// deterministic behavior. /// - /// The algorithm allocates temporary storage in a `Vec<(K, usize)>` the length of the slice. + /// In the worst case, the algorithm allocates temporary storage in a `Vec<(K, usize)>` the + /// length of the slice. /// /// # Examples /// /// ``` - /// let mut v = [-5i32, 4, 1, -3, 2]; + /// let mut v = [-5i32, 4, 32, -3, 2]; /// - /// v.sort_by_cached_key(|k| k.abs()); - /// assert!(v == [1, 2, -3, 4, -5]); + /// v.sort_by_cached_key(|k| k.to_string()); + /// assert!(v == [-3, -5, 2, 32, 4]); /// ``` + /// + /// [pdqsort]: https://github.com/orlp/pdqsort #[unstable(feature = "slice_sort_by_cached_key", issue = "34447")] #[inline] pub fn sort_by_cached_key(&mut self, f: F) From b57ea5615921609815752c2d2133956b8a4fded6 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 17 Mar 2018 21:41:14 +0000 Subject: [PATCH 336/830] Stabilise FromUtf8Error::as_bytes Closes #40895. --- src/liballoc/string.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 9fec90914985..e253122ffd6b 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1576,7 +1576,6 @@ impl FromUtf8Error { /// Basic usage: /// /// ``` - /// #![feature(from_utf8_error_as_bytes)] /// // some invalid bytes, in a vector /// let bytes = vec![0, 159]; /// @@ -1584,7 +1583,7 @@ impl FromUtf8Error { /// /// assert_eq!(&[0, 159], value.unwrap_err().as_bytes()); /// ``` - #[unstable(feature = "from_utf8_error_as_bytes", reason = "recently added", issue = "40895")] + #[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")] pub fn as_bytes(&self) -> &[u8] { &self.bytes[..] } From 3fa69c935d2dc28207908987a3a3cb518ab7f62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 3 Dec 2017 14:37:23 +0100 Subject: [PATCH 337/830] Make Span and Symbol implement Send and Sync --- src/libsyntax_pos/lib.rs | 6 +++++- src/libsyntax_pos/symbol.rs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index bec46ff3d797..51da9a755ec4 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -184,8 +184,12 @@ impl SpanData { } } -// The interner in thread-local, so `Span` shouldn't move between threads. +// The interner is pointed to by a thread local value which is only set on the main thread +// with parallelization is disabled. So we don't allow Span to transfer between threads +// to avoid panics and other errors, even though it would be memory safe to do so. +#[cfg(not(parallel_queries))] impl !Send for Span {} +#[cfg(not(parallel_queries))] impl !Sync for Span {} impl PartialOrd for Span { diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index e95079f7c88d..34716e6eeec8 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -83,8 +83,12 @@ impl Decodable for Ident { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Symbol(u32); -// The interner in thread-local, so `Symbol` shouldn't move between threads. +// The interner is pointed to by a thread local value which is only set on the main thread +// with parallelization is disabled. So we don't allow Symbol to transfer between threads +// to avoid panics and other errors, even though it would be memory safe to do so. +#[cfg(not(parallel_queries))] impl !Send for Symbol { } +#[cfg(not(parallel_queries))] impl !Sync for Symbol { } impl Symbol { From 1dbc84d0066c4689a1e3de21f5a22d87e74a2ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 7 Mar 2018 02:43:50 +0100 Subject: [PATCH 338/830] Remove rustc_global! --- src/librustc_data_structures/sync.rs | 30 ---------------------------- 1 file changed, 30 deletions(-) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index d7cd459e5771..f066ea98f91f 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -26,11 +26,6 @@ //! //! `MTLock` is a mutex which disappears if cfg!(parallel_queries) is false. //! -//! `rustc_global!` gives us a way to declare variables which are intended to be -//! global for the current rustc session. This currently maps to thread-locals, -//! since rustdoc uses the rustc libraries in multiple threads. -//! These globals should eventually be moved into the `Session` structure. -//! //! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync //! depending on the value of cfg!(parallel_queries). @@ -228,31 +223,6 @@ pub fn assert_sync() {} pub fn assert_send_val(_t: &T) {} pub fn assert_send_sync_val(_t: &T) {} -#[macro_export] -#[allow_internal_unstable] -macro_rules! rustc_global { - // empty (base case for the recursion) - () => {}; - - // process multiple declarations - ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => ( - thread_local!($(#[$attr])* $vis static $name: $t = $init); - rustc_global!($($rest)*); - ); - - // handle a single declaration - ($(#[$attr:meta])* $vis:vis static $name:ident: $t:ty = $init:expr) => ( - thread_local!($(#[$attr])* $vis static $name: $t = $init); - ); -} - -#[macro_export] -macro_rules! rustc_access_global { - ($name:path, $callback:expr) => { - $name.with($callback) - } -} - impl Debug for LockCell { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.debug_struct("LockCell") From 1551ef181267ea1e5db534b247148aba6bd14970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 23:23:46 +0100 Subject: [PATCH 339/830] Don't get the global lock in the fast case --- src/librustc/ty/context.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fd3465f59ebf..37a539cfff46 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -161,12 +161,12 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { -> Ty<'tcx> { let ty = { let mut interner = self.type_.borrow_mut(); - let global_interner = global_interners.map(|interners| { - interners.type_.borrow_mut() - }); if let Some(&Interned(ty)) = interner.get(&st) { return ty; } + let global_interner = global_interners.map(|interners| { + interners.type_.borrow_mut() + }); if let Some(ref interner) = global_interner { if let Some(&Interned(ty)) = interner.get(&st) { return ty; From 697d3bee96c8e385cea9cf2a01325f033ae160fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 20:11:23 +0100 Subject: [PATCH 340/830] Replace Rc with Lrc --- src/librustc/middle/const_val.rs | 4 ++-- src/librustc/traits/query/dropck_outlives.rs | 6 +++--- src/librustc/traits/query/normalize.rs | 6 +++--- src/librustc/ty/structural_impls.rs | 3 ++- src/librustc_mir/interpret/const_eval.rs | 6 +++--- src/librustc_traits/dropck_outlives.rs | 4 ++-- src/librustc_traits/normalize_projection_ty.rs | 4 ++-- 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 8c3dfd0bce75..19a7576b7cea 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -19,7 +19,7 @@ use graphviz::IntoCow; use syntax_pos::Span; use std::borrow::Cow; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub type EvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ConstEvalErr<'tcx>>; @@ -52,7 +52,7 @@ impl<'tcx> ConstVal<'tcx> { #[derive(Clone, Debug)] pub struct ConstEvalErr<'tcx> { pub span: Span, - pub kind: Rc>, + pub kind: Lrc>, } #[derive(Clone, Debug)] diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1caab6fd89ef..e16a1082214f 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -15,7 +15,7 @@ use std::iter::FromIterator; use traits::query::CanonicalTyGoal; use ty::{self, Ty, TyCtxt}; use ty::subst::Kind; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> { /// Given a type `ty` of some value being dropped, computes a set @@ -182,13 +182,13 @@ impl_stable_hash_for!(struct DropckOutlivesResult<'tcx> { impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, DropckOutlivesResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 70c5cf5f3902..63f50cff4c2a 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -17,7 +17,7 @@ use infer::at::At; use infer::canonical::{Canonical, Canonicalize, QueryResult}; use middle::const_val::ConstVal; use mir::interpret::GlobalId; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use traits::query::CanonicalProjectionGoal; use traits::project::Normalized; @@ -259,13 +259,13 @@ impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::Pr impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> { // we ought to intern this, but I'm too lazy just now - type Canonicalized = Rc>>>; + type Canonicalized = Lrc>>>; fn intern( _gcx: TyCtxt<'_, 'gcx, 'gcx>, value: Canonical<'gcx, Self::Lifted>, ) -> Self::Canonicalized { - Rc::new(value) + Lrc::new(value) } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index c9a69d5405c9..3fc20508ad7e 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -18,6 +18,7 @@ use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::sync::Lrc; use mir::interpret; use std::rc::Rc; @@ -465,7 +466,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> { tcx.lift(&*self.kind).map(|kind| { ConstEvalErr { span: self.span, - kind: Rc::new(kind), + kind: Lrc::new(kind), } }) } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 82eb28287b03..50997089a576 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -14,7 +14,7 @@ use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory}; use std::fmt; use std::error::Error; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -477,7 +477,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do match-check before building MIR if tcx.check_match(def_id).is_err() { return Err(ConstEvalErr { - kind: Rc::new(CheckMatchError), + kind: Lrc::new(CheckMatchError), span, }); } @@ -489,7 +489,7 @@ pub fn const_eval_provider<'a, 'tcx>( // Do not continue into miri if typeck errors occurred; it will fail horribly if tables.tainted_by_errors { return Err(ConstEvalErr { - kind: Rc::new(TypeckError), + kind: Lrc::new(TypeckError), span, }); } diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 2a8cfe5cc06b..1fe2f87128ab 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -16,14 +16,14 @@ use rustc::traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResu use rustc::ty::{self, ParamEnvAnd, Ty, TyCtxt}; use rustc::ty::subst::Subst; use rustc::util::nodemap::FxHashSet; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::codemap::{Span, DUMMY_SP}; use util; crate fn dropck_outlives<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalTyGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("dropck_outlives(goal={:#?})", goal); tcx.infer_ctxt().enter(|ref infcx| { diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 55785d9586cc..62d5ef11551c 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -14,7 +14,7 @@ use rustc::traits::{self, FulfillmentContext, Normalized, ObligationCause, use rustc::traits::query::{CanonicalProjectionGoal, NoSolution, normalize::NormalizationResult}; use rustc::ty::{ParamEnvAnd, TyCtxt}; use rustc::util::common::CellUsizeExt; -use std::rc::Rc; +use rustc_data_structures::sync::Lrc; use syntax::ast::DUMMY_NODE_ID; use syntax_pos::DUMMY_SP; use util; @@ -22,7 +22,7 @@ use util; crate fn normalize_projection_ty<'tcx>( tcx: TyCtxt<'_, 'tcx, 'tcx>, goal: CanonicalProjectionGoal<'tcx>, -) -> Result>>>, NoSolution> { +) -> Result>>>, NoSolution> { debug!("normalize_provider(goal={:#?})", goal); tcx.sess.perf_stats.normalize_projection_ty.increment(); From 8e5eb025a2b438eaaf609894ed910458078cc899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 14 Mar 2018 20:13:42 +0100 Subject: [PATCH 341/830] Add an Default impl for Lock --- src/librustc_data_structures/sync.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index f066ea98f91f..184ef1369761 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -333,6 +333,13 @@ impl Lock { } } +impl Default for Lock { + #[inline] + fn default() -> Self { + Lock::new(T::default()) + } +} + // FIXME: Probably a bad idea impl Clone for Lock { #[inline] From 37f9c7ff8281696545c72fc4f24e61d72b9e8df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:38:12 +0100 Subject: [PATCH 342/830] Add OnDrop --- src/librustc_data_structures/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 81246aea1b56..bf0b3726bb30 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -76,6 +76,14 @@ pub mod flock; pub mod sync; pub mod owning_ref; +pub struct OnDrop(pub F); + +impl Drop for OnDrop { + fn drop(&mut self) { + (self.0)(); + } +} + // See comments in src/librustc/lib.rs #[doc(hidden)] pub fn __noop_fix_for_27438() {} From ec4a9c6b2fb188ffd5eeee00e635061fb784af5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 15 Mar 2018 10:01:17 +0100 Subject: [PATCH 343/830] Minor cleanup --- src/librustc/ty/context.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 37a539cfff46..fbee9a0ec5c5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1010,17 +1010,16 @@ impl<'tcx> InterpretInterner<'tcx> { } } -impl<'tcx> GlobalCtxt<'tcx> { +impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Get the global TyCtxt. - pub fn global_tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> { + #[inline] + pub fn global_tcx(self) -> TyCtxt<'a, 'gcx, 'gcx> { TyCtxt { - gcx: self, - interners: &self.global_interners + gcx: self.gcx, + interners: &self.gcx.global_interners, } } -} -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics { self.global_arenas.generics.alloc(generics) } From e09c2ff3f85b428cd8283a7f7d9b38843bbc95a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 17 Mar 2018 23:02:27 +0100 Subject: [PATCH 344/830] Make interners thread-safe --- src/librustc/ty/context.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fbee9a0ec5c5..966c96e594fc 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1080,12 +1080,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self, alloc: interpret::Allocation, ) -> &'gcx interpret::Allocation { - if let Some(alloc) = self.interpret_interner.inner.borrow().allocs.get(&alloc) { + let allocs = &mut self.interpret_interner.inner.borrow_mut().allocs; + if let Some(alloc) = allocs.get(&alloc) { return alloc; } let interned = self.global_arenas.const_allocs.alloc(alloc); - if let Some(prev) = self.interpret_interner.inner.borrow_mut().allocs.replace(interned) { + if let Some(prev) = allocs.replace(interned) { bug!("Tried to overwrite interned Allocation: {:#?}", prev) } interned @@ -1112,24 +1113,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability { - if let Some(st) = self.stability_interner.borrow().get(&stab) { + let mut stability_interner = self.stability_interner.borrow_mut(); + if let Some(st) = stability_interner.get(&stab) { return st; } let interned = self.global_interners.arena.alloc(stab); - if let Some(prev) = self.stability_interner.borrow_mut().replace(interned) { + if let Some(prev) = stability_interner.replace(interned) { bug!("Tried to overwrite interned Stability: {:?}", prev) } interned } pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails { - if let Some(layout) = self.layout_interner.borrow().get(&layout) { + let mut layout_interner = self.layout_interner.borrow_mut(); + if let Some(layout) = layout_interner.get(&layout) { return layout; } let interned = self.global_arenas.layout.alloc(layout); - if let Some(prev) = self.layout_interner.borrow_mut().replace(interned) { + if let Some(prev) = layout_interner.replace(interned) { bug!("Tried to overwrite interned Layout: {:?}", prev) } interned From f40877feeb17c538a73fe6294d48af123251a8c5 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 10:39:24 +0100 Subject: [PATCH 345/830] Add 12 num::NonZero* types for each primitive integer RFC: https://github.com/rust-lang/rfcs/pull/2307 --- src/libcore/nonzero.rs | 2 +- src/libcore/num/mod.rs | 87 ++++++++++++++++++++++++++++++++++++++++++ src/libstd/lib.rs | 1 + src/libstd/num.rs | 11 ++++++ 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 2c966eb3b579..c6a1dab56175 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -62,7 +62,7 @@ impl_zeroable_for_integer_types! { /// NULL or 0 that might allow certain optimizations. #[lang = "non_zero"] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)] -pub struct NonZero(T); +pub struct NonZero(pub(crate) T); impl NonZero { /// Creates an instance of NonZero with the provided value. diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 09ab7060d37d..d3556ef742b5 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -15,9 +15,96 @@ use convert::{Infallible, TryFrom}; use fmt; use intrinsics; +use nonzero::NonZero; use ops; use str::FromStr; +macro_rules! impl_nonzero_fmt { + ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { + $( + #[$stability] + impl fmt::$Trait for $Ty { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.get().fmt(f) + } + } + )+ + } +} + +macro_rules! nonzero_integers { + ( #[$stability: meta] $( $Ty: ident($Int: ty); )+ ) => { + $( + /// An integer that is known not to equal zero. + /// + /// This may enable some memory layout optimization such as: + /// + /// ```rust + /// # #![feature(nonzero)] + /// use std::mem::size_of; + /// assert_eq!(size_of::>(), size_of::()); + /// ``` + #[$stability] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] + pub struct $Ty(NonZero<$Int>); + + impl $Ty { + /// Create a non-zero without checking the value. + /// + /// # Safety + /// + /// The value must not be zero. + #[$stability] + #[inline] + pub const unsafe fn new_unchecked(n: $Int) -> Self { + $Ty(NonZero(n)) + } + + /// Create a non-zero if the given value is not zero. + #[$stability] + #[inline] + pub fn new(n: $Int) -> Option { + if n != 0 { + Some($Ty(NonZero(n))) + } else { + None + } + } + + /// Returns the value as a primitive type. + #[$stability] + #[inline] + pub fn get(self) -> $Int { + self.0 .0 + } + + } + + impl_nonzero_fmt! { + #[$stability] + (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty + } + )+ + } +} + +nonzero_integers! { + #[unstable(feature = "nonzero", issue = "27730")] + NonZeroU8(u8); NonZeroI8(i8); + NonZeroU16(u16); NonZeroI16(i16); + NonZeroU32(u32); NonZeroI32(i32); + NonZeroU64(u64); NonZeroI64(i64); + NonZeroUsize(usize); NonZeroIsize(isize); +} + +nonzero_integers! { + // Change this to `#[unstable(feature = "i128", issue = "35118")]` + // if other NonZero* integer types are stabilizied before 128-bit integers + #[unstable(feature = "nonzero", issue = "27730")] + NonZeroU128(u128); NonZeroI128(i128); +} + /// Provides intentionally-wrapped arithmetic on `T`. /// /// Operations like `+` on `u32` values is intended to never overflow, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70a1f82c9a15..5c0a83fde102 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -282,6 +282,7 @@ #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] #![feature(exhaustive_patterns)] +#![feature(nonzero)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] diff --git a/src/libstd/num.rs b/src/libstd/num.rs index a2c133954a32..5e0406ca2202 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -21,6 +21,17 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError} #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; +#[unstable(feature = "nonzero", issue = "27730")] +pub use core::num::{ + NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, + NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize, +}; + +// Change this to `#[unstable(feature = "i128", issue = "35118")]` +// if other NonZero* integer types are stabilizied before 128-bit integers +#[unstable(feature = "nonzero", issue = "27730")] +pub use core::num::{NonZeroU128, NonZeroI128}; + #[cfg(test)] use fmt; #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; From 2d13ddb6e14322edcd07135a436d0d848d127fb2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 10:58:48 +0100 Subject: [PATCH 346/830] Use NonNull<_> instead of NonZero<*const _> in btree internals --- src/liballoc/btree/node.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index c1618043ce66..464f8f2f4ece 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -43,8 +43,7 @@ use core::marker::PhantomData; use core::mem; -use core::nonzero::NonZero; -use core::ptr::{self, Unique}; +use core::ptr::{self, Unique, NonNull}; use core::slice; use boxed::Box; @@ -149,14 +148,12 @@ impl BoxedNode { } } - unsafe fn from_ptr(ptr: NonZero<*const LeafNode>) -> Self { - BoxedNode { ptr: Unique::new_unchecked(ptr.get() as *mut LeafNode) } + unsafe fn from_ptr(ptr: NonNull>) -> Self { + BoxedNode { ptr: Unique::from(ptr) } } - fn as_ptr(&self) -> NonZero<*const LeafNode> { - unsafe { - NonZero::from(self.ptr.as_ref()) - } + fn as_ptr(&self) -> NonNull> { + NonNull::from(self.ptr) } } @@ -276,7 +273,7 @@ impl Root { /// `NodeRef` could be pointing to either type of node. pub struct NodeRef { height: usize, - node: NonZero<*const LeafNode>, + node: NonNull>, // This is null unless the borrow type is `Mut` root: *const Root, _marker: PhantomData<(BorrowType, Type)> @@ -302,7 +299,7 @@ unsafe impl Send impl NodeRef { fn as_internal(&self) -> &InternalNode { unsafe { - &*(self.node.get() as *const InternalNode) + &*(self.node.as_ptr() as *mut InternalNode) } } } @@ -310,7 +307,7 @@ impl NodeRef { impl<'a, K, V> NodeRef, K, V, marker::Internal> { fn as_internal_mut(&mut self) -> &mut InternalNode { unsafe { - &mut *(self.node.get() as *mut InternalNode) + &mut *(self.node.as_ptr() as *mut InternalNode) } } } @@ -352,7 +349,7 @@ impl NodeRef { fn as_leaf(&self) -> &LeafNode { unsafe { - &*self.node.get() + self.node.as_ref() } } @@ -382,7 +379,8 @@ impl NodeRef { >, Self > { - if let Some(non_zero) = NonZero::new(self.as_leaf().parent as *const LeafNode) { + let parent_as_leaf = self.as_leaf().parent as *const LeafNode; + if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) { Ok(Handle { node: NodeRef { height: self.height + 1, @@ -498,7 +496,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { fn as_leaf_mut(&mut self) -> &mut LeafNode { unsafe { - &mut *(self.node.get() as *mut LeafNode) + self.node.as_mut() } } @@ -1241,12 +1239,12 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } Heap.dealloc( - right_node.node.get() as *mut u8, + right_node.node.as_ptr() as *mut u8, Layout::new::>(), ); } else { Heap.dealloc( - right_node.node.get() as *mut u8, + right_node.node.as_ptr() as *mut u8, Layout::new::>(), ); } From 67f46ce1122121849890ad51c35f0eb6ded14b6f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:02:06 +0100 Subject: [PATCH 347/830] Use num::NonZero* instead of NonZero<_> in rustc and tests --- src/libcore/tests/nonzero.rs | 14 ++++----- src/librustc/ty/subst.rs | 6 ++-- .../obligation_forest/node_index.rs | 6 ++-- src/librustc_mir/dataflow/move_paths/mod.rs | 6 ++-- src/test/run-pass/enum-null-pointer-opt.rs | 9 +++--- src/test/run-pass/issue-23433.rs | 2 +- src/test/ui/print_type_sizes/niche-filling.rs | 31 +++++++------------ .../ui/print_type_sizes/niche-filling.stdout | 10 +++--- 8 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index a795dd575043..9eaf7529dd3c 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::nonzero::NonZero; +use core::num::NonZeroU32; use core::option::Option; use core::option::Option::{Some, None}; use std::mem::size_of; @@ -16,28 +16,28 @@ use std::mem::size_of; #[test] fn test_create_nonzero_instance() { let _a = unsafe { - NonZero::new_unchecked(21) + NonZeroU32::new_unchecked(21) }; } #[test] fn test_size_nonzero_in_option() { - assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::(), size_of::>()); } #[test] fn test_match_on_nonzero_option() { let a = Some(unsafe { - NonZero::new_unchecked(42) + NonZeroU32::new_unchecked(42) }); match a { Some(val) => assert_eq!(val.get(), 42), - None => panic!("unexpected None while matching on Some(NonZero(_))") + None => panic!("unexpected None while matching on Some(NonZeroU32(_))") } - match unsafe { Some(NonZero::new_unchecked(43)) } { + match unsafe { Some(NonZeroU32::new_unchecked(43)) } { Some(val) => assert_eq!(val.get(), 43), - None => panic!("unexpected None while matching on Some(NonZero(_))") + None => panic!("unexpected None while matching on Some(NonZeroU32(_))") } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index a301049fe1c4..e7b58ae1564a 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -19,11 +19,11 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc_data_structures::accumulate_vec::AccumulateVec; use core::intrinsics; -use core::nonzero::NonZero; use std::fmt; use std::iter; use std::marker::PhantomData; use std::mem; +use std::num::NonZeroUsize; /// An entity in the Rust typesystem, which can be one of /// several kinds (only types and lifetimes for now). @@ -32,7 +32,7 @@ use std::mem; /// indicate the type (`Ty` or `Region`) it points to. #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Kind<'tcx> { - ptr: NonZero, + ptr: NonZeroUsize, marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)> } @@ -63,7 +63,7 @@ impl<'tcx> UnpackedKind<'tcx> { Kind { ptr: unsafe { - NonZero::new_unchecked(ptr | tag) + NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } diff --git a/src/librustc_data_structures/obligation_forest/node_index.rs b/src/librustc_data_structures/obligation_forest/node_index.rs index a72cc6b57ead..37512e4bcd57 100644 --- a/src/librustc_data_structures/obligation_forest/node_index.rs +++ b/src/librustc_data_structures/obligation_forest/node_index.rs @@ -8,18 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::nonzero::NonZero; +use std::num::NonZeroU32; use std::u32; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct NodeIndex { - index: NonZero, + index: NonZeroU32, } impl NodeIndex { pub fn new(value: usize) -> NodeIndex { assert!(value < (u32::MAX as usize)); - NodeIndex { index: NonZero::new((value as u32) + 1).unwrap() } + NodeIndex { index: NonZeroU32::new((value as u32) + 1).unwrap() } } pub fn get(self) -> usize { diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 7b6ebc6fba87..9f6cf8c036e1 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -29,17 +29,17 @@ mod abs_domain; // (which is likely to yield a subtle off-by-one error). pub(crate) mod indexes { use std::fmt; - use core::nonzero::NonZero; + use std::num::NonZeroUsize; use rustc_data_structures::indexed_vec::Idx; macro_rules! new_index { ($Index:ident, $debug_name:expr) => { #[derive(Copy, Clone, PartialEq, Eq, Hash)] - pub struct $Index(NonZero); + pub struct $Index(NonZeroUsize); impl Idx for $Index { fn new(idx: usize) -> Self { - $Index(NonZero::new(idx + 1).unwrap()) + $Index(NonZeroUsize::new(idx + 1).unwrap()) } fn index(self) -> usize { self.0.get() - 1 diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs index e296aff2782c..12f17a1575e8 100644 --- a/src/test/run-pass/enum-null-pointer-opt.rs +++ b/src/test/run-pass/enum-null-pointer-opt.rs @@ -10,10 +10,9 @@ #![feature(nonzero, core)] -extern crate core; - -use core::nonzero::NonZero; use std::mem::size_of; +use std::num::NonZeroUsize; +use std::ptr::NonNull; use std::rc::Rc; use std::sync::Arc; @@ -59,8 +58,8 @@ fn main() { assert_eq!(size_of::<[Box; 1]>(), size_of::; 1]>>()); // Should apply to NonZero - assert_eq!(size_of::>(), size_of::>>()); - assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::>(), size_of::>>()); // Should apply to types that use NonZero internally assert_eq!(size_of::>(), size_of::>>()); diff --git a/src/test/run-pass/issue-23433.rs b/src/test/run-pass/issue-23433.rs index 7af732f561de..9547b2f08a6b 100644 --- a/src/test/run-pass/issue-23433.rs +++ b/src/test/run-pass/issue-23433.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Don't fail if we encounter a NonZero<*T> where T is an unsized type +// Don't fail if we encounter a NonNull where T is an unsized type use std::ptr::NonNull; diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index 7f234e243e92..875883a2cca7 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -14,7 +14,7 @@ // This file illustrates how niche-filling enums are handled, // modelled after cases like `Option<&u32>`, `Option` and such. // -// It uses NonZero directly, rather than `&_` or `Unique<_>`, because +// It uses NonZeroU32 rather than `&_` or `Unique<_>`, because // the test is not set up to deal with target-dependent pointer width. // // It avoids using u64/i64 because on some targets that is only 4-byte @@ -25,8 +25,7 @@ #![feature(nonzero)] #![allow(dead_code)] -extern crate core; -use core::nonzero::{NonZero, Zeroable}; +use std::num::NonZeroU32; pub enum MyOption { None, Some(T) } @@ -36,7 +35,7 @@ impl Default for MyOption { pub enum EmbeddedDiscr { None, - Record { pre: u8, val: NonZero, post: u16 }, + Record { pre: u8, val: NonZeroU32, post: u16 }, } impl Default for EmbeddedDiscr { @@ -44,32 +43,24 @@ impl Default for EmbeddedDiscr { } #[derive(Default)] -pub struct IndirectNonZero { +pub struct IndirectNonZero { pre: u8, - nested: NestedNonZero, + nested: NestedNonZero, post: u16, } -pub struct NestedNonZero { +pub struct NestedNonZero { pre: u8, - val: NonZero, + val: NonZeroU32, post: u16, } -impl Default for NestedNonZero { +impl Default for NestedNonZero { fn default() -> Self { - NestedNonZero { pre: 0, val: NonZero::new(T::one()).unwrap(), post: 0 } + NestedNonZero { pre: 0, val: NonZeroU32::new(1).unwrap(), post: 0 } } } -pub trait One { - fn one() -> Self; -} - -impl One for u32 { - fn one() -> Self { 1 } -} - pub enum Enum4 { One(A), Two(B), @@ -79,9 +70,9 @@ pub enum Enum4 { #[start] fn start(_: isize, _: *const *const u8) -> isize { - let _x: MyOption> = Default::default(); + let _x: MyOption = Default::default(); let _y: EmbeddedDiscr = Default::default(); - let _z: MyOption> = Default::default(); + let _z: MyOption = Default::default(); let _a: MyOption = Default::default(); let _b: MyOption = Default::default(); let _c: MyOption = Default::default(); diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index 0f53e7722dd5..79f9ef5a231d 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -1,9 +1,9 @@ -print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes +print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes print-type-size field `.nested`: 8 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes -print-type-size type: `MyOption>`: 12 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 12 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 12 bytes print-type-size field `.0`: 12 bytes @@ -14,7 +14,7 @@ print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes -print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes +print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes @@ -32,12 +32,14 @@ print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes -print-type-size type: `MyOption>`: 4 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size type: `core::nonzero::NonZero`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes +print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes print-type-size variant `One`: 0 bytes print-type-size field `.0`: 0 bytes From 22f7a0295828c0d75b5487d89343e722b406dd5f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:14:35 +0100 Subject: [PATCH 348/830] Deprecate core::nonzero in favor of ptr::NonNull and num::NonZero* --- src/libcore/nonzero.rs | 5 ++++- src/libcore/num/mod.rs | 4 +++- src/libcore/ptr.rs | 11 +++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index c6a1dab56175..59aaef9d66a0 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -10,8 +10,11 @@ //! Exposes the NonZero lang item which provides optimization hints. #![unstable(feature = "nonzero", - reason = "needs an RFC to flesh out the design", + reason = "deprecated", issue = "27730")] +#![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead", + since = "1.26.0")] +#![allow(deprecated)] use ops::CoerceUnsized; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index d3556ef742b5..84f6ab9b7649 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -15,7 +15,7 @@ use convert::{Infallible, TryFrom}; use fmt; use intrinsics; -use nonzero::NonZero; +#[allow(deprecated)] use nonzero::NonZero; use ops; use str::FromStr; @@ -46,9 +46,11 @@ macro_rules! nonzero_integers { /// assert_eq!(size_of::>(), size_of::()); /// ``` #[$stability] + #[allow(deprecated)] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct $Ty(NonZero<$Int>); + #[allow(deprecated)] impl $Ty { /// Create a non-zero without checking the value. /// diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 6270e5892b3a..834a2ed09f77 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -23,7 +23,7 @@ use fmt; use hash; use marker::{PhantomData, Unsize}; use mem; -use nonzero::NonZero; +#[allow(deprecated)] use nonzero::NonZero; use cmp::Ordering::{self, Less, Equal, Greater}; @@ -2285,6 +2285,7 @@ impl PartialOrd for *mut T { #[unstable(feature = "ptr_internals", issue = "0", reason = "use NonNull instead and consider PhantomData \ (if you also use #[may_dangle]), Send, and/or Sync")] +#[allow(deprecated)] pub struct Unique { pointer: NonZero<*const T>, // NOTE: this marker has no consequences for variance, but is necessary @@ -2332,6 +2333,7 @@ impl Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl Unique { /// Creates a new `Unique`. /// @@ -2392,6 +2394,7 @@ impl fmt::Pointer for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for Unique { fn from(reference: &'a mut T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } @@ -2399,6 +2402,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for Unique { fn from(reference: &'a T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } @@ -2436,7 +2440,7 @@ pub type Shared = NonNull; /// provide a public API that follows the normal shared XOR mutable rules of Rust. #[stable(feature = "nonnull", since = "1.25.0")] pub struct NonNull { - pointer: NonZero<*const T>, + #[allow(deprecated)] pointer: NonZero<*const T>, } /// `NonNull` pointers are not `Send` because the data they reference may be aliased. @@ -2463,6 +2467,7 @@ impl NonNull { } } +#[allow(deprecated)] impl NonNull { /// Creates a new `NonNull`. /// @@ -2581,6 +2586,7 @@ impl From> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { NonNull { pointer: NonZero::from(reference) } @@ -2588,6 +2594,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { NonNull { pointer: NonZero::from(reference) } From 6d682c9adc12c5aee1bac37afa15f01b420be8ee Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:45:44 +0100 Subject: [PATCH 349/830] Stop using deprecated NonZero APIs These will eventually be removed (though the NonZero lang item will likely stay). --- src/libcore/ptr.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 834a2ed09f77..4ab0ceb79677 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2341,17 +2341,21 @@ impl Unique { /// /// `ptr` must be non-null. pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { - Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData } + Unique { pointer: NonZero(ptr as _), _marker: PhantomData } } /// Creates a new `Unique` if `ptr` is non-null. pub fn new(ptr: *mut T) -> Option { - NonZero::new(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData }) + if !ptr.is_null() { + Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData }) + } else { + None + } } /// Acquires the underlying `*mut` pointer. pub fn as_ptr(self) -> *mut T { - self.pointer.get() as *mut T + self.pointer.0 as *mut T } /// Dereferences the content. @@ -2397,7 +2401,7 @@ impl fmt::Pointer for Unique { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for Unique { fn from(reference: &'a mut T) -> Self { - Unique { pointer: NonZero::from(reference), _marker: PhantomData } + Unique { pointer: NonZero(reference as _), _marker: PhantomData } } } @@ -2405,7 +2409,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for Unique { fn from(reference: &'a T) -> Self { - Unique { pointer: NonZero::from(reference), _marker: PhantomData } + Unique { pointer: NonZero(reference as _), _marker: PhantomData } } } @@ -2476,19 +2480,23 @@ impl NonNull { /// `ptr` must be non-null. #[stable(feature = "nonnull", since = "1.25.0")] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { - NonNull { pointer: NonZero::new_unchecked(ptr) } + NonNull { pointer: NonZero(ptr as _) } } /// Creates a new `NonNull` if `ptr` is non-null. #[stable(feature = "nonnull", since = "1.25.0")] pub fn new(ptr: *mut T) -> Option { - NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz }) + if !ptr.is_null() { + Some(NonNull { pointer: NonZero(ptr as _) }) + } else { + None + } } /// Acquires the underlying `*mut` pointer. #[stable(feature = "nonnull", since = "1.25.0")] pub fn as_ptr(self) -> *mut T { - self.pointer.get() as *mut T + self.pointer.0 as *mut T } /// Dereferences the content. @@ -2589,7 +2597,7 @@ impl From> for NonNull { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { - NonNull { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero(reference as _) } } } @@ -2597,6 +2605,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { - NonNull { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero(reference as _) } } } From 7cf1f18cb9209156108e3871e11cb5d63f7f1cf1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 19:28:13 +0100 Subject: [PATCH 350/830] Test NonZero in a const item in a pattern. (This was buggy before https://github.com/rust-lang/rust/pull/46882) --- src/libcore/tests/nonzero.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index 9eaf7529dd3c..8d39298bac3d 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -98,3 +98,26 @@ fn test_match_option_string() { None => panic!("unexpected None while matching on Some(String { ... })") } } + +mod atom { + use core::num::NonZeroU32; + + #[derive(PartialEq, Eq)] + pub struct Atom { + index: NonZeroU32, // private + } + pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZeroU32::new_unchecked(7) } }; +} + +macro_rules! atom { + ("foo") => { atom::FOO_ATOM } +} + +#[test] +fn test_match_nonzero_const_pattern() { + match atom!("foo") { + // Using as a pattern is supported by the compiler: + atom!("foo") => {} + _ => panic!("Expected the const item as a pattern to match.") + } +} From b4981923a05869ea2c50f1893acf433b1b67f79a Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 17 Mar 2018 15:34:12 -0700 Subject: [PATCH 351/830] Add a -Z flag for LLVM align attributes on arguments LLVM seems to still put the assume calls in when inlining, so this probably isn't in a place where it can be turned on by default, but it's interesting to experiment with. For example, this makes `swap::` be 8x `vmovaps ymm` instead of 16x `vmovups xmm`, on my cpu. --- src/librustc/session/config.rs | 2 ++ src/librustc_trans/abi.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 1c5cfa87ef46..a5eae35c5567 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1208,6 +1208,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "set the MIR optimization level (0-3, default: 1)"), mutable_noalias: bool = (false, parse_bool, [UNTRACKED], "emit noalias metadata for mutable references"), + arg_align_attributes: bool = (false, parse_bool, [UNTRACKED], + "emit align metadata for reference arguments"), dump_mir: Option = (None, parse_opt_string, [UNTRACKED], "dump MIR state at various points in translation"), dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED], diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index ee0f2415bd80..c8c914776698 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -778,7 +778,7 @@ impl<'a, 'tcx> FnType<'tcx> { // HACK(eddyb) LLVM inserts `llvm.assume` calls when inlining functions // with align attributes, and those calls later block optimizations. - if !is_return { + if !is_return && !cx.tcx.sess.opts.debugging_opts.arg_align_attributes { attrs.pointee_align = None; } From 73c053786dde55059932b9ebcd4a40edf89eae15 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 8 Mar 2018 16:55:51 +0100 Subject: [PATCH 352/830] Remove deprecated unstable ptr::Shared type alias. It has been deprecated for about one release cycle. --- src/libcore/cell.rs | 5 ++--- src/libcore/ptr.rs | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 36618e86968b..c8ee166fee3e 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -146,13 +146,12 @@ //! //! ``` //! #![feature(core_intrinsics)] -//! #![feature(shared)] //! use std::cell::Cell; -//! use std::ptr::Shared; +//! use std::ptr::NonNull; //! use std::intrinsics::abort; //! //! struct Rc { -//! ptr: Shared> +//! ptr: NonNull> //! } //! //! struct RcBox { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 4ab0ceb79677..cebd5989e96c 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2420,11 +2420,6 @@ impl<'a, T: ?Sized> From> for Unique { } } -/// Previous name of `NonNull`. -#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")] -#[unstable(feature = "shared", issue = "27730")] -pub type Shared = NonNull; - /// `*mut T` but non-zero and covariant. /// /// This is often the correct thing to use when building data structures using From 1e73c1d39f0734d2ae687b9cad5f5bde2f96d0b8 Mon Sep 17 00:00:00 2001 From: Maxim Nazarenko Date: Sun, 18 Mar 2018 03:05:00 +0200 Subject: [PATCH 353/830] rustbuild: Ship libsynchronization Ship libsynchronization from MinGW --- src/bootstrap/dist.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index dcb572416594..eca06eac7f30 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -221,6 +221,7 @@ fn make_win_dist( "libsecur32.a", "libsetupapi.a", "libshell32.a", + "libsynchronization.a", "libuser32.a", "libuserenv.a", "libuuid.a", From 13d94d666e037162808174f0bedbd5db9d65c7fe Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Sun, 18 Mar 2018 13:05:00 +0100 Subject: [PATCH 354/830] Fix formatting. --- src/libcore/borrow.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index 7470512e2b2d..f45a32d4b94a 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -55,7 +55,6 @@ /// [`String`]: ../../std/string/struct.String.html /// [`borrow`]: #tymethod.borrow /// -/// /// # Examples /// /// As a data collection, [`HashMap`] owns both keys and values. If @@ -163,7 +162,6 @@ /// [`HashMap`]: ../../std/collections/struct.HashMap.html /// [`String`]: ../../std/string/struct.String.html /// [`str`]: ../../std/primitive.str.html -/// #[stable(feature = "rust1", since = "1.0.0")] pub trait Borrow { /// Immutably borrows from an owned value. From 55116243e708201918f4f8bc20182754b00f32fa Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Thu, 15 Mar 2018 18:39:44 +0800 Subject: [PATCH 355/830] remove unneeded where clause --- src/librustc_mir/util/borrowck_errors.rs | 40 +++--------------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index bcd7a3e7cd34..5e15348de5e7 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -52,19 +52,17 @@ impl Origin { } } -pub trait BorrowckErrors<'cx> { +pub trait BorrowckErrors<'cx>: Sized + Copy { fn struct_span_err_with_code>(self, sp: S, msg: &str, code: DiagnosticId) - -> DiagnosticBuilder<'cx> - where Self: Sized + Copy; + -> DiagnosticBuilder<'cx>; fn struct_span_err>(self, sp: S, msg: &str) - -> DiagnosticBuilder<'cx> - where Self: Sized + Copy; + -> DiagnosticBuilder<'cx>; /// Cancels the given error if we shouldn't emit errors for a given /// origin in the current mode. @@ -74,12 +72,10 @@ pub trait BorrowckErrors<'cx> { fn cancel_if_wrong_origin(self, diag: DiagnosticBuilder<'cx>, o: Origin) - -> DiagnosticBuilder<'cx> - where Self: Sized + Copy; + -> DiagnosticBuilder<'cx>; fn cannot_move_when_borrowed(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0505, "cannot move out of `{}` because it is borrowed{OGN}", @@ -94,7 +90,6 @@ pub trait BorrowckErrors<'cx> { borrow_desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0503, "cannot use `{}` because it was mutably borrowed{OGN}", @@ -112,7 +107,6 @@ pub trait BorrowckErrors<'cx> { desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0381, "{} of possibly uninitialized variable: `{}`{OGN}", @@ -129,7 +123,6 @@ pub trait BorrowckErrors<'cx> { old_load_end_span: Option, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0499, "cannot borrow `{}`{} as mutable more than once at a time{OGN}", @@ -162,7 +155,6 @@ pub trait BorrowckErrors<'cx> { old_load_end_span: Option, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0524, "two closures require unique access to `{}` at the same time{OGN}", @@ -191,7 +183,6 @@ pub trait BorrowckErrors<'cx> { previous_end_span: Option, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0500, "closure requires unique access to `{}` but {} is already borrowed{}{OGN}", @@ -216,7 +207,6 @@ pub trait BorrowckErrors<'cx> { previous_end_span: Option, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, new_loan_span, E0501, "cannot borrow `{}`{} as {} because previous closure \ @@ -244,7 +234,6 @@ pub trait BorrowckErrors<'cx> { old_load_end_span: Option, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0502, "cannot borrow `{}`{} as {} because {} is also borrowed as {}{}{OGN}", @@ -259,7 +248,6 @@ pub trait BorrowckErrors<'cx> { fn cannot_assign_to_borrowed(self, span: Span, borrow_span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0506, "cannot assign to `{}` because it is borrowed{OGN}", @@ -273,7 +261,6 @@ pub trait BorrowckErrors<'cx> { fn cannot_move_into_closure(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0504, "cannot move `{}` into closure because it is borrowed{OGN}", @@ -284,7 +271,6 @@ pub trait BorrowckErrors<'cx> { fn cannot_reassign_immutable(self, span: Span, desc: &str, is_arg: bool, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let msg = if is_arg { "to immutable argument" @@ -299,7 +285,6 @@ pub trait BorrowckErrors<'cx> { } fn cannot_assign(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0594, "cannot assign to {}{OGN}", @@ -309,14 +294,12 @@ pub trait BorrowckErrors<'cx> { fn cannot_assign_static(self, span: Span, desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { self.cannot_assign(span, &format!("immutable static item `{}`", desc), o) } fn cannot_move_out_of(self, move_from_span: Span, move_from_desc: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, move_from_span, E0507, "cannot move out of {}{OGN}", @@ -334,7 +317,6 @@ pub trait BorrowckErrors<'cx> { is_index: bool, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let type_name = match (&ty.sty, is_index) { (&ty::TyArray(_, _), true) => "array", @@ -355,7 +337,6 @@ pub trait BorrowckErrors<'cx> { container_ty: ty::Ty, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, move_from_span, E0509, "cannot move out of type `{}`, \ @@ -373,7 +354,6 @@ pub trait BorrowckErrors<'cx> { moved_path: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, use_span, E0382, "{} of {}moved value: `{}`{OGN}", @@ -387,7 +367,6 @@ pub trait BorrowckErrors<'cx> { uninit_path: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, @@ -403,7 +382,6 @@ pub trait BorrowckErrors<'cx> { descr: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0595, "closure cannot assign to {}{OGN}", descr, OGN=o); @@ -416,7 +394,6 @@ pub trait BorrowckErrors<'cx> { path: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0596, "cannot borrow {} as mutable{OGN}", path, OGN=o); @@ -429,7 +406,6 @@ pub trait BorrowckErrors<'cx> { yield_span: Span, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, span, @@ -446,7 +422,6 @@ pub trait BorrowckErrors<'cx> { path: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0597, "{} does not live long enough{OGN}", path, OGN=o); @@ -459,7 +434,6 @@ pub trait BorrowckErrors<'cx> { path: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let err = struct_span_err!(self, span, E0598, "lifetime of {} is too short to guarantee \ @@ -475,7 +449,6 @@ pub trait BorrowckErrors<'cx> { help: (Span, &str), o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let (help_span, help_msg) = help; let mut err = struct_span_err!(self, span, E0387, @@ -491,7 +464,6 @@ pub trait BorrowckErrors<'cx> { bad_thing: &str, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, span, E0389, "{} in a `&` reference{OGN}", bad_thing, OGN=o); @@ -506,7 +478,6 @@ pub trait BorrowckErrors<'cx> { capture_span: Span, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { let mut err = struct_span_err!(self, closure_span, E0373, "closure may outlive the current function, \ @@ -526,7 +497,6 @@ impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> { msg: &str, code: DiagnosticId) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { self.sess.struct_span_err_with_code(sp, msg, code) } @@ -535,7 +505,6 @@ impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> { sp: S, msg: &str) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { self.sess.struct_span_err(sp, msg) } @@ -544,7 +513,6 @@ impl<'cx, 'gcx, 'tcx> BorrowckErrors<'cx> for TyCtxt<'cx, 'gcx, 'tcx> { mut diag: DiagnosticBuilder<'cx>, o: Origin) -> DiagnosticBuilder<'cx> - where Self: Sized + Copy { if !o.should_emit_errors(self.borrowck_mode()) { self.sess.diagnostic().cancel(&mut diag); From 5904543234e29fe4a69c67b5dc2dd6b799668e78 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Sun, 18 Mar 2018 13:29:57 +0100 Subject: [PATCH 356/830] Update clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 6f3f25878f22..4edd140e57cc 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 6f3f25878f2271911e4b6de4d0cf86accc397455 +Subproject commit 4edd140e57cce900fa930e1439bab469f5bbce46 From 9896b38f01c068abfe7170cb9ae2bfadb4aebbc4 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 17 Mar 2018 20:43:46 +0000 Subject: [PATCH 357/830] Clarify time complexity --- src/liballoc/lib.rs | 1 - src/liballoc/slice.rs | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 253b8acc16c4..b93e128d5081 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -113,7 +113,6 @@ #![feature(slice_get_slice)] #![feature(slice_patterns)] #![feature(slice_rsplit)] -#![feature(slice_sort_by_cached_key)] #![feature(specialization)] #![feature(staged_api)] #![feature(str_internals)] diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index bef50a733cc7..cd212aa15bae 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1303,7 +1303,7 @@ impl [T] { /// Sorts the slice with a key extraction function. /// - /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log m n)` + /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log(m n))` /// worst-case, where the key function is `O(m)`. /// /// For expensive key functions (e.g. functions that are not simple property accesses or @@ -1365,6 +1365,7 @@ impl [T] { /// # Examples /// /// ``` + /// #![feature(slice_sort_by_cached_key)] /// let mut v = [-5i32, 4, 32, -3, 2]; /// /// v.sort_by_cached_key(|k| k.to_string()); @@ -1480,7 +1481,7 @@ impl [T] { /// elements. /// /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), - /// and `O(m n log m n)` worst-case, where the key function is `O(m)`. + /// and `O(m n log(m n))` worst-case, where the key function is `O(m)`. /// /// # Current implementation /// From 81edd1796b463776d111cd4fe48e866dd716dfab Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 18 Mar 2018 11:11:17 +0000 Subject: [PATCH 358/830] Check that the size optimisation is not redundant --- src/liballoc/slice.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index cd212aa15bae..2b4ce9fe49c8 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1384,8 +1384,8 @@ impl [T] { let mut indices: Vec<_> = $slice.iter().map($f).enumerate().map(|(i, k)| (k, i as $t)).collect(); // The elements of `indices` are unique, as they are indexed, so any sort will be - // stable with respect to the original slice. We use `sort_unstable` here because it - // requires less memory allocation. + // stable with respect to the original slice. We use `sort_unstable` here because + // it requires less memory allocation. indices.sort_unstable(); for i in 0..$slice.len() { let mut index = indices[i].1; @@ -1398,10 +1398,15 @@ impl [T] { }) } + let sz_u8 = mem::size_of::<(K, u8)>(); + let sz_u16 = mem::size_of::<(K, u16)>(); + let sz_u32 = mem::size_of::<(K, u32)>(); + let sz_usize = mem::size_of::<(K, usize)>(); + let len = self.len(); - if len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) } - if len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) } - if len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) } + if sz_u8 < sz_u16 && len <= ( u8::MAX as usize) { return sort_by_key!( u8, self, f) } + if sz_u16 < sz_u32 && len <= (u16::MAX as usize) { return sort_by_key!(u16, self, f) } + if sz_u32 < sz_usize && len <= (u32::MAX as usize) { return sort_by_key!(u32, self, f) } sort_by_key!(usize, self, f) } From 785e3c38fe6c49e39aec145c81e463ceb60d179e Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 18 Mar 2018 12:37:06 +0000 Subject: [PATCH 359/830] Add lexicographic sorting benchmark --- src/liballoc/benches/lib.rs | 1 + src/liballoc/benches/slice.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs index 2de0ffb4b261..9cb5f558574c 100644 --- a/src/liballoc/benches/lib.rs +++ b/src/liballoc/benches/lib.rs @@ -13,6 +13,7 @@ #![feature(i128_type)] #![feature(rand)] #![feature(repr_simd)] +#![feature(slice_sort_by_cached_key)] #![feature(test)] extern crate rand; diff --git a/src/liballoc/benches/slice.rs b/src/liballoc/benches/slice.rs index ee5182a1d466..a699ff9c0a76 100644 --- a/src/liballoc/benches/slice.rs +++ b/src/liballoc/benches/slice.rs @@ -284,6 +284,17 @@ macro_rules! sort_expensive { } } +macro_rules! sort_lexicographic { + ($f:ident, $name:ident, $gen:expr, $len:expr) => { + #[bench] + fn $name(b: &mut Bencher) { + let v = $gen($len); + b.iter(|| v.clone().$f(|x| x.to_string())); + b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64; + } + } +} + sort!(sort, sort_small_ascending, gen_ascending, 10); sort!(sort, sort_small_descending, gen_descending, 10); sort!(sort, sort_small_random, gen_random, 10); @@ -312,6 +323,10 @@ sort!(sort_unstable, sort_unstable_large_big, gen_big_random, 10000); sort_strings!(sort_unstable, sort_unstable_large_strings, gen_strings, 10000); sort_expensive!(sort_unstable_by, sort_unstable_large_expensive, gen_random, 10000); +sort_lexicographic!(sort_by_key, sort_by_key_lexicographic, gen_random, 10000); +sort_lexicographic!(sort_unstable_by_key, sort_unstable_by_key_lexicographic, gen_random, 10000); +sort_lexicographic!(sort_by_cached_key, sort_by_cached_key_lexicographic, gen_random, 10000); + macro_rules! reverse { ($name:ident, $ty:ty, $f:expr) => { #[bench] From e85c9227c2e913b71f0d7b6cc2322d7897f28554 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 27 Feb 2018 16:51:12 +0900 Subject: [PATCH 360/830] rustc_driver: get rid of extra thread on Unix --- src/librustc_driver/lib.rs | 51 +++++++++++++++++++++++----- src/libstd/sys_common/thread_info.rs | 4 +++ src/libstd/thread/mod.rs | 8 +++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f1f3a0519bbc..8605764497a1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -24,6 +24,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(set_stdio)] +#![feature(rustc_stack_internals)] extern crate arena; extern crate getopts; @@ -1461,16 +1462,50 @@ pub fn in_rustc_thread(f: F) -> Result> // Temporarily have stack size set to 16MB to deal with nom-using crates failing const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB - let mut cfg = thread::Builder::new().name("rustc".to_string()); + #[cfg(unix)] + let spawn_thread = unsafe { + // Fetch the current resource limits + let mut rlim = libc::rlimit { + rlim_cur: 0, + rlim_max: 0, + }; + if libc::getrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { + let err = io::Error::last_os_error(); + error!("in_rustc_thread: error calling getrlimit: {}", err); + true + } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t { + true + } else { + rlim.rlim_cur = STACK_SIZE as libc::rlim_t; + if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { + let err = io::Error::last_os_error(); + error!("in_rustc_thread: error calling setrlimit: {}", err); + true + } else { + std::thread::update_stack_guard(); + false + } + } + }; - // FIXME: Hacks on hacks. If the env is trying to override the stack size - // then *don't* set it explicitly. - if env::var_os("RUST_MIN_STACK").is_none() { - cfg = cfg.stack_size(STACK_SIZE); + #[cfg(not(unix))] + let spawn_thread = true; + + // The or condition is added from backward compatibility. + if spawn_thread || env::var_os("RUST_MIN_STACK").is_some() { + let mut cfg = thread::Builder::new().name("rustc".to_string()); + + // FIXME: Hacks on hacks. If the env is trying to override the stack size + // then *don't* set it explicitly. + if env::var_os("RUST_MIN_STACK").is_none() { + cfg = cfg.stack_size(STACK_SIZE); + } + + let thread = cfg.spawn(f); + thread.unwrap().join() + } else { + Ok(f()) } - - let thread = cfg.spawn(f); - thread.unwrap().join() } /// Get a list of extra command-line flags provided by the user, as strings. diff --git a/src/libstd/sys_common/thread_info.rs b/src/libstd/sys_common/thread_info.rs index 6a2b6742367a..d75cbded7347 100644 --- a/src/libstd/sys_common/thread_info.rs +++ b/src/libstd/sys_common/thread_info.rs @@ -50,3 +50,7 @@ pub fn set(stack_guard: Option, thread: Thread) { thread, })); } + +pub fn reset_guard(stack_guard: Option) { + THREAD_INFO.with(move |c| c.borrow_mut().as_mut().unwrap().stack_guard = stack_guard); +} diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 71aee673cfe3..b686ddc205ea 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -208,6 +208,14 @@ pub use self::local::{LocalKey, AccessError}; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner; +/// Function used for resetting the main stack guard address after setrlimit(). +/// This is POSIX specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn update_stack_guard() { + let main_guard = imp::guard::init(); + thread_info::reset_guard(main_guard); +} + //////////////////////////////////////////////////////////////////////////////// // Builder //////////////////////////////////////////////////////////////////////////////// From 1bb89f1b3cf1e4b5fa83391872136251c0030c1e Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 6 Mar 2018 13:33:36 +0900 Subject: [PATCH 361/830] rustc_driver: get rid of extra thread on Windows --- src/librustc_driver/lib.rs | 6 +++++- src/rustc/rustc.rs | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8605764497a1..761797239412 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1488,7 +1488,11 @@ pub fn in_rustc_thread(f: F) -> Result> } }; - #[cfg(not(unix))] + // We set the stack size at link time. See src/rustc/rustc.rs. + #[cfg(windows)] + let spawn_thread = false; + + #[cfg(not(any(windows,unix)))] let spawn_thread = true; // The or condition is added from backward compatibility. diff --git a/src/rustc/rustc.rs b/src/rustc/rustc.rs index bfd01146d2c4..bd36aaf01f86 100644 --- a/src/rustc/rustc.rs +++ b/src/rustc/rustc.rs @@ -9,6 +9,15 @@ // except according to those terms. #![feature(rustc_private)] +#![feature(link_args)] + +// Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread +// for the rationale. +#[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")] +// We only build for msvc and gnu now, but we use a exhaustive condition here +// so we can expect either the stack size to be set or the build fails. +#[cfg_attr(all(windows, not(target_env = "msvc")), link_args = "-Wl,--stack,16777216")] +extern {} extern crate rustc_driver; From 8501e950231a98b4b4a6a9eabfe8f5bb5e438937 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 18 Mar 2018 22:26:57 +0800 Subject: [PATCH 362/830] Update RLS. --- src/tools/rls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rls b/src/tools/rls index fc4db0a5e99e..567fb6d74cca 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit fc4db0a5e99e426fd97de370c6f36f585b6af13a +Subproject commit 567fb6d74cca9ccbfae2440c688035400b51e3c6 From fad1648e0f8299a8b108f85c2b1055eb37bdab9e Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Fri, 9 Mar 2018 23:56:40 -0600 Subject: [PATCH 363/830] Initial implementation of RFC 2151, Raw Identifiers --- src/libproc_macro/lib.rs | 11 +- src/librustc/ich/impls_syntax.rs | 5 +- src/librustc_passes/ast_validation.rs | 4 +- src/librustc_resolve/lib.rs | 2 +- src/librustc_resolve/macros.rs | 2 +- src/librustc_resolve/resolve_imports.rs | 4 +- src/librustdoc/html/highlight.rs | 8 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/attr.rs | 13 ++- src/libsyntax/diagnostics/plugin.rs | 10 +- src/libsyntax/ext/base.rs | 5 +- src/libsyntax/ext/quote.rs | 11 +- src/libsyntax/ext/tt/macro_parser.rs | 19 +-- src/libsyntax/ext/tt/macro_rules.rs | 6 +- src/libsyntax/ext/tt/quoted.rs | 2 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/fold.rs | 5 +- src/libsyntax/parse/lexer/mod.rs | 69 +++++++---- src/libsyntax/parse/mod.rs | 20 ++-- src/libsyntax/parse/parser.rs | 29 +++-- src/libsyntax/parse/token.rs | 108 +++++++++++++----- src/libsyntax/print/pprust.rs | 40 ++++--- src/libsyntax/tokenstream.rs | 2 +- src/libsyntax_ext/concat_idents.rs | 3 +- src/libsyntax_ext/format.rs | 2 +- src/test/parse-fail/raw-str-delim.rs | 2 +- .../auxiliary/roman_numerals.rs | 2 +- .../run-pass/rfc-2151-raw-identifiers/attr.rs | 24 ++++ .../rfc-2151-raw-identifiers/basic.rs | 29 +++++ .../rfc-2151-raw-identifiers/items.rs | 41 +++++++ .../rfc-2151-raw-identifiers/macros.rs | 47 ++++++++ src/test/ui/raw-literal-keywords.rs | 25 ++++ src/test/ui/raw-literal-keywords.stderr | 20 ++++ src/test/ui/raw-literal-self.rs | 15 +++ src/test/ui/raw-literal-self.stderr | 8 ++ src/test/ui/raw-literal-underscore.rs | 15 +++ src/test/ui/raw-literal-underscore.stderr | 8 ++ 37 files changed, 475 insertions(+), 145 deletions(-) create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/attr.rs create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/basic.rs create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/items.rs create mode 100644 src/test/run-pass/rfc-2151-raw-identifiers/macros.rs create mode 100644 src/test/ui/raw-literal-keywords.rs create mode 100644 src/test/ui/raw-literal-keywords.stderr create mode 100644 src/test/ui/raw-literal-self.rs create mode 100644 src/test/ui/raw-literal-self.stderr create mode 100644 src/test/ui/raw-literal-underscore.rs create mode 100644 src/test/ui/raw-literal-underscore.stderr diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index b239f8018beb..d6e679bad48b 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -681,7 +681,8 @@ impl TokenTree { Dollar => op!('$'), Question => op!('?'), - Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), + Ident(ident, false) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), + Ident(ident, true) => TokenNode::Term(Term(Symbol::intern(&format!("r#{}", ident)))), Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)), Interpolated(_) => { @@ -713,8 +714,14 @@ impl TokenTree { }, TokenNode::Term(symbol) => { let ident = ast::Ident { name: symbol.0, ctxt: self.span.0.ctxt() }; + let sym_str = symbol.0.as_str(); let token = - if symbol.0.as_str().starts_with("'") { Lifetime(ident) } else { Ident(ident) }; + if sym_str.starts_with("'") { Lifetime(ident) } + else if sym_str.starts_with("r#") { + let name = Symbol::intern(&sym_str[2..]); + let ident = ast::Ident { name, ctxt: self.span.0.ctxt() }; + Ident(ident, true) + } else { Ident(ident, false) }; return TokenTree::Token(self.span.0, token).into(); } TokenNode::Literal(token) => return TokenTree::Token(self.span.0, token.0).into(), diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 513b6c835f98..0b037964981c 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -318,7 +318,10 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>( opt_name.hash_stable(hcx, hasher); } - token::Token::Ident(ident) | + token::Token::Ident(ident, is_raw) => { + ident.name.hash_stable(hcx, hasher); + is_raw.hash_stable(hcx, hasher); + } token::Token::Lifetime(ident) => ident.name.hash_stable(hcx, hasher), token::Token::Interpolated(_) => { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 4215bf306a4f..3c33d29585a8 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -41,13 +41,13 @@ impl<'a> AstValidator<'a> { keywords::StaticLifetime.name(), keywords::Invalid.name()]; if !valid_names.contains(&lifetime.ident.name) && - token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() { + token::is_reserved_ident(lifetime.ident.without_first_quote()) { self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names"); } } fn check_label(&self, label: Ident, span: Span) { - if token::Ident(label.without_first_quote()).is_reserved_ident() { + if token::is_reserved_ident(label.without_first_quote()) { self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name)); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index dc22c23271d6..2cb2c76c6320 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3206,7 +3206,7 @@ impl<'a> Resolver<'a> { // `$crate::a::b` module = Some(self.resolve_crate_root(ident.node.ctxt, true)); continue - } else if i == 1 && !token::Ident(ident.node).is_path_segment_keyword() { + } else if i == 1 && !token::is_path_segment_keyword(ident.node) { let prev_name = path[0].node.name; if prev_name == keywords::Extern.name() || prev_name == keywords::CrateRoot.name() && diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 95fa0f3b52fe..0692a1e0d7f8 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -268,7 +268,7 @@ impl<'a> base::Resolver for Resolver<'a> { if k > 0 { tokens.push(TokenTree::Token(path.span, Token::ModSep).into()); } - let tok = Token::Ident(segment.identifier); + let tok = Token::from_ast_ident(segment.identifier); tokens.push(TokenTree::Token(path.span, tok).into()); } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 4cbebdc3c1c3..78d2357e02b6 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -625,7 +625,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } else { Some(self.resolve_crate_root(source.ctxt.modern(), false)) } - } else if is_extern && !token::Ident(source).is_path_segment_keyword() { + } else if is_extern && !token::is_path_segment_keyword(source) { let crate_id = self.crate_loader.resolve_crate_from_path(source.name, directive.span); let crate_root = @@ -667,7 +667,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { } PathResult::Failed(span, msg, true) => { let (mut self_path, mut self_result) = (module_path.clone(), None); - let is_special = |ident| token::Ident(ident).is_path_segment_keyword() && + let is_special = |ident| token::is_path_segment_keyword(ident) && ident.name != keywords::CrateRoot.name(); if !self_path.is_empty() && !is_special(self_path[0].node) && !(self_path.len() > 1 && is_special(self_path[1].node)) { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 659ec8a993dc..cfa3f5a4e0b4 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -323,12 +323,12 @@ impl<'a> Classifier<'a> { } // Keywords are also included in the identifier set. - token::Ident(ident) => { + token::Ident(ident, is_raw) => { match &*ident.name.as_str() { - "ref" | "mut" => Class::RefKeyWord, + "ref" | "mut" if !is_raw => Class::RefKeyWord, - "self" |"Self" => Class::Self_, - "false" | "true" => Class::Bool, + "self" | "Self" => Class::Self_, + "false" | "true" if !is_raw => Class::Bool, "Option" | "Result" => Class::PreludeTy, "Some" | "None" | "Ok" | "Err" => Class::PreludeVal, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 1f16b728cd23..a3af6b247ee2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -112,7 +112,7 @@ impl Path { // or starts with something like `self`/`super`/`$crate`/etc. pub fn make_root(&self) -> Option { if let Some(ident) = self.segments.get(0).map(|seg| seg.identifier) { - if ::parse::token::Ident(ident).is_path_segment_keyword() && + if ::parse::token::is_path_segment_keyword(ident) && ident.name != keywords::Crate.name() { return None; } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index f2cdcda98da5..5954b9eb2747 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -1106,7 +1106,8 @@ impl IntType { impl MetaItem { fn tokens(&self) -> TokenStream { - let ident = TokenTree::Token(self.span, Token::Ident(Ident::with_empty_ctxt(self.name))); + let ident = TokenTree::Token(self.span, + Token::from_ast_ident(Ident::with_empty_ctxt(self.name))); TokenStream::concat(vec![ident.into(), self.node.tokens(self.span)]) } @@ -1114,9 +1115,9 @@ impl MetaItem { where I: Iterator, { let (span, name) = match tokens.next() { - Some(TokenTree::Token(span, Token::Ident(ident))) => (span, ident.name), + Some(TokenTree::Token(span, Token::Ident(ident, _))) => (span, ident.name), Some(TokenTree::Token(_, Token::Interpolated(ref nt))) => match nt.0 { - token::Nonterminal::NtIdent(ident) => (ident.span, ident.node.name), + token::Nonterminal::NtIdent(ident, _) => (ident.span, ident.node.name), token::Nonterminal::NtMeta(ref meta) => return Some(meta.clone()), _ => return None, }, @@ -1269,14 +1270,14 @@ impl LitKind { "true" } else { "false" - }))), + })), false), } } fn from_token(token: Token) -> Option { match token { - Token::Ident(ident) if ident.name == "true" => Some(LitKind::Bool(true)), - Token::Ident(ident) if ident.name == "false" => Some(LitKind::Bool(false)), + Token::Ident(ident, false) if ident.name == "true" => Some(LitKind::Bool(true)), + Token::Ident(ident, false) if ident.name == "false" => Some(LitKind::Bool(false)), Token::Interpolated(ref nt) => match nt.0 { token::NtExpr(ref v) => match v.node { ExprKind::Lit(ref lit) => Some(lit.node.clone()), diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 2c91844da96d..c7e453c9e105 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -44,7 +44,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, token_tree: &[TokenTree]) -> Box { let code = match (token_tree.len(), token_tree.get(0)) { - (1, Some(&TokenTree::Token(_, token::Ident(code)))) => code, + (1, Some(&TokenTree::Token(_, token::Ident(code, false)))) => code, _ => unreachable!() }; @@ -82,10 +82,10 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, token_tree.get(1), token_tree.get(2) ) { - (1, Some(&TokenTree::Token(_, token::Ident(ref code))), None, None) => { + (1, Some(&TokenTree::Token(_, token::Ident(ref code, false))), None, None) => { (code, None) }, - (3, Some(&TokenTree::Token(_, token::Ident(ref code))), + (3, Some(&TokenTree::Token(_, token::Ident(ref code, false))), Some(&TokenTree::Token(_, token::Comma)), Some(&TokenTree::Token(_, token::Literal(token::StrRaw(description, _), None)))) => { (code, Some(description)) @@ -150,9 +150,9 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, let (crate_name, name) = match (&token_tree[0], &token_tree[2]) { ( // Crate name. - &TokenTree::Token(_, token::Ident(ref crate_name)), + &TokenTree::Token(_, token::Ident(ref crate_name, false)), // DIAGNOSTICS ident. - &TokenTree::Token(_, token::Ident(ref name)) + &TokenTree::Token(_, token::Ident(ref name, false)) ) => (*&crate_name, name), _ => unreachable!() }; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 23c42972912a..c3ae0fd2ca86 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -229,8 +229,9 @@ impl TTMacroExpander for F impl Folder for AvoidInterpolatedIdents { fn fold_tt(&mut self, tt: tokenstream::TokenTree) -> tokenstream::TokenTree { if let tokenstream::TokenTree::Token(_, token::Interpolated(ref nt)) = tt { - if let token::NtIdent(ident) = nt.0 { - return tokenstream::TokenTree::Token(ident.span, token::Ident(ident.node)); + if let token::NtIdent(ident, is_raw) = nt.0 { + return tokenstream::TokenTree::Token(ident.span, + token::Ident(ident.node, is_raw)); } } fold::noop_fold_tt(tt, self) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 6844532e7b37..090b9a354463 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -75,7 +75,7 @@ pub mod rt { impl ToTokens for ast::Ident { fn to_tokens(&self, _cx: &ExtCtxt) -> Vec { - vec![TokenTree::Token(DUMMY_SP, token::Ident(*self))] + vec![TokenTree::Token(DUMMY_SP, Token::from_ast_ident(*self))] } } @@ -238,7 +238,8 @@ pub mod rt { if i > 0 { inner.push(TokenTree::Token(self.span, token::Colon).into()); } - inner.push(TokenTree::Token(self.span, token::Ident(segment.identifier)).into()); + inner.push(TokenTree::Token(self.span, + token::Ident(segment.identifier, false)).into()); } inner.push(self.tokens.clone()); @@ -658,10 +659,10 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { 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) => { + token::Ident(ident, is_raw) => { return cx.expr_call(sp, mk_token_path(cx, sp, "Ident"), - vec![mk_ident(cx, sp, ident)]); + vec![mk_ident(cx, sp, ident), cx.expr_bool(sp, is_raw)]); } token::Lifetime(ident) => { @@ -720,7 +721,7 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P { fn statements_mk_tt(cx: &ExtCtxt, tt: &TokenTree, quoted: bool) -> Vec { match *tt { - TokenTree::Token(sp, token::Ident(ident)) if quoted => { + TokenTree::Token(sp, token::Ident(ident, _)) if quoted => { // tt.extend($ident.to_tokens(ext_cx)) let e_to_toks = diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 667653b5f7f2..714b7ca981da 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -365,7 +365,7 @@ 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 { if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) { - id1.name == id2.name + id1.name == id2.name && t1.is_raw_ident() == t2.is_raw_ident() } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { id1.name == id2.name } else { @@ -711,9 +711,10 @@ pub fn parse( /// The token is an identifier, but not `_`. /// We prohibit passing `_` to macros expecting `ident` for now. -fn get_macro_ident(token: &Token) -> Option { +fn get_macro_ident(token: &Token) -> Option<(Ident, bool)> { match *token { - token::Ident(ident) if ident.name != keywords::Underscore.name() => Some(ident), + token::Ident(ident, is_raw) if ident.name != keywords::Underscore.name() => + Some((ident, is_raw)), _ => None, } } @@ -737,7 +738,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { "ident" => get_macro_ident(token).is_some(), "vis" => match *token { // The follow-set of :vis + "priv" keyword + interpolated - Token::Comma | Token::Ident(_) | Token::Interpolated(_) => true, + Token::Comma | Token::Ident(..) | Token::Interpolated(_) => true, _ => token.can_begin_type(), }, "block" => match *token { @@ -746,7 +747,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { token::NtItem(_) | token::NtPat(_) | token::NtTy(_) - | token::NtIdent(_) + | token::NtIdent(..) | token::NtMeta(_) | token::NtPath(_) | token::NtVis(_) => false, // none of these may start with '{'. @@ -755,7 +756,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { _ => false, }, "path" | "meta" => match *token { - Token::ModSep | Token::Ident(_) => true, + Token::ModSep | Token::Ident(..) => true, Token::Interpolated(ref nt) => match nt.0 { token::NtPath(_) | token::NtMeta(_) => true, _ => may_be_ident(&nt.0), @@ -763,7 +764,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { _ => false, }, "pat" => match *token { - Token::Ident(_) | // box, ref, mut, and other identifiers (can stricten) + Token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) Token::OpenDelim(token::Paren) | // tuple pattern Token::OpenDelim(token::Bracket) | // slice pattern Token::BinOp(token::And) | // reference @@ -823,9 +824,9 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { "expr" => token::NtExpr(panictry!(p.parse_expr())), "ty" => token::NtTy(panictry!(p.parse_ty())), // this could be handled like a token, since it is one - "ident" => if let Some(ident) = get_macro_ident(&p.token) { + "ident" => if let Some((ident, is_raw)) = get_macro_ident(&p.token) { p.bump(); - token::NtIdent(respan(p.prev_span, ident)) + token::NtIdent(respan(p.prev_span, ident), is_raw) } else { let token_str = pprust::token_to_string(&p.token); p.fatal(&format!("expected ident, found {}", &token_str)).emit(); diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index a4b2c3990f5e..10e5926eb9e3 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -831,7 +831,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result match *tok { TokenTree::Token(_, ref tok) => match *tok { FatArrow | Comma | Eq | BinOp(token::Or) => Ok(true), - Ident(i) if i.name == "if" || i.name == "in" => Ok(true), + Ident(i, false) if i.name == "if" || i.name == "in" => Ok(true), _ => Ok(false) }, _ => Ok(false), @@ -840,7 +840,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result match *tok { OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) | Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true), - Ident(i) if i.name == "as" || i.name == "where" => Ok(true), + Ident(i, false) if i.name == "as" || i.name == "where" => Ok(true), _ => Ok(false) }, TokenTree::MetaVarDecl(_, _, frag) if frag.name == "block" => Ok(true), @@ -860,7 +860,7 @@ fn is_in_follow(tok: "ed::TokenTree, frag: &str) -> Result match *tok { Comma => Ok(true), - Ident(i) if i.name != "priv" => Ok(true), + Ident(i, is_raw) if is_raw || i.name != "priv" => Ok(true), ref tok => Ok(tok.can_begin_type()) }, TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident" diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 122bb9ba024a..11eb9b940aea 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -296,7 +296,7 @@ where name: keywords::DollarCrate.name(), ..ident }; - TokenTree::Token(span, token::Ident(ident)) + TokenTree::Token(span, token::Ident(ident, false)) } else { TokenTree::MetaVar(span, ident) } diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 7883c4bbc164..0f5855a32259 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -169,7 +169,7 @@ pub fn transcribe(cx: &ExtCtxt, Ident { ctxt: ident.ctxt.apply_mark(cx.current_expansion.mark), ..ident }; sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark)); result.push(TokenTree::Token(sp, token::Dollar).into()); - result.push(TokenTree::Token(sp, token::Ident(ident)).into()); + result.push(TokenTree::Token(sp, token::Ident(ident, false)).into()); } } quoted::TokenTree::Delimited(mut span, delimited) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 46e6027b094b..05a3150c139c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -578,7 +578,7 @@ pub fn noop_fold_tts(tts: TokenStream, fld: &mut T) -> TokenStream { // apply ident folder if it's an ident, apply other folds to interpolated nodes pub fn noop_fold_token(t: token::Token, fld: &mut T) -> token::Token { match t { - token::Ident(id) => token::Ident(fld.fold_ident(id)), + token::Ident(id, is_raw) => token::Ident(fld.fold_ident(id), is_raw), token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)), token::Interpolated(nt) => { let nt = match Lrc::try_unwrap(nt) { @@ -630,7 +630,8 @@ pub fn noop_fold_interpolated(nt: token::Nonterminal, fld: &mut T) token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)), token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)), token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)), - token::NtIdent(id) => token::NtIdent(Spanned::{node: fld.fold_ident(id.node), ..id}), + token::NtIdent(id, is_raw) => + token::NtIdent(Spanned::{node: fld.fold_ident(id.node), ..id}, is_raw), token::NtMeta(meta) => token::NtMeta(fld.fold_meta_item(meta)), token::NtPath(path) => token::NtPath(fld.fold_path(path)), token::NtTT(tt) => token::NtTT(fld.fold_tt(tt)), diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0e20eb49d395..0596fb44abee 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -14,7 +14,7 @@ use codemap::{CodeMap, FilePathMapping}; use errors::{FatalError, DiagnosticBuilder}; use parse::{token, ParseSess}; use str::char_at; -use symbol::Symbol; +use symbol::{Symbol, keywords}; use std_unicode::property::Pattern_White_Space; use std::borrow::Cow; @@ -1115,26 +1115,49 @@ impl<'a> StringReader<'a> { /// token, and updates the interner fn next_token_inner(&mut self) -> Result { let c = self.ch; - if ident_start(c) && - match (c.unwrap(), self.nextch(), self.nextnextch()) { - // Note: r as in r" or r#" is part of a raw string literal, - // b as in b' is part of a byte literal. - // They are not identifiers, and are handled further down. - ('r', Some('"'), _) | - ('r', Some('#'), _) | - ('b', Some('"'), _) | - ('b', Some('\''), _) | - ('b', Some('r'), Some('"')) | - ('b', Some('r'), Some('#')) => false, - _ => true, - } { - let start = self.pos; - while ident_continue(self.ch) { - self.bump(); - } - // FIXME: perform NFKC normalization here. (Issue #2253) - return Ok(self.with_str_from(start, |string| token::Ident(self.mk_ident(string)))); + if ident_start(c) { + let (is_ident_start, is_raw_ident) = + match (c.unwrap(), self.nextch(), self.nextnextch()) { + // r# followed by an identifier starter is a raw identifier. + // This is an exception to the r# case below. + ('r', Some('#'), x) if ident_start(x) => (true, true), + // r as in r" or r#" is part of a raw string literal. + // b as in b' is part of a byte literal. + // They are not identifiers, and are handled further down. + ('r', Some('"'), _) | + ('r', Some('#'), _) | + ('b', Some('"'), _) | + ('b', Some('\''), _) | + ('b', Some('r'), Some('"')) | + ('b', Some('r'), Some('#')) => (false, false), + _ => (true, false), + }; + if is_ident_start { + let raw_start = self.pos; + if is_raw_ident { + // Consume the 'r#' characters. + self.bump(); + self.bump(); + } + + let start = self.pos; + while ident_continue(self.ch) { + self.bump(); + } + + return Ok(self.with_str_from(start, |string| { + // FIXME: perform NFKC normalization here. (Issue #2253) + let ident = self.mk_ident(string); + if is_raw_ident && (token::is_path_segment_keyword(ident) || + ident.name == keywords::Underscore.name()) { + self.fatal_span_(raw_start, self.pos, + &format!("`r#{}` is not currently supported.", ident.name) + ).raise(); + } + token::Ident(ident, is_raw_ident) + })); + } } if is_dec_digit(c) { @@ -1801,7 +1824,7 @@ mod tests { assert_eq!(string_reader.next_token().tok, token::Whitespace); let tok1 = string_reader.next_token(); let tok2 = TokenAndSpan { - tok: token::Ident(id), + tok: token::Ident(id, false), sp: Span::new(BytePos(21), BytePos(23), NO_EXPANSION), }; assert_eq!(tok1, tok2); @@ -1811,7 +1834,7 @@ mod tests { // read another token: let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan { - tok: token::Ident(Ident::from_str("main")), + tok: mk_ident("main"), sp: Span::new(BytePos(24), BytePos(28), NO_EXPANSION), }; assert_eq!(tok3, tok4); @@ -1830,7 +1853,7 @@ mod tests { // make the identifier by looking up the string in the interner fn mk_ident(id: &str) -> token::Token { - token::Ident(Ident::from_str(id)) + token::Token::from_ast_ident(Ident::from_str(id)) } #[test] diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index f7e5d40b5246..4acfdab53c09 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -741,9 +741,9 @@ mod tests { match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) { ( 4, - Some(&TokenTree::Token(_, token::Ident(name_macro_rules))), + Some(&TokenTree::Token(_, token::Ident(name_macro_rules, false))), Some(&TokenTree::Token(_, token::Not)), - Some(&TokenTree::Token(_, token::Ident(name_zip))), + Some(&TokenTree::Token(_, token::Ident(name_zip, false))), Some(&TokenTree::Delimited(_, ref macro_delimed)), ) if name_macro_rules.name == "macro_rules" @@ -762,7 +762,7 @@ mod tests { ( 2, Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident))), + Some(&TokenTree::Token(_, token::Ident(ident, false))), ) if first_delimed.delim == token::Paren && ident.name == "a" => {}, _ => panic!("value 3: {:?}", *first_delimed), @@ -772,7 +772,7 @@ mod tests { ( 2, Some(&TokenTree::Token(_, token::Dollar)), - Some(&TokenTree::Token(_, token::Ident(ident))), + Some(&TokenTree::Token(_, token::Ident(ident, false))), ) if second_delimed.delim == token::Paren && ident.name == "a" => {}, @@ -793,17 +793,18 @@ mod tests { let tts = string_to_stream("fn a (b : i32) { b; }".to_string()); let expected = TokenStream::concat(vec![ - TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))).into(), - TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))).into(), + TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"), false)).into(), + TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"), false)).into(), TokenTree::Delimited( sp(5, 14), tokenstream::Delimited { delim: token::DelimToken::Paren, tts: TokenStream::concat(vec![ - TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))).into(), + TokenTree::Token(sp(6, 7), + token::Ident(Ident::from_str("b"), false)).into(), TokenTree::Token(sp(8, 9), token::Colon).into(), TokenTree::Token(sp(10, 13), - token::Ident(Ident::from_str("i32"))).into(), + token::Ident(Ident::from_str("i32"), false)).into(), ]).into(), }).into(), TokenTree::Delimited( @@ -811,7 +812,8 @@ mod tests { tokenstream::Delimited { delim: token::DelimToken::Brace, tts: TokenStream::concat(vec![ - TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))).into(), + TokenTree::Token(sp(17, 18), + token::Ident(Ident::from_str("b"), false)).into(), TokenTree::Token(sp(18, 19), token::Semi).into(), ]).into(), }).into() diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cb5010a638df..4c1575cf5893 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -358,7 +358,7 @@ impl TokenCursor { let body = TokenTree::Delimited(sp, Delimited { delim: token::Bracket, - tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"))), + tts: [TokenTree::Token(sp, token::Ident(ast::Ident::from_str("doc"), false)), TokenTree::Token(sp, token::Eq), TokenTree::Token(sp, token::Literal( token::StrRaw(Symbol::intern(&stripped), num_of_hashes), None))] @@ -784,7 +784,7 @@ impl<'a> Parser<'a> { fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i) => { + token::Ident(i, _) => { if self.token.is_reserved_ident() { let mut err = self.expected_ident_found(); if recover { @@ -1925,7 +1925,7 @@ impl<'a> Parser<'a> { pub fn parse_path_segment_ident(&mut self) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(sid) if self.token.is_path_segment_keyword() => { + token::Ident(sid, _) if self.token.is_path_segment_keyword() => { self.bump(); Ok(sid) } @@ -2740,11 +2740,14 @@ impl<'a> Parser<'a> { } pub fn process_potential_macro_variable(&mut self) { - let ident = match self.token { + let (ident, is_raw) = match self.token { token::Dollar if self.span.ctxt() != syntax_pos::hygiene::SyntaxContext::empty() && self.look_ahead(1, |t| t.is_ident()) => { self.bump(); - let name = match self.token { token::Ident(ident) => ident, _ => unreachable!() }; + let name = match self.token { + token::Ident(ident, _) => ident, + _ => unreachable!() + }; let mut err = self.fatal(&format!("unknown macro variable `{}`", name)); err.span_label(self.span, "unknown macro variable"); err.emit(); @@ -2753,13 +2756,13 @@ impl<'a> Parser<'a> { token::Interpolated(ref nt) => { self.meta_var_span = Some(self.span); match nt.0 { - token::NtIdent(ident) => ident, + token::NtIdent(ident, is_raw) => (ident, is_raw), _ => return, } } _ => return, }; - self.token = token::Ident(ident.node); + self.token = token::Ident(ident.node, is_raw); self.span = ident.span; } @@ -4245,7 +4248,7 @@ impl<'a> Parser<'a> { -> PResult<'a, Option>> { let token_lo = self.span; let (ident, def) = match self.token { - token::Ident(ident) if ident.name == keywords::Macro.name() => { + token::Ident(ident, false) if ident.name == keywords::Macro.name() => { self.bump(); let ident = self.parse_ident()?; let tokens = if self.check(&token::OpenDelim(token::Brace)) { @@ -4273,7 +4276,7 @@ impl<'a> Parser<'a> { (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) } - token::Ident(ident) if ident.name == "macro_rules" && + token::Ident(ident, _) if ident.name == "macro_rules" && self.look_ahead(1, |t| *t == token::Not) => { let prev_span = self.prev_span; self.complain_if_pub_macro(&vis.node, prev_span); @@ -5078,7 +5081,9 @@ impl<'a> Parser<'a> { fn parse_self_arg(&mut self) -> PResult<'a, Option> { let expect_ident = |this: &mut Self| match this.token { // Preserve hygienic context. - token::Ident(ident) => { let sp = this.span; this.bump(); codemap::respan(sp, ident) } + token::Ident(ident, _) => { + let sp = this.span; this.bump(); codemap::respan(sp, ident) + } _ => unreachable!() }; let isolated_self = |this: &mut Self, n| { @@ -5375,7 +5380,7 @@ impl<'a> Parser<'a> { VisibilityKind::Inherited => Ok(()), _ => { let is_macro_rules: bool = match self.token { - token::Ident(sid) => sid.name == Symbol::intern("macro_rules"), + token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"), _ => false, }; if is_macro_rules { @@ -7016,7 +7021,7 @@ impl<'a> Parser<'a> { fn parse_rename(&mut self) -> PResult<'a, Option> { if self.eat_keyword(keywords::As) { match self.token { - token::Ident(ident) if ident.name == keywords::Underscore.name() => { + token::Ident(ident, false) if ident.name == keywords::Underscore.name() => { self.bump(); // `_` Ok(Some(Ident { name: ident.name.gensymed(), ..ident })) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 4ada9e20f2cc..6406651bcba8 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -91,8 +91,8 @@ impl Lit { } } -fn ident_can_begin_expr(ident: ast::Ident) -> bool { - let ident_token: Token = Ident(ident); +fn ident_can_begin_expr(ident: ast::Ident, is_raw: bool) -> bool { + let ident_token: Token = Ident(ident, is_raw); !ident_token.is_reserved_ident() || ident_token.is_path_segment_keyword() || @@ -116,8 +116,8 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool { ].contains(&ident.name) } -fn ident_can_begin_type(ident: ast::Ident) -> bool { - let ident_token: Token = Ident(ident); +fn ident_can_begin_type(ident: ast::Ident, is_raw: bool) -> bool { + let ident_token: Token = Ident(ident, is_raw); !ident_token.is_reserved_ident() || ident_token.is_path_segment_keyword() || @@ -132,6 +132,37 @@ fn ident_can_begin_type(ident: ast::Ident) -> bool { ].contains(&ident.name) } +pub fn is_path_segment_keyword(id: ast::Ident) -> bool { + id.name == keywords::Super.name() || + id.name == keywords::SelfValue.name() || + id.name == keywords::SelfType.name() || + id.name == keywords::Extern.name() || + id.name == keywords::Crate.name() || + id.name == keywords::CrateRoot.name() || + id.name == keywords::DollarCrate.name() +} + +// Returns true for reserved identifiers used internally for elided lifetimes, +// unnamed method parameters, crate root module, error recovery etc. +pub fn is_special_ident(id: ast::Ident) -> bool { + id.name <= keywords::Underscore.name() +} + +/// Returns `true` if the token is a keyword used in the language. +pub fn is_used_keyword(id: ast::Ident) -> bool { + id.name >= keywords::As.name() && id.name <= keywords::While.name() +} + +/// Returns `true` if the token is a keyword reserved for possible future use. +pub fn is_unused_keyword(id: ast::Ident) -> bool { + id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name() +} + +/// Returns `true` if the token is either a special identifier or a keyword. +pub fn is_reserved_ident(id: ast::Ident) -> bool { + is_special_ident(id) || is_used_keyword(id) || is_unused_keyword(id) +} + #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug)] pub enum Token { /* Expression-operator symbols. */ @@ -175,7 +206,7 @@ pub enum Token { Literal(Lit, Option), /* Name components */ - Ident(ast::Ident), + Ident(ast::Ident, /* is_raw */ bool), Lifetime(ast::Ident), // The `LazyTokenStream` is a pure function of the `Nonterminal`, @@ -203,6 +234,11 @@ impl Token { Token::Interpolated(Lrc::new((nt, LazyTokenStream::new()))) } + /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary. + pub fn from_ast_ident(ident: ast::Ident) -> Token { + Ident(ident, is_reserved_ident(ident)) + } + /// Returns `true` if the token starts with '>'. pub fn is_like_gt(&self) -> bool { match *self { @@ -214,7 +250,8 @@ impl Token { /// Returns `true` if the token can appear at the start of an expression. pub fn can_begin_expr(&self) -> bool { match *self { - Ident(ident) => ident_can_begin_expr(ident), // value name or keyword + Ident(ident, is_raw) => + ident_can_begin_expr(ident, is_raw), // value name or keyword OpenDelim(..) | // tuple, array or block Literal(..) | // literal Not | // operator not @@ -239,7 +276,8 @@ impl Token { /// Returns `true` if the token can appear at the start of a type. pub fn can_begin_type(&self) -> bool { match *self { - Ident(ident) => ident_can_begin_type(ident), // type name or keyword + Ident(ident, is_raw) => + ident_can_begin_type(ident, is_raw), // type name or keyword OpenDelim(Paren) | // tuple OpenDelim(Bracket) | // array Not | // never @@ -272,17 +310,32 @@ impl Token { } } - pub fn ident(&self) -> Option { + fn ident_common(&self, allow_raw: bool) -> Option { match *self { - Ident(ident) => Some(ident), + Ident(ident, is_raw) if !is_raw || allow_raw => Some(ident), Interpolated(ref nt) => match nt.0 { - NtIdent(ident) => Some(ident.node), + NtIdent(ident, is_raw) if !is_raw || allow_raw => Some(ident.node), _ => None, }, _ => None, } } + pub fn nonraw_ident(&self) -> Option { + self.ident_common(false) + } + + pub fn is_raw_ident(&self) -> bool { + match *self { + Ident(_, true) => true, + _ => false, + } + } + + pub fn ident(&self) -> Option { + self.ident_common(true) + } + /// Returns `true` if the token is an identifier. pub fn is_ident(&self) -> bool { self.ident().is_some() @@ -351,18 +404,12 @@ impl Token { /// Returns `true` if the token is a given keyword, `kw`. pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { - self.ident().map(|ident| ident.name == kw.name()).unwrap_or(false) + self.nonraw_ident().map(|ident| ident.name == kw.name()).unwrap_or(false) } pub fn is_path_segment_keyword(&self) -> bool { - match self.ident() { - Some(id) => id.name == keywords::Super.name() || - id.name == keywords::SelfValue.name() || - id.name == keywords::SelfType.name() || - id.name == keywords::Extern.name() || - id.name == keywords::Crate.name() || - id.name == keywords::CrateRoot.name() || - id.name == keywords::DollarCrate.name(), + match self.nonraw_ident() { + Some(id) => is_path_segment_keyword(id), None => false, } } @@ -370,24 +417,24 @@ impl Token { // Returns true for reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. pub fn is_special_ident(&self) -> bool { - match self.ident() { - Some(id) => id.name <= keywords::Underscore.name(), + match self.nonraw_ident() { + Some(id) => is_special_ident(id), _ => false, } } /// Returns `true` if the token is a keyword used in the language. pub fn is_used_keyword(&self) -> bool { - match self.ident() { - Some(id) => id.name >= keywords::As.name() && id.name <= keywords::While.name(), + match self.nonraw_ident() { + Some(id) => is_used_keyword(id), _ => false, } } /// Returns `true` if the token is a keyword reserved for possible future use. pub fn is_unused_keyword(&self) -> bool { - match self.ident() { - Some(id) => id.name >= keywords::Abstract.name() && id.name <= keywords::Yield.name(), + match self.nonraw_ident() { + Some(id) => is_unused_keyword(id), _ => false, } } @@ -460,7 +507,10 @@ impl Token { /// Returns `true` if the token is either a special identifier or a keyword. pub fn is_reserved_ident(&self) -> bool { - self.is_special_ident() || self.is_used_keyword() || self.is_unused_keyword() + match self.nonraw_ident() { + Some(id) => is_reserved_ident(id), + _ => false, + } } pub fn interpolated_to_tokenstream(&self, sess: &ParseSess, span: Span) @@ -496,8 +546,8 @@ impl Token { Nonterminal::NtImplItem(ref item) => { tokens = prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span); } - Nonterminal::NtIdent(ident) => { - let token = Token::Ident(ident.node); + Nonterminal::NtIdent(ident, is_raw) => { + let token = Token::Ident(ident.node, is_raw); tokens = Some(TokenTree::Token(ident.span, token).into()); } Nonterminal::NtLifetime(lifetime) => { @@ -529,7 +579,7 @@ pub enum Nonterminal { NtPat(P), NtExpr(P), NtTy(P), - NtIdent(ast::SpannedIdent), + NtIdent(ast::SpannedIdent, /* is_raw */ bool), /// Stuff inside brackets for attributes NtMeta(ast::MetaItem), NtPath(ast::Path), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7adb2848f8d9..50577a26abf4 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -250,7 +250,8 @@ pub fn token_to_string(tok: &Token) -> String { } /* Name components */ - token::Ident(s) => s.to_string(), + token::Ident(s, false) => s.to_string(), + token::Ident(s, true) => format!("r#{}", s), token::Lifetime(s) => s.to_string(), /* Other */ @@ -261,24 +262,25 @@ pub fn token_to_string(tok: &Token) -> String { token::Shebang(s) => format!("/* shebang: {}*/", s), token::Interpolated(ref nt) => match nt.0 { - 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) => generic_params_to_string(&e.params), - 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::NtLifetime(ref e) => lifetime_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, false) => ident_to_string(e.node), + token::NtIdent(ref e, true) => format!("r#{}", 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) => generic_params_to_string(&e.params), + 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::NtLifetime(ref e) => lifetime_to_string(e), } } } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 1219e909e121..3a7a1b9a6696 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -684,7 +684,7 @@ mod tests { with_globals(|| { let test0: TokenStream = Vec::::new().into_iter().collect(); let test1: TokenStream = - TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"))).into(); + TokenTree::Token(sp(0, 1), Token::Ident(Ident::from_str("a"), false)).into(); let test2 = string_to_ts("foo(bar::baz)"); assert_eq!(test0.is_empty(), true); diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 8d0104e512bf..d513008f0e2d 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -44,7 +44,8 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, } } else { match *e { - TokenTree::Token(_, token::Ident(ident)) => res_str.push_str(&ident.name.as_str()), + TokenTree::Token(_, token::Ident(ident, _)) => + res_str.push_str(&ident.name.as_str()), _ => { cx.span_err(sp, "concat_idents! requires ident args."); return DummyResult::expr(sp); diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 8fd95aa1ca86..d9c68e3167bd 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -149,7 +149,7 @@ fn parse_args(ecx: &mut ExtCtxt, if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) { named = true; let ident = match p.token { - token::Ident(i) => { + token::Ident(i, _) => { p.bump(); i } diff --git a/src/test/parse-fail/raw-str-delim.rs b/src/test/parse-fail/raw-str-delim.rs index 3fc5f8aae187..8c0027287dec 100644 --- a/src/test/parse-fail/raw-str-delim.rs +++ b/src/test/parse-fail/raw-str-delim.rs @@ -11,5 +11,5 @@ // compile-flags: -Z parse-only static s: &'static str = - r#x"#"x# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation + r#~"#"~# //~ ERROR found invalid character; only `#` is allowed in raw string delimitation ; diff --git a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs index 26419a51513f..ed0434051b70 100644 --- a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs +++ b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs @@ -49,7 +49,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) } let text = match args[0] { - TokenTree::Token(_, token::Ident(s)) => s.to_string(), + TokenTree::Token(_, token::Ident(s, _)) => s.to_string(), _ => { cx.span_err(sp, "argument should be a single identifier"); return DummyResult::any(sp); diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs new file mode 100644 index 000000000000..2ef9fba2076a --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::mem; + +#[r#repr(r#C, r#packed)] +struct Test { + a: bool, b: u64 +} + +#[r#derive(r#Debug)] +struct Test2(u32); + +pub fn main() { + assert_eq!(mem::size_of::(), 9); + assert_eq!("Test2(123)", format!("{:?}", Test2(123))); +} diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs new file mode 100644 index 000000000000..eefce3981bec --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn r#fn(r#match: u32) -> u32 { + r#match +} + +pub fn main() { + let r#struct = 1; + assert_eq!(1, r#struct); + + let foo = 2; + assert_eq!(2, r#foo); + + let r#bar = 3; + assert_eq!(3, bar); + + assert_eq!(4, r#fn(4)); + + let r#true = false; + assert_eq!(r#true, false); +} diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs new file mode 100644 index 000000000000..4306ffe2042a --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs @@ -0,0 +1,41 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[derive(Debug, PartialEq, Eq)] +struct IntWrapper(u32); + +#[derive(Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Copy, Clone, Default)] +struct HasKeywordField { + r#struct: u32, +} + +struct Generic(T); + +trait Trait { + fn r#trait(&self) -> u32; +} +impl Trait for Generic { + fn r#trait(&self) -> u32 { + self.0 + } +} + +pub fn main() { + assert_eq!(IntWrapper(1), r#IntWrapper(1)); + + match IntWrapper(2) { + r#IntWrapper(r#struct) => assert_eq!(2, r#struct), + } + + assert_eq!("HasKeywordField { struct: 3 }", format!("{:?}", HasKeywordField { r#struct: 3 })); + + assert_eq!(4, Generic(4).0); + assert_eq!(5, Generic(5).r#trait()); +} diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs new file mode 100644 index 000000000000..9e89b79266cf --- /dev/null +++ b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs @@ -0,0 +1,47 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(decl_macro)] + +r#macro_rules! r#struct { + ($r#struct:expr) => { $r#struct } +} + +macro_rules! old_macro { + ($a:expr) => {$a} +} + +macro r#decl_macro($r#fn:expr) { + $r#fn +} + +macro passthrough($id:ident) { + $id +} + +macro_rules! test_pat_match { + (a) => { 6 }; + (r#a) => { 7 }; +} + +pub fn main() { + r#println!("{struct}", r#struct = 1); + assert_eq!(2, r#struct!(2)); + assert_eq!(3, r#old_macro!(3)); + assert_eq!(4, decl_macro!(4)); + + let r#match = 5; + assert_eq!(5, passthrough!(r#match)); + + assert_eq!("r#struct", stringify!(r#struct)); + + assert_eq!(6, test_pat_match!(a)); + assert_eq!(7, test_pat_match!(r#a)); +} diff --git a/src/test/ui/raw-literal-keywords.rs b/src/test/ui/raw-literal-keywords.rs new file mode 100644 index 000000000000..8b3747dbe15e --- /dev/null +++ b/src/test/ui/raw-literal-keywords.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +#![feature(dyn_trait)] + +fn test_if() { + r#if true { } //~ ERROR found `true` +} + +fn test_struct() { + r#struct Test; //~ ERROR found `Test` +} + +fn test_union() { + r#union Test; //~ ERROR found `Test` +} diff --git a/src/test/ui/raw-literal-keywords.stderr b/src/test/ui/raw-literal-keywords.stderr new file mode 100644 index 000000000000..022f80ae8a4e --- /dev/null +++ b/src/test/ui/raw-literal-keywords.stderr @@ -0,0 +1,20 @@ +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `true` + --> $DIR/raw-literal-keywords.rs:16:10 + | +LL | r#if true { } //~ ERROR found `true` + | ^^^^ expected one of 8 possible tokens here + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` + --> $DIR/raw-literal-keywords.rs:20:14 + | +LL | r#struct Test; //~ ERROR found `Test` + | ^^^^ expected one of 8 possible tokens here + +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` + --> $DIR/raw-literal-keywords.rs:24:13 + | +LL | r#union Test; //~ ERROR found `Test` + | ^^^^ expected one of 8 possible tokens here + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/raw-literal-self.rs b/src/test/ui/raw-literal-self.rs new file mode 100644 index 000000000000..17496d767b62 --- /dev/null +++ b/src/test/ui/raw-literal-self.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +fn self_test(r#self: u32) { + //~^ ERROR `r#self` is not currently supported. +} diff --git a/src/test/ui/raw-literal-self.stderr b/src/test/ui/raw-literal-self.stderr new file mode 100644 index 000000000000..f4b759372471 --- /dev/null +++ b/src/test/ui/raw-literal-self.stderr @@ -0,0 +1,8 @@ +error: `r#self` is not currently supported. + --> $DIR/raw-literal-self.rs:13:14 + | +LL | fn self_test(r#self: u32) { + | ^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/raw-literal-underscore.rs b/src/test/ui/raw-literal-underscore.rs new file mode 100644 index 000000000000..ec33e4861958 --- /dev/null +++ b/src/test/ui/raw-literal-underscore.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +fn underscore_test(r#_: u32) { + //~^ ERROR `r#_` is not currently supported. +} diff --git a/src/test/ui/raw-literal-underscore.stderr b/src/test/ui/raw-literal-underscore.stderr new file mode 100644 index 000000000000..8072eee4f060 --- /dev/null +++ b/src/test/ui/raw-literal-underscore.stderr @@ -0,0 +1,8 @@ +error: `r#_` is not currently supported. + --> $DIR/raw-literal-underscore.rs:13:20 + | +LL | fn underscore_test(r#_: u32) { + | ^^^ + +error: aborting due to previous error + From 7d5c29b9eae5857c040bf6f1b2d729596c8af3ae Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Wed, 14 Mar 2018 02:00:41 -0500 Subject: [PATCH 364/830] Feature gate raw identifiers. --- src/libsyntax/feature_gate.rs | 14 ++++++++++++++ src/libsyntax/parse/lexer/mod.rs | 1 + src/libsyntax/parse/mod.rs | 4 ++++ src/libsyntax/parse/parser.rs | 5 ++++- src/test/run-pass/rfc-2151-raw-identifiers/attr.rs | 2 ++ .../run-pass/rfc-2151-raw-identifiers/basic.rs | 2 ++ .../run-pass/rfc-2151-raw-identifiers/items.rs | 2 ++ .../run-pass/rfc-2151-raw-identifiers/macros.rs | 1 + src/test/ui/feature-gate-raw-identifiers.rs | 14 ++++++++++++++ src/test/ui/feature-gate-raw-identifiers.stderr | 11 +++++++++++ src/test/ui/raw-literal-keywords.rs | 1 + src/test/ui/raw-literal-keywords.stderr | 6 +++--- src/test/ui/raw-literal-self.rs | 2 ++ src/test/ui/raw-literal-self.stderr | 2 +- 14 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/feature-gate-raw-identifiers.rs create mode 100644 src/test/ui/feature-gate-raw-identifiers.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fa600cd68606..153e42c8214f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -452,6 +452,9 @@ declare_features! ( // `use path as _;` and `extern crate c as _;` (active, underscore_imports, "1.26.0", Some(48216), None), + + // Raw identifiers allowing keyword names to be used + (active, raw_identifiers, "1.26.0", Some(48589), None), ); declare_features! ( @@ -1932,6 +1935,17 @@ pub fn check_crate(krate: &ast::Crate, parse_sess: sess, plugin_attributes, }; + + if !features.raw_identifiers { + for &span in sess.raw_identifier_spans.borrow().iter() { + if !span.allows_unstable() { + gate_feature!(&ctx, raw_identifiers, span, + "raw identifiers are experimental and subject to change" + ); + } + } + } + let visitor = &mut PostExpansionVisitor { context: &ctx }; visitor.whole_crate_feature_gates(krate); visit::walk_crate(visitor, krate); diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0596fb44abee..8e746ea69e79 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1796,6 +1796,7 @@ mod tests { included_mod_stack: RefCell::new(Vec::new()), code_map: cm, missing_fragment_specifiers: RefCell::new(HashSet::new()), + raw_identifier_spans: RefCell::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), non_modrs_mods: RefCell::new(vec![]), } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 4acfdab53c09..03ac1e8b5a9b 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -48,6 +48,9 @@ pub struct ParseSess { pub unstable_features: UnstableFeatures, pub config: CrateConfig, pub missing_fragment_specifiers: RefCell>, + /// Places where raw identifiers were used. This is used for feature gating + /// raw identifiers + pub raw_identifier_spans: RefCell>, /// The registered diagnostics codes pub registered_diagnostics: Lock, // Spans where a `mod foo;` statement was included in a non-mod.rs file. @@ -74,6 +77,7 @@ impl ParseSess { unstable_features: UnstableFeatures::from_environment(), config: HashSet::new(), missing_fragment_specifiers: RefCell::new(HashSet::new()), + raw_identifier_spans: RefCell::new(Vec::new()), registered_diagnostics: Lock::new(ErrorMap::new()), included_mod_stack: RefCell::new(vec![]), code_map, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4c1575cf5893..c2ee78e9e9d1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -784,7 +784,7 @@ impl<'a> Parser<'a> { fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i, _) => { + token::Ident(i, is_raw) => { if self.token.is_reserved_ident() { let mut err = self.expected_ident_found(); if recover { @@ -793,6 +793,9 @@ impl<'a> Parser<'a> { return Err(err); } } + if is_raw { + self.sess.raw_identifier_spans.borrow_mut().push(self.span); + } self.bump(); Ok(i) } diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs index 2ef9fba2076a..6cea75cf1d11 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(raw_identifiers)] + use std::mem; #[r#repr(r#C, r#packed)] diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs index eefce3981bec..5d495c4e9e55 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(raw_identifiers)] + fn r#fn(r#match: u32) -> u32 { r#match } diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs index 4306ffe2042a..256bd263d38d 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(raw_identifiers)] + #[derive(Debug, PartialEq, Eq)] struct IntWrapper(u32); diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs index 9e89b79266cf..4bd16ded52fb 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(decl_macro)] +#![feature(raw_identifiers)] r#macro_rules! r#struct { ($r#struct:expr) => { $r#struct } diff --git a/src/test/ui/feature-gate-raw-identifiers.rs b/src/test/ui/feature-gate-raw-identifiers.rs new file mode 100644 index 000000000000..38024feb432d --- /dev/null +++ b/src/test/ui/feature-gate-raw-identifiers.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let r#foo = 3; //~ ERROR raw identifiers are experimental and subject to change + println!("{}", foo); +} diff --git a/src/test/ui/feature-gate-raw-identifiers.stderr b/src/test/ui/feature-gate-raw-identifiers.stderr new file mode 100644 index 000000000000..02eff7247c47 --- /dev/null +++ b/src/test/ui/feature-gate-raw-identifiers.stderr @@ -0,0 +1,11 @@ +error[E0658]: raw identifiers are experimental and subject to change (see issue #48589) + --> $DIR/feature-gate-raw-identifiers.rs:12:9 + | +LL | let r#foo = 3; //~ ERROR raw identifiers are experimental and subject to change + | ^^^^^ + | + = help: add #![feature(raw_identifiers)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/raw-literal-keywords.rs b/src/test/ui/raw-literal-keywords.rs index 8b3747dbe15e..9b28aa0b1511 100644 --- a/src/test/ui/raw-literal-keywords.rs +++ b/src/test/ui/raw-literal-keywords.rs @@ -11,6 +11,7 @@ // compile-flags: -Z parse-only #![feature(dyn_trait)] +#![feature(raw_identifiers)] fn test_if() { r#if true { } //~ ERROR found `true` diff --git a/src/test/ui/raw-literal-keywords.stderr b/src/test/ui/raw-literal-keywords.stderr index 022f80ae8a4e..3758568323cc 100644 --- a/src/test/ui/raw-literal-keywords.stderr +++ b/src/test/ui/raw-literal-keywords.stderr @@ -1,17 +1,17 @@ error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `true` - --> $DIR/raw-literal-keywords.rs:16:10 + --> $DIR/raw-literal-keywords.rs:17:10 | LL | r#if true { } //~ ERROR found `true` | ^^^^ expected one of 8 possible tokens here error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` - --> $DIR/raw-literal-keywords.rs:20:14 + --> $DIR/raw-literal-keywords.rs:21:14 | LL | r#struct Test; //~ ERROR found `Test` | ^^^^ expected one of 8 possible tokens here error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `Test` - --> $DIR/raw-literal-keywords.rs:24:13 + --> $DIR/raw-literal-keywords.rs:25:13 | LL | r#union Test; //~ ERROR found `Test` | ^^^^ expected one of 8 possible tokens here diff --git a/src/test/ui/raw-literal-self.rs b/src/test/ui/raw-literal-self.rs index 17496d767b62..f88d6cf9a67b 100644 --- a/src/test/ui/raw-literal-self.rs +++ b/src/test/ui/raw-literal-self.rs @@ -10,6 +10,8 @@ // compile-flags: -Z parse-only +#![feature(raw_identifiers)] + fn self_test(r#self: u32) { //~^ ERROR `r#self` is not currently supported. } diff --git a/src/test/ui/raw-literal-self.stderr b/src/test/ui/raw-literal-self.stderr index f4b759372471..e3345847aa89 100644 --- a/src/test/ui/raw-literal-self.stderr +++ b/src/test/ui/raw-literal-self.stderr @@ -1,5 +1,5 @@ error: `r#self` is not currently supported. - --> $DIR/raw-literal-self.rs:13:14 + --> $DIR/raw-literal-self.rs:15:14 | LL | fn self_test(r#self: u32) { | ^^^^^^ From 5581aa8eebba270cde4e95d2e2b7f08163ae7319 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 18 Mar 2018 16:32:41 +0100 Subject: [PATCH 365/830] Fix events handling in rustdoc --- src/librustdoc/html/static/main.js | 77 ++++++++++++++++-------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 28d39cb174a1..21c1d9d670d6 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -239,52 +239,59 @@ } } - function handleShortcut(ev) { - if (document.activeElement.tagName === "INPUT" && - hasClass(document.getElementById('main'), "hidden")) { - return; + function handleEscape(ev, help) { + hideModal(); + var search = document.getElementById("search"); + if (!hasClass(help, "hidden")) { + displayHelp(false, ev); + } else if (!hasClass(search, "hidden")) { + ev.preventDefault(); + addClass(search, "hidden"); + removeClass(document.getElementById("main"), "hidden"); } + defocusSearchBar(); + } + function handleShortcut(ev) { // Don't interfere with browser shortcuts if (ev.ctrlKey || ev.altKey || ev.metaKey) { return; } var help = document.getElementById("help"); - switch (getVirtualKey(ev)) { - case "Escape": - hideModal(); - var search = document.getElementById("search"); - if (!hasClass(help, "hidden")) { + if (document.activeElement.tagName === "INPUT") { + switch (getVirtualKey(ev)) { + case "Escape": + handleEscape(ev, help); + break; + } + } else { + switch (getVirtualKey(ev)) { + case "Escape": + handleEscape(ev, help); + break; + + case "s": + case "S": displayHelp(false, ev); - } else if (!hasClass(search, "hidden")) { - ev.preventDefault(); - addClass(search, "hidden"); - removeClass(document.getElementById("main"), "hidden"); - } - defocusSearchBar(); - break; - - case "s": - case "S": - displayHelp(false, ev); - hideModal(); - ev.preventDefault(); - focusSearchBar(); - break; - - case "+": - case "-": - ev.preventDefault(); - toggleAllDocs(); - break; - - case "?": - if (ev.shiftKey) { hideModal(); - displayHelp(true, ev); + ev.preventDefault(); + focusSearchBar(); + break; + + case "+": + case "-": + ev.preventDefault(); + toggleAllDocs(); + break; + + case "?": + if (ev.shiftKey) { + hideModal(); + displayHelp(true, ev); + } + break; } - break; } } From a23f685296b2edd59acc998411340184b958ec82 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 18 Mar 2018 16:58:38 +0100 Subject: [PATCH 366/830] num::NonZero* types now have their own tracking issue: #49137 Fixes #27730 --- src/libcore/nonzero.rs | 7 +------ src/libcore/num/mod.rs | 4 ++-- src/libstd/num.rs | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 59aaef9d66a0..19836d98844e 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -9,9 +9,7 @@ // except according to those terms. //! Exposes the NonZero lang item which provides optimization hints. -#![unstable(feature = "nonzero", - reason = "deprecated", - issue = "27730")] +#![unstable(feature = "nonzero", reason = "deprecated", issue = "49137")] #![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead", since = "1.26.0")] #![allow(deprecated)] @@ -70,9 +68,6 @@ pub struct NonZero(pub(crate) T); impl NonZero { /// Creates an instance of NonZero with the provided value. /// You must indeed ensure that the value is actually "non-zero". - #[unstable(feature = "nonzero", - reason = "needs an RFC to flesh out the design", - issue = "27730")] #[inline] pub const unsafe fn new_unchecked(inner: T) -> Self { NonZero(inner) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 84f6ab9b7649..2ffcb9e95e2d 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -92,7 +92,7 @@ macro_rules! nonzero_integers { } nonzero_integers! { - #[unstable(feature = "nonzero", issue = "27730")] + #[unstable(feature = "nonzero", issue = "49137")] NonZeroU8(u8); NonZeroI8(i8); NonZeroU16(u16); NonZeroI16(i16); NonZeroU32(u32); NonZeroI32(i32); @@ -103,7 +103,7 @@ nonzero_integers! { nonzero_integers! { // Change this to `#[unstable(feature = "i128", issue = "35118")]` // if other NonZero* integer types are stabilizied before 128-bit integers - #[unstable(feature = "nonzero", issue = "27730")] + #[unstable(feature = "nonzero", issue = "49137")] NonZeroU128(u128); NonZeroI128(i128); } diff --git a/src/libstd/num.rs b/src/libstd/num.rs index 5e0406ca2202..0c618370ac21 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -21,7 +21,7 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError} #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; -#[unstable(feature = "nonzero", issue = "27730")] +#[unstable(feature = "nonzero", issue = "49137")] pub use core::num::{ NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize, @@ -29,7 +29,7 @@ pub use core::num::{ // Change this to `#[unstable(feature = "i128", issue = "35118")]` // if other NonZero* integer types are stabilizied before 128-bit integers -#[unstable(feature = "nonzero", issue = "27730")] +#[unstable(feature = "nonzero", issue = "49137")] pub use core::num::{NonZeroU128, NonZeroI128}; #[cfg(test)] use fmt; From efa9016390c6980983c58271436813215595bd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 17 Mar 2018 22:17:33 +0100 Subject: [PATCH 367/830] Add a CI job for parallel rustc using x.py check --- config.toml.example | 3 +++ src/bootstrap/configure.py | 1 + src/ci/docker/x86_64-gnu-debug/Dockerfile | 1 + src/ci/run.sh | 7 +++++++ 4 files changed, 12 insertions(+) diff --git a/config.toml.example b/config.toml.example index b47f9163c0da..86ddefefb43b 100644 --- a/config.toml.example +++ b/config.toml.example @@ -268,6 +268,9 @@ # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE) #backtrace = true +# Build rustc with experimental parallelization +#experimental-parallel-queries = false + # The default linker that will be hard-coded into the generated compiler for # targets that don't specify linker explicitly in their target specifications. # Note that this is not the linker used to link said compiler. diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 97da7cae07f7..a5c373d5d5e7 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -44,6 +44,7 @@ o("debug", "rust.debug", "debug mode; disables optimization unless `--enable-opt o("docs", "build.docs", "build standard library documentation") o("compiler-docs", "build.compiler-docs", "build compiler documentation") o("optimize-tests", "rust.optimize-tests", "build tests with optimizations") +o("experimental-parallel-queries", "rust.experimental-parallel-queries", "build rustc with experimental parallelization") o("test-miri", "rust.test-miri", "run miri's test suite") o("debuginfo-tests", "rust.debuginfo-tests", "build tests with debugger metadata") o("quiet-tests", "rust.quiet-tests", "enable quieter output when running tests") diff --git a/src/ci/docker/x86_64-gnu-debug/Dockerfile b/src/ci/docker/x86_64-gnu-debug/Dockerfile index 95d41028595f..ff6ab1013b4c 100644 --- a/src/ci/docker/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/x86_64-gnu-debug/Dockerfile @@ -16,6 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh +ENV PARALLEL_CHECK 1 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --enable-debug \ diff --git a/src/ci/run.sh b/src/ci/run.sh index e3f38e4834a9..7fc2a963640b 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -72,6 +72,13 @@ fi # sccache server at the start of the build, but no need to worry if this fails. SCCACHE_IDLE_TIMEOUT=10800 sccache --start-server || true +if [ "$PARALLEL_CHECK" != "" ]; then + $SRC/configure --enable-experimental-parallel-queries + python2.7 ../x.py check + rm -f config.toml + rm -rf build +fi + travis_fold start configure travis_time_start $SRC/configure $RUST_CONFIGURE_ARGS From d2e7953d1325b1a1fe1cef526dbe8d23fa3e00a1 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Sun, 18 Mar 2018 11:21:38 -0500 Subject: [PATCH 368/830] Move raw_identifiers check to the lexer. --- src/libsyntax/parse/lexer/mod.rs | 4 ++++ src/libsyntax/parse/parser.rs | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 8e746ea69e79..068929c8948d 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1155,6 +1155,10 @@ impl<'a> StringReader<'a> { &format!("`r#{}` is not currently supported.", ident.name) ).raise(); } + if is_raw_ident { + let span = self.mk_sp(raw_start, self.pos); + self.sess.raw_identifier_spans.borrow_mut().push(span); + } token::Ident(ident, is_raw_ident) })); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c2ee78e9e9d1..4c1575cf5893 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -784,7 +784,7 @@ impl<'a> Parser<'a> { fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i, is_raw) => { + token::Ident(i, _) => { if self.token.is_reserved_ident() { let mut err = self.expected_ident_found(); if recover { @@ -793,9 +793,6 @@ impl<'a> Parser<'a> { return Err(err); } } - if is_raw { - self.sess.raw_identifier_spans.borrow_mut().push(self.span); - } self.bump(); Ok(i) } From e269a7435e80e0c4e02e3a5aa21233ef28892def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Sun, 18 Mar 2018 18:08:17 +0100 Subject: [PATCH 369/830] Allow test target to pass without installing explicitly pass -L target-lib to rustdoc --- src/test/run-make/tools.mk | 2 +- src/tools/compiletest/src/runtest.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/run-make/tools.mk b/src/test/run-make/tools.mk index d9103e199273..af1707de6c02 100644 --- a/src/test/run-make/tools.mk +++ b/src/test/run-make/tools.mk @@ -9,7 +9,7 @@ RUSTC_ORIGINAL := $(RUSTC) BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)' BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)' RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS) -RUSTDOC := $(BARE_RUSTDOC) +RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR) ifdef RUSTC_LINKER RUSTC := $(RUSTC) -Clinker=$(RUSTC_LINKER) RUSTDOC := $(RUSTDOC) --linker $(RUSTC_LINKER) -Z unstable-options diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 953a13a3f582..23bb39215d37 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1324,6 +1324,8 @@ impl<'test> TestCx<'test> { let mut rustdoc = Command::new(rustdoc_path); rustdoc + .arg("-L") + .arg(self.config.run_lib_path.to_str().unwrap()) .arg("-L") .arg(aux_dir) .arg("-o") From 5c3d6320deb20f78d83d12fb3a319b9dd6b15290 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Sun, 18 Mar 2018 12:16:02 -0500 Subject: [PATCH 370/830] Return a is_raw parameter from Token::ident rather than having separate methods. --- src/libsyntax/ext/tt/macro_parser.rs | 4 +-- src/libsyntax/ext/tt/quoted.rs | 4 +-- src/libsyntax/parse/token.rs | 45 ++++++++++------------------ 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 714b7ca981da..8cb331c65da2 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -364,8 +364,8 @@ 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 { - if let (Some(id1), Some(id2)) = (t1.ident(), t2.ident()) { - id1.name == id2.name && t1.is_raw_ident() == t2.is_raw_ident() + if let (Some((id1, is_raw1)), Some((id2, is_raw2))) = (t1.ident(), t2.ident()) { + id1.name == id2.name && is_raw1 == is_raw2 } else if let (&token::Lifetime(id1), &token::Lifetime(id2)) = (t1, t2) { id1.name == id2.name } else { diff --git a/src/libsyntax/ext/tt/quoted.rs b/src/libsyntax/ext/tt/quoted.rs index 11eb9b940aea..f324edeb1178 100644 --- a/src/libsyntax/ext/tt/quoted.rs +++ b/src/libsyntax/ext/tt/quoted.rs @@ -200,7 +200,7 @@ pub fn parse( let span = match trees.next() { Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() { Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() { - Some(kind) => { + Some((kind, _)) => { let span = end_sp.with_lo(start_sp.lo()); result.push(TokenTree::MetaVarDecl(span, ident, kind)); continue; @@ -289,7 +289,7 @@ where // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special // metavariable that names the crate of the invokation. Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => { - let ident = token.ident().unwrap(); + let (ident, _) = token.ident().unwrap(); let span = ident_span.with_lo(span.lo()); if ident.name == keywords::Crate.name() { let ident = ast::Ident { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 6406651bcba8..4e7a282adc58 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -310,32 +310,17 @@ impl Token { } } - fn ident_common(&self, allow_raw: bool) -> Option { + pub fn ident(&self) -> Option<(ast::Ident, bool)> { match *self { - Ident(ident, is_raw) if !is_raw || allow_raw => Some(ident), + Ident(ident, is_raw) => Some((ident, is_raw)), Interpolated(ref nt) => match nt.0 { - NtIdent(ident, is_raw) if !is_raw || allow_raw => Some(ident.node), + NtIdent(ident, is_raw) => Some((ident.node, is_raw)), _ => None, }, _ => None, } } - pub fn nonraw_ident(&self) -> Option { - self.ident_common(false) - } - - pub fn is_raw_ident(&self) -> bool { - match *self { - Ident(_, true) => true, - _ => false, - } - } - - pub fn ident(&self) -> Option { - self.ident_common(true) - } - /// Returns `true` if the token is an identifier. pub fn is_ident(&self) -> bool { self.ident().is_some() @@ -404,37 +389,37 @@ impl Token { /// Returns `true` if the token is a given keyword, `kw`. pub fn is_keyword(&self, kw: keywords::Keyword) -> bool { - self.nonraw_ident().map(|ident| ident.name == kw.name()).unwrap_or(false) + self.ident().map(|(ident, is_raw)| ident.name == kw.name() && !is_raw).unwrap_or(false) } pub fn is_path_segment_keyword(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_path_segment_keyword(id), - None => false, + match self.ident() { + Some((id, false)) => is_path_segment_keyword(id), + _ => false, } } // Returns true for reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. pub fn is_special_ident(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_special_ident(id), + match self.ident() { + Some((id, false)) => is_special_ident(id), _ => false, } } /// Returns `true` if the token is a keyword used in the language. pub fn is_used_keyword(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_used_keyword(id), + match self.ident() { + Some((id, false)) => is_used_keyword(id), _ => false, } } /// Returns `true` if the token is a keyword reserved for possible future use. pub fn is_unused_keyword(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_unused_keyword(id), + match self.ident() { + Some((id, false)) => is_unused_keyword(id), _ => false, } } @@ -507,8 +492,8 @@ impl Token { /// Returns `true` if the token is either a special identifier or a keyword. pub fn is_reserved_ident(&self) -> bool { - match self.nonraw_ident() { - Some(id) => is_reserved_ident(id), + match self.ident() { + Some((id, false)) => is_reserved_ident(id), _ => false, } } From 9a44448a252a94bf6b99388cab82aa9cd4595207 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sun, 18 Mar 2018 18:33:36 +0100 Subject: [PATCH 371/830] add simd_select intrinsic --- src/librustc_trans/intrinsic.rs | 21 +++ src/librustc_typeck/check/intrinsic.rs | 1 + .../simd-intrinsic-generic-select.rs | 56 +++++++ .../run-pass/simd-intrinsic-generic-select.rs | 144 ++++++++++++++++++ 4 files changed, 222 insertions(+) create mode 100644 src/test/compile-fail/simd-intrinsic-generic-select.rs create mode 100644 src/test/run-pass/simd-intrinsic-generic-select.rs diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index c3de9e0ffcce..76c5bf56daa9 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1153,6 +1153,27 @@ fn generic_simd_intrinsic<'a, 'tcx>( return Ok(bx.extract_element(args[0].immediate(), args[1].immediate())) } + if name == "simd_select" { + let m_elem_ty = in_elem; + let m_len = in_len; + let v_len = arg_tys[1].simd_size(tcx); + require!(m_len == v_len, + "mismatched lengths: mask length `{}` != other vector length `{}`", + m_len, v_len + ); + match m_elem_ty.sty { + ty::TyInt(_) => {}, + _ => { + return_error!("mask element type is `{}`, expected `i_`", m_elem_ty); + } + } + // truncate the mask to a vector of i1s + let i1 = Type::i1(bx.cx); + let i1xn = Type::vector(&i1, m_len as u64); + let m_i1s = bx.trunc(args[0].immediate(), i1xn); + return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); + } + macro_rules! arith_red { ($name:tt : $integer_reduce:ident, $float_reduce:ident, $ordered:expr) => { if name == $name { diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 99707a4a3c0e..84c9339be0ad 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -361,6 +361,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), "simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)), "simd_cast" => (2, vec![param(0)], param(1)), + "simd_select" => (2, vec![param(0), param(1), param(1)], param(1)), "simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool), "simd_reduce_add_ordered" | "simd_reduce_mul_ordered" => (2, vec![param(0), param(1)], param(1)), diff --git a/src/test/compile-fail/simd-intrinsic-generic-select.rs b/src/test/compile-fail/simd-intrinsic-generic-select.rs new file mode 100644 index 000000000000..d74d6815d5f5 --- /dev/null +++ b/src/test/compile-fail/simd-intrinsic-generic-select.rs @@ -0,0 +1,56 @@ +// Copyright 2015 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. + +// Test that the simd_select intrinsic produces ok-ish error +// messages when misused. + +#![feature(repr_simd, platform_intrinsics)] +#![allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone)] +pub struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq)] +struct b8x8(pub i8, pub i8, pub i8, pub i8, + pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; +} + +fn main() { + let m4 = b8x4(0, 0, 0, 0); + let m8 = b8x8(0, 0, 0, 0, 0, 0, 0, 0); + let x = u32x4(0, 0, 0, 0); + let z = f32x4(0.0, 0.0, 0.0, 0.0); + + unsafe { + simd_select(m4, x, x); + + simd_select(m8, x, x); + //~^ ERROR mismatched lengths: mask length `8` != other vector length `4` + + simd_select(x, x, x); + //~^ ERROR mask element type is `u32`, expected `i_` + + simd_select(z, z, z); + //~^ ERROR mask element type is `f32`, expected `i_` + } +} diff --git a/src/test/run-pass/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd-intrinsic-generic-select.rs new file mode 100644 index 000000000000..bf0a59309ca2 --- /dev/null +++ b/src/test/run-pass/simd-intrinsic-generic-select.rs @@ -0,0 +1,144 @@ +// Copyright 2015 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. + +// Test that the simd_select intrinsics produces correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct i32x4(pub i32, pub i32, pub i32, pub i32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct u32x4(pub u32, pub u32, pub u32, pub u32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct b8x4(pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; +} + +fn main() { + let m0 = b8x4(!0, !0, !0, !0); + let m1 = b8x4(0, 0, 0, 0); + let m2 = b8x4(!0, !0, 0, 0); + let m3 = b8x4(0, 0, !0, !0); + let m4 = b8x4(!0, 0, !0, 0); + + unsafe { + let a = i32x4(1, -2, 3, 4); + let b = i32x4(5, 6, -7, 8); + + let r: i32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: i32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: i32x4 = simd_select(m2, a, b); + let e = i32x4(1, -2, -7, 8); + assert_eq!(r, e); + + let r: i32x4 = simd_select(m3, a, b); + let e = i32x4(5, 6, 3, 4); + assert_eq!(r, e); + + let r: i32x4 = simd_select(m4, a, b); + let e = i32x4(1, 6, 3, 8); + assert_eq!(r, e); + } + + unsafe { + let a = u32x4(1, 2, 3, 4); + let b = u32x4(5, 6, 7, 8); + + let r: u32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: u32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: u32x4 = simd_select(m2, a, b); + let e = u32x4(1, 2, 7, 8); + assert_eq!(r, e); + + let r: u32x4 = simd_select(m3, a, b); + let e = u32x4(5, 6, 3, 4); + assert_eq!(r, e); + + let r: u32x4 = simd_select(m4, a, b); + let e = u32x4(1, 6, 3, 8); + assert_eq!(r, e); + } + + unsafe { + let a = f32x4(1., 2., 3., 4.); + let b = f32x4(5., 6., 7., 8.); + + let r: f32x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: f32x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: f32x4 = simd_select(m2, a, b); + let e = f32x4(1., 2., 7., 8.); + assert_eq!(r, e); + + let r: f32x4 = simd_select(m3, a, b); + let e = f32x4(5., 6., 3., 4.); + assert_eq!(r, e); + + let r: f32x4 = simd_select(m4, a, b); + let e = f32x4(1., 6., 3., 8.); + assert_eq!(r, e); + } + + unsafe { + let t = !0 as i8; + let f = 0 as i8; + let a = b8x4(t, f, t, f); + let b = b8x4(f, f, f, t); + + let r: b8x4 = simd_select(m0, a, b); + let e = a; + assert_eq!(r, e); + + let r: b8x4 = simd_select(m1, a, b); + let e = b; + assert_eq!(r, e); + + let r: b8x4 = simd_select(m2, a, b); + let e = b8x4(t, f, f, t); + assert_eq!(r, e); + + let r: b8x4 = simd_select(m3, a, b); + let e = b8x4(f, f, t, f); + assert_eq!(r, e); + + let r: b8x4 = simd_select(m4, a, b); + let e = b8x4(t, f, t, t); + assert_eq!(r, e); + } +} From ce84a41936e367dfeb7d348564f2337819395ca6 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Sun, 18 Mar 2018 13:27:56 -0500 Subject: [PATCH 372/830] Allow raw identifiers in diagnostic macros. --- src/libsyntax/diagnostics/plugin.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index c7e453c9e105..aecf32ab6afb 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -44,7 +44,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, token_tree: &[TokenTree]) -> Box { let code = match (token_tree.len(), token_tree.get(0)) { - (1, Some(&TokenTree::Token(_, token::Ident(code, false)))) => code, + (1, Some(&TokenTree::Token(_, token::Ident(code, _)))) => code, _ => unreachable!() }; @@ -82,10 +82,10 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, token_tree.get(1), token_tree.get(2) ) { - (1, Some(&TokenTree::Token(_, token::Ident(ref code, false))), None, None) => { + (1, Some(&TokenTree::Token(_, token::Ident(ref code, _))), None, None) => { (code, None) }, - (3, Some(&TokenTree::Token(_, token::Ident(ref code, false))), + (3, Some(&TokenTree::Token(_, token::Ident(ref code, _))), Some(&TokenTree::Token(_, token::Comma)), Some(&TokenTree::Token(_, token::Literal(token::StrRaw(description, _), None)))) => { (code, Some(description)) @@ -150,9 +150,9 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, let (crate_name, name) = match (&token_tree[0], &token_tree[2]) { ( // Crate name. - &TokenTree::Token(_, token::Ident(ref crate_name, false)), + &TokenTree::Token(_, token::Ident(ref crate_name, _)), // DIAGNOSTICS ident. - &TokenTree::Token(_, token::Ident(ref name, false)) + &TokenTree::Token(_, token::Ident(ref name, _)) ) => (*&crate_name, name), _ => unreachable!() }; From cca2604e6cf4bf303085d6f38731353621aa39cf Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Sun, 18 Mar 2018 19:55:20 +0100 Subject: [PATCH 373/830] add codegen test --- .../codegen/simd-intrinsic-generic-select.rs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/test/codegen/simd-intrinsic-generic-select.rs diff --git a/src/test/codegen/simd-intrinsic-generic-select.rs b/src/test/codegen/simd-intrinsic-generic-select.rs new file mode 100644 index 000000000000..8a64d7437d84 --- /dev/null +++ b/src/test/codegen/simd-intrinsic-generic-select.rs @@ -0,0 +1,35 @@ +// 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. + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct b8x4(pub i8, pub i8, pub i8, pub i8); + +extern "platform-intrinsic" { + fn simd_select(x: T, a: U, b: U) -> U; +} + +// CHECK-LABEL: @select +#[no_mangle] +pub unsafe fn select(m: b8x4, a: f32x4, b: f32x4) -> f32x4 { + // CHECK: select <4 x i1> + simd_select(m, a, b) +} From 7786f70437f66fb0964ef2685833d2d9d8152b28 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Feb 2018 01:09:30 +0100 Subject: [PATCH 374/830] Add warning for invalid start of code blocks in rustdoc --- src/librustdoc/html/markdown.rs | 7 ++++++- src/librustdoc/markdown.rs | 2 +- src/librustdoc/test.rs | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5e55353a26e6..5ce3d57f82f2 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -27,6 +27,7 @@ #![allow(non_camel_case_types)] +use rustc::session; use std::cell::RefCell; use std::collections::{HashMap, VecDeque}; use std::default::Default; @@ -434,7 +435,8 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { } } -pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) { +pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span, + sess: Option<&session::Session>) { tests.set_position(position); let mut parser = Parser::new(doc); @@ -484,6 +486,9 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp line, filename, block_info.allow_fail); prev_offset = offset; } else { + if let Some(ref sess) = sess { + sess.span_warn(position, "invalid start of a new code block"); + } break; } } diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 0f107457d2bf..3a55b279b5cc 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -152,7 +152,7 @@ pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, true, opts, maybe_sysroot, None, Some(PathBuf::from(input)), linker); - find_testable_code(&input_str, &mut collector, DUMMY_SP); + find_testable_code(&input_str, &mut collector, DUMMY_SP, None); test_args.insert(0, "rustdoctest".to_string()); testing::test_main(&test_args, collector.tests, testing::Options::new().display_output(display_warnings)); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 117b21d47587..707d5a12bbf9 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -645,8 +645,10 @@ impl<'a, 'hir> HirCollector<'a, 'hir> { // the collapse-docs pass won't combine sugared/raw doc attributes, or included files with // anything else, this will combine them for us if let Some(doc) = attrs.collapsed_doc_value() { - markdown::find_testable_code(&doc, self.collector, - attrs.span.unwrap_or(DUMMY_SP)); + markdown::find_testable_code(&doc, + self.collector, + attrs.span.unwrap_or(DUMMY_SP), + Some(self.sess)); } nested(self); From 16da5d4bb2d65a4d533d1da2a4e0d288d3a474c5 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 18 Mar 2018 09:18:18 -0700 Subject: [PATCH 375/830] Add BufReader::buffer This subsumes the need for an explicit is_empty function, and provides access to the buffered data itself which has been requested from time to time. --- src/libstd/io/buffered.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 9250c1c437b2..ccaa19acc837 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -168,8 +168,36 @@ impl BufReader { /// # } /// ``` #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")] + #[rustc_deprecated(since = "1.26.0", reason = "use .buffer().is_empty() instead")] pub fn is_empty(&self) -> bool { - self.pos == self.cap + self.buffer().is_empty() + } + + /// Returns a reference to the internally buffered data. + /// + /// Unlike `fill_buf`, this will not attempt to fill the buffer if it is empty. + /// + /// # Examples + /// + /// ``` + /// # #![feature(bufreader_buffer)] + /// use std::io::{BufReader, BufRead}; + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let f = File::open("log.txt")?; + /// let mut reader = BufReader::new(f); + /// assert!(reader.buffer().is_empty()); + /// + /// if reader.fill_buf()?.len() > 0 { + /// assert!(!reader.buffer().is_empty()); + /// } + /// # Ok(()) + /// # } + /// ``` + #[unstable(feature = "bufreader_buffer", issue = "45323")] + pub fn buffer(&self) -> &[u8] { + &self.buf[self.pos..self.cap] } /// Unwraps this `BufReader`, returning the underlying reader. From 2797aaca77fe5c454f3a3ada84b06912b2f74b9f Mon Sep 17 00:00:00 2001 From: boats Date: Sun, 18 Mar 2018 15:05:45 -0700 Subject: [PATCH 376/830] Update tracking issue. --- src/liballoc/boxed.rs | 24 ++++++++++++------------ src/libcore/marker.rs | 2 +- src/libcore/mem.rs | 28 ++++++++++++++-------------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 46d3ccb9de52..0e71cc59d947 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -898,22 +898,22 @@ impl Generator for Box } /// A pinned, heap allocated reference. -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] #[fundamental] pub struct PinBox { inner: Box, } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl PinBox { /// Allocate memory on the heap, move the data into it and pin it. - #[unstable(feature = "pin", issue = "0")] + #[unstable(feature = "pin", issue = "49150")] pub fn new(data: T) -> PinBox { PinBox { inner: Box::new(data) } } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl PinBox { /// Get a pinned reference to the data in this PinBox. pub fn as_pin<'a>(&'a mut self) -> Pin<'a, T> { @@ -937,21 +937,21 @@ impl PinBox { } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl From> for PinBox { fn from(boxed: Box) -> PinBox { PinBox { inner: boxed } } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl From> for Box { fn from(pinned: PinBox) -> Box { pinned.inner } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl Deref for PinBox { type Target = T; @@ -960,28 +960,28 @@ impl Deref for PinBox { } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl DerefMut for PinBox { fn deref_mut(&mut self) -> &mut T { &mut *self.inner } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl fmt::Display for PinBox { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&*self.inner, f) } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl fmt::Debug for PinBox { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&*self.inner, f) } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl fmt::Pointer for PinBox { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // It's not possible to extract the inner Uniq directly from the Box, @@ -991,5 +991,5 @@ impl fmt::Pointer for PinBox { } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl, U: ?Sized> CoerceUnsized> for PinBox {} diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 7b67404db5d9..9d7f8abff150 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -573,5 +573,5 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {} /// `Pin` pointer. /// /// This trait is automatically implemented for almost every type. -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] pub unsafe auto trait Unpin {} diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index e960b5ae7582..b2467c948b4b 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1111,24 +1111,24 @@ pub unsafe fn unreachable() -> ! { /// A pinned reference is a lot like a mutable reference, except that it is not /// safe to move a value out of a pinned reference unless the type of that /// value implements the `Unpin` trait. -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] #[fundamental] pub struct Pin<'a, T: ?Sized + 'a> { inner: &'a mut T, } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: ?Sized + Unpin> Pin<'a, T> { /// Construct a new `Pin` around a reference to some data of a type that /// implements `Unpin`. - #[unstable(feature = "pin", issue = "0")] + #[unstable(feature = "pin", issue = "49150")] pub fn new(reference: &'a mut T) -> Pin<'a, T> { Pin { inner: reference } } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: ?Sized> Pin<'a, T> { /// Construct a new `Pin` around a reference to some data of a type that /// may or may not implement `Unpin`. @@ -1136,13 +1136,13 @@ impl<'a, T: ?Sized> Pin<'a, T> { /// This constructor is unsafe because we do not know what will happen with /// that data after the reference ends. If you cannot guarantee that the /// data will never move again, calling this constructor is invalid. - #[unstable(feature = "pin", issue = "0")] + #[unstable(feature = "pin", issue = "49150")] pub unsafe fn new_unchecked(reference: &'a mut T) -> Pin<'a, T> { Pin { inner: reference } } /// Borrow a Pin for a shorter lifetime than it already has. - #[unstable(feature = "pin", issue = "0")] + #[unstable(feature = "pin", issue = "49150")] pub fn borrow<'b>(this: &'b mut Pin<'a, T>) -> Pin<'b, T> { Pin { inner: this.inner } } @@ -1152,7 +1152,7 @@ impl<'a, T: ?Sized> Pin<'a, T> { /// This function is unsafe. You must guarantee that you will never move /// the data out of the mutable reference you receive when you call this /// function. - #[unstable(feature = "pin", issue = "0")] + #[unstable(feature = "pin", issue = "49150")] pub unsafe fn get_mut<'b>(this: &'b mut Pin<'a, T>) -> &'b mut T { this.inner } @@ -1166,7 +1166,7 @@ impl<'a, T: ?Sized> Pin<'a, T> { /// will not move so long as the argument value does not move (for example, /// because it is one of the fields of that value), and also that you do /// not move out of the argument you receive to the interior function. - #[unstable(feature = "pin", issue = "0")] + #[unstable(feature = "pin", issue = "49150")] pub unsafe fn map<'b, U, F>(this: &'b mut Pin<'a, T>, f: F) -> Pin<'b, U> where F: FnOnce(&mut T) -> &mut U { @@ -1174,7 +1174,7 @@ impl<'a, T: ?Sized> Pin<'a, T> { } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: ?Sized> Deref for Pin<'a, T> { type Target = T; @@ -1183,33 +1183,33 @@ impl<'a, T: ?Sized> Deref for Pin<'a, T> { } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: ?Sized + Unpin> DerefMut for Pin<'a, T> { fn deref_mut(&mut self) -> &mut T { self.inner } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: fmt::Debug + ?Sized> fmt::Debug for Pin<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: fmt::Display + ?Sized> fmt::Display for Pin<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&**self, f) } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: ?Sized> fmt::Pointer for Pin<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&(&*self.inner as *const T), f) } } -#[unstable(feature = "pin", issue = "0")] +#[unstable(feature = "pin", issue = "49150")] impl<'a, T: ?Sized + Unsize, U: ?Sized> CoerceUnsized> for Pin<'a, T> {} From 4dd45069feda95e06cf8287629caea9c64d9d481 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Sun, 11 Mar 2018 02:21:38 -0300 Subject: [PATCH 377/830] Refactored with high-order functions. --- src/librustc/traits/error_reporting.rs | 42 +++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index c90a6d0709db..5bfeff89e355 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -888,28 +888,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err: &mut DiagnosticBuilder<'tcx>, trait_ref: &ty::Binder>) { let ty::Binder(trait_ref) = trait_ref; - let span = obligation.cause.span; - let mut snippet = match self.tcx.sess.codemap().span_to_snippet(span) { - Ok(s) => s, - Err(_) => String::from(""), - }; - let mut refs_number = 0; + if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) { + let refs_number = snippet.chars() + .filter(|c| !c.is_whitespace()) + .take_while(|c| *c == '&') + .count(); - for c in snippet.chars() { - if c == '&' { - refs_number += 1; - } - } + let mut refs_remaining = refs_number; + let mut trait_type = trait_ref.self_ty(); + let mut selcx = SelectionContext::new(self); - let mut refs_remaining = refs_number; - let mut trait_type = trait_ref.self_ty(); - let mut selcx = SelectionContext::new(self); + while refs_remaining > 0 { + if let ty::TypeVariants::TyRef(_, ty::TypeAndMut{ ty: t_type, mutbl: _ }) = + trait_type.sty { - while refs_remaining > 0 { - if let ty::TypeVariants::TyRef(_, ty::TypeAndMut{ ty: t_type, mutbl: _ }) = - trait_type.sty { trait_type = t_type; refs_remaining -= 1; @@ -920,14 +914,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { new_trait_ref.to_predicate()); if selcx.evaluate_obligation(&new_obligation) { - for i in 0..refs_number { - snippet.remove(i); - } - err.span_suggestion(span, "consider removing `&`s like", format!("{}", snippet)); + let suggest_snippet = snippet.chars() + .skip(refs_number) + .collect::(); + + err.span_suggestion(span, + "consider removing `&`s like", + format!("{}", suggest_snippet)); + + break; } } else { break; } + } } } From e0fb0132c12cc291a866c0ca72334751d3b5a677 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Mon, 12 Mar 2018 23:40:55 -0300 Subject: [PATCH 378/830] Test added. --- src/test/ui/suggest-remove-refs.rs | 18 ++++++++++++++++++ src/test/ui/suggest-remove-refs.stderr | 15 +++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/test/ui/suggest-remove-refs.rs create mode 100644 src/test/ui/suggest-remove-refs.stderr diff --git a/src/test/ui/suggest-remove-refs.rs b/src/test/ui/suggest-remove-refs.rs new file mode 100644 index 000000000000..0f19c48337b1 --- /dev/null +++ b/src/test/ui/suggest-remove-refs.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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() { + let v = vec![0, 1, 2, 3]; + + for (i, n) in &v.iter().enumerate() { + //~^ ERROR the trait bound + println!("{}", i); + } +} diff --git a/src/test/ui/suggest-remove-refs.stderr b/src/test/ui/suggest-remove-refs.stderr new file mode 100644 index 000000000000..d81166e55797 --- /dev/null +++ b/src/test/ui/suggest-remove-refs.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `&std::iter::Enumerate>: std::iter::Iterator` is not satisfied + --> $DIR/suggest-remove-refs.rs:14:19 + | +LL | for (i, n) in &v.iter().enumerate() { + | ^^^^^^^^^^^^^^^^^^^^^ + | | + | `&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | help: consider removing `&`s like: `v.iter().enumerate()` + | + = help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate>` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0277" From f44b945e0ed73c6d108a40655d3bed14133ec7db Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Tue, 13 Mar 2018 01:05:46 -0300 Subject: [PATCH 379/830] New test added. --- ...remove-refs.rs => suggest-remove-refs-1.rs} | 0 ...efs.stderr => suggest-remove-refs-1.stderr} | 4 ++-- src/test/ui/suggest-remove-refs-2.rs | 18 ++++++++++++++++++ src/test/ui/suggest-remove-refs-2.stderr | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) rename src/test/ui/{suggest-remove-refs.rs => suggest-remove-refs-1.rs} (100%) rename src/test/ui/{suggest-remove-refs.stderr => suggest-remove-refs-1.stderr} (84%) create mode 100644 src/test/ui/suggest-remove-refs-2.rs create mode 100644 src/test/ui/suggest-remove-refs-2.stderr diff --git a/src/test/ui/suggest-remove-refs.rs b/src/test/ui/suggest-remove-refs-1.rs similarity index 100% rename from src/test/ui/suggest-remove-refs.rs rename to src/test/ui/suggest-remove-refs-1.rs diff --git a/src/test/ui/suggest-remove-refs.stderr b/src/test/ui/suggest-remove-refs-1.stderr similarity index 84% rename from src/test/ui/suggest-remove-refs.stderr rename to src/test/ui/suggest-remove-refs-1.stderr index d81166e55797..154b67219f67 100644 --- a/src/test/ui/suggest-remove-refs.stderr +++ b/src/test/ui/suggest-remove-refs-1.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `&std::iter::Enumerate>: std::iter::Iterator` is not satisfied - --> $DIR/suggest-remove-refs.rs:14:19 + --> $DIR/suggest-remove-refs-1.rs:14:19 | LL | for (i, n) in &v.iter().enumerate() { | ^^^^^^^^^^^^^^^^^^^^^ | | | `&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method - | help: consider removing `&`s like: `v.iter().enumerate()` + | help: consider removing 1 references `&`: `v.iter().enumerate()` | = help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/suggest-remove-refs-2.rs b/src/test/ui/suggest-remove-refs-2.rs new file mode 100644 index 000000000000..c427f697ae1e --- /dev/null +++ b/src/test/ui/suggest-remove-refs-2.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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() { + let v = vec![0, 1, 2, 3]; + + for (i, n) in & & & & &v.iter().enumerate() { + //~^ ERROR the trait bound + println!("{}", i); + } +} diff --git a/src/test/ui/suggest-remove-refs-2.stderr b/src/test/ui/suggest-remove-refs-2.stderr new file mode 100644 index 000000000000..f394344275aa --- /dev/null +++ b/src/test/ui/suggest-remove-refs-2.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied + --> $DIR/suggest-remove-refs-2.rs:14:19 + | +LL | for (i, n) in & & & & &v.iter().enumerate() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | help: consider removing 5 references `&`: `v.iter().enumerate()` + | + = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0277" From 97b66d2987522d28bb69994e8908a5bb789bff37 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Tue, 13 Mar 2018 01:06:04 -0300 Subject: [PATCH 380/830] Review fixes. - `suggest_snippet` handling space between refs; - Suggest message changing according to the number of refs that should be removed. --- src/librustc/traits/error_reporting.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 5bfeff89e355..31c8cb25c521 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -883,6 +883,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`, + /// suggest removing these references until we reach a type that implements the trait. fn suggest_remove_reference(&self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -896,16 +898,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .take_while(|c| *c == '&') .count(); - let mut refs_remaining = refs_number; let mut trait_type = trait_ref.self_ty(); let mut selcx = SelectionContext::new(self); - while refs_remaining > 0 { + for refs_remaining in 0..refs_number { if let ty::TypeVariants::TyRef(_, ty::TypeAndMut{ ty: t_type, mutbl: _ }) = trait_type.sty { trait_type = t_type; - refs_remaining -= 1; let substs = self.tcx.mk_substs_trait(trait_type, &[]); let new_trait_ref = ty::TraitRef::new(trait_ref.def_id, substs); @@ -914,12 +914,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { new_trait_ref.to_predicate()); if selcx.evaluate_obligation(&new_obligation) { + let remove_refs = refs_remaining + 1; + let suggest_snippet = snippet.chars() - .skip(refs_number) + .filter(|c| !c.is_whitespace()) + .skip(remove_refs) .collect::(); err.span_suggestion(span, - "consider removing `&`s like", + &format!("consider removing {} references `&`", + remove_refs), format!("{}", suggest_snippet)); break; From f41dc775a3ae1f002c24fdff6b2f7c4b68ceca66 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Wed, 14 Mar 2018 06:41:05 -0300 Subject: [PATCH 381/830] Keeping code formatting. Suggesting snippet without changing the original formatting of the code. --- src/librustc/traits/error_reporting.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 31c8cb25c521..1bbd24de6ae4 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -914,11 +914,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { new_trait_ref.to_predicate()); if selcx.evaluate_obligation(&new_obligation) { - let remove_refs = refs_remaining + 1; + let mut remove_refs = refs_remaining + 1; let suggest_snippet = snippet.chars() - .filter(|c| !c.is_whitespace()) - .skip(remove_refs) + .skip_while(|c| c.is_whitespace() || { + if *c == '&' && remove_refs > 0 { + true + } else { + false + } + }) .collect::(); err.span_suggestion(span, From 52cd07aef79223b89109fe392addb905d491de18 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Wed, 14 Mar 2018 06:42:27 -0300 Subject: [PATCH 382/830] Created multiple line test. --- src/test/ui/suggest-remove-refs-3.rs | 21 +++++++++++++++++++++ src/test/ui/suggest-remove-refs-3.stderr | 22 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/test/ui/suggest-remove-refs-3.rs create mode 100644 src/test/ui/suggest-remove-refs-3.stderr diff --git a/src/test/ui/suggest-remove-refs-3.rs b/src/test/ui/suggest-remove-refs-3.rs new file mode 100644 index 000000000000..f54ae30caebc --- /dev/null +++ b/src/test/ui/suggest-remove-refs-3.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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() { + let v = vec![0, 1, 2, 3]; + + for (i, n) in & & & + & &v + .iter() + .enumerate() { + //~^^^^ ERROR the trait bound + println!("{}", i); + } +} diff --git a/src/test/ui/suggest-remove-refs-3.stderr b/src/test/ui/suggest-remove-refs-3.stderr new file mode 100644 index 000000000000..7add72adf4d3 --- /dev/null +++ b/src/test/ui/suggest-remove-refs-3.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied + --> $DIR/suggest-remove-refs-3.rs:14:19 + | +LL | for (i, n) in & & & + | ___________________^ +LL | | & &v +LL | | .iter() +LL | | .enumerate() { + | |____________________^ `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method + | + = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` + = note: required by `std::iter::IntoIterator::into_iter` +help: consider removing 5 references `&` + | +LL | for (i, n) in v +LL | .iter() +LL | .enumerate() { + | + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0277" From f6bffd16d15672557e7d9c32b0cca08639a32251 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Wed, 14 Mar 2018 12:49:06 -0300 Subject: [PATCH 383/830] Rebased with master. --- src/librustc_traits/normalize_projection_ty.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/test/ui/suggest-remove-refs-1.stderr | 2 +- src/test/ui/suggest-remove-refs-2.stderr | 2 +- src/test/ui/suggest-remove-refs-3.stderr | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 55785d9586cc..171bc1bd2d6d 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -36,7 +36,7 @@ crate fn normalize_projection_ty<'tcx>( ) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal); let fulfill_cx = &mut FulfillmentContext::new(); let selcx = &mut SelectionContext::new(infcx); - let cause = ObligationCause::misc(DUMMY_SP, DUMMY_NODE_ID); + let cause = ObligationCause::misc(DUMMY_SP, DUMMY_NODE_ID, DUMMY_NODE_ID); let Normalized { value: answer, obligations, diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 596381d7ea67..4943560d68be 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -298,7 +298,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( }; let parent_scope = rcx.tcx.mk_region(ty::ReScope(parent_scope)); let origin = || infer::SubregionOrigin::SafeDestructor(span); - let cause = &ObligationCause::misc(span, body_id); + let cause = &ObligationCause::misc(span, body_id, body_id); let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty); debug!("dropck_outlives = {:#?}", infer_ok); let kinds = rcx.fcx.register_infer_ok_obligations(infer_ok); diff --git a/src/test/ui/suggest-remove-refs-1.stderr b/src/test/ui/suggest-remove-refs-1.stderr index 154b67219f67..fe4ab2c4ee05 100644 --- a/src/test/ui/suggest-remove-refs-1.stderr +++ b/src/test/ui/suggest-remove-refs-1.stderr @@ -12,4 +12,4 @@ LL | for (i, n) in &v.iter().enumerate() { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggest-remove-refs-2.stderr b/src/test/ui/suggest-remove-refs-2.stderr index f394344275aa..243ddcfe125e 100644 --- a/src/test/ui/suggest-remove-refs-2.stderr +++ b/src/test/ui/suggest-remove-refs-2.stderr @@ -12,4 +12,4 @@ LL | for (i, n) in & & & & &v.iter().enumerate() { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggest-remove-refs-3.stderr b/src/test/ui/suggest-remove-refs-3.stderr index 7add72adf4d3..83f3826642b2 100644 --- a/src/test/ui/suggest-remove-refs-3.stderr +++ b/src/test/ui/suggest-remove-refs-3.stderr @@ -19,4 +19,4 @@ LL | .enumerate() { error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0277" +For more information about this error, try `rustc --explain E0277`. From c1ba5ac62c14ab5e231edcce914fd33f0e32c2d1 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Fri, 16 Mar 2018 17:58:11 -0300 Subject: [PATCH 384/830] Reporting with `span_suggestion_short`. --- src/librustc/traits/error_reporting.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 1bbd24de6ae4..267d84cc5314 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -914,22 +914,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { new_trait_ref.to_predicate()); if selcx.evaluate_obligation(&new_obligation) { - let mut remove_refs = refs_remaining + 1; + let remove_refs = refs_remaining + 1; - let suggest_snippet = snippet.chars() - .skip_while(|c| c.is_whitespace() || { - if *c == '&' && remove_refs > 0 { - true - } else { - false - } - }) - .collect::(); - - err.span_suggestion(span, - &format!("consider removing {} references `&`", - remove_refs), - format!("{}", suggest_snippet)); + err.span_suggestion_short(span, + &format!("consider removing {} leading `&`-references", + remove_refs), + String::from("")); break; } From 74a4928ed49d000dee9827c21f68148ad3aa271e Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Sat, 17 Mar 2018 15:41:46 -0300 Subject: [PATCH 385/830] Review fixes. - `span_suggestion` changed to `span_suggestion_short`; - `Span` used changed to contain only `&` refs; - Tests passing. --- src/librustc/traits/error_reporting.rs | 11 ++++++----- src/libsyntax/codemap.rs | 16 ++++++++++++++++ src/test/ui/suggest-remove-refs-1.stderr | 4 ++-- src/test/ui/suggest-remove-refs-2.stderr | 4 ++-- src/test/ui/suggest-remove-refs-3.stderr | 21 +++++++++------------ 5 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 267d84cc5314..9b01f8899b52 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -914,13 +914,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { new_trait_ref.to_predicate()); if selcx.evaluate_obligation(&new_obligation) { + let sp = self.tcx.sess.codemap() + .span_take_while(span, |c| c.is_whitespace() || *c == '&'); + let remove_refs = refs_remaining + 1; + let format_str = format!("consider removing {} leading `&`-references", + remove_refs); - err.span_suggestion_short(span, - &format!("consider removing {} leading `&`-references", - remove_refs), - String::from("")); - + err.span_suggestion_short(sp, &format_str, String::from("")); break; } } else { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index a1aec0520885..324d57c11945 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -697,6 +697,22 @@ impl CodeMap { sp } + /// Given a `Span`, get a shorter one until `predicate` yields false. + pub fn span_take_while

(&self, sp: Span, predicate: P) -> Span + where P: for <'r> FnMut(&'r char) -> bool + { + if let Ok(snippet) = self.span_to_snippet(sp) { + let offset = snippet.chars() + .take_while(predicate) + .map(|c| c.len_utf8()) + .sum::(); + + sp.with_hi(BytePos(sp.lo().0 + (offset as u32))) + } else { + sp + } + } + pub fn def_span(&self, sp: Span) -> Span { self.span_until_char(sp, '{') } diff --git a/src/test/ui/suggest-remove-refs-1.stderr b/src/test/ui/suggest-remove-refs-1.stderr index fe4ab2c4ee05..c47b4d283d7c 100644 --- a/src/test/ui/suggest-remove-refs-1.stderr +++ b/src/test/ui/suggest-remove-refs-1.stderr @@ -2,10 +2,10 @@ error[E0277]: the trait bound `&std::iter::Enumerate $DIR/suggest-remove-refs-1.rs:14:19 | LL | for (i, n) in &v.iter().enumerate() { - | ^^^^^^^^^^^^^^^^^^^^^ + | -^^^^^^^^^^^^^^^^^^^^ | | | `&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method - | help: consider removing 1 references `&`: `v.iter().enumerate()` + | help: consider removing 1 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/suggest-remove-refs-2.stderr b/src/test/ui/suggest-remove-refs-2.stderr index 243ddcfe125e..fdd654ea3923 100644 --- a/src/test/ui/suggest-remove-refs-2.stderr +++ b/src/test/ui/suggest-remove-refs-2.stderr @@ -2,10 +2,10 @@ error[E0277]: the trait bound `&&&&&std::iter::Enumerate $DIR/suggest-remove-refs-2.rs:14:19 | LL | for (i, n) in & & & & &v.iter().enumerate() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ---------^^^^^^^^^^^^^^^^^^^^ | | | `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method - | help: consider removing 5 references `&`: `v.iter().enumerate()` + | help: consider removing 5 leading `&`-references | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/suggest-remove-refs-3.stderr b/src/test/ui/suggest-remove-refs-3.stderr index 83f3826642b2..b0920a0fa523 100644 --- a/src/test/ui/suggest-remove-refs-3.stderr +++ b/src/test/ui/suggest-remove-refs-3.stderr @@ -1,21 +1,18 @@ error[E0277]: the trait bound `&&&&&std::iter::Enumerate>: std::iter::Iterator` is not satisfied --> $DIR/suggest-remove-refs-3.rs:14:19 | -LL | for (i, n) in & & & - | ___________________^ -LL | | & &v -LL | | .iter() -LL | | .enumerate() { - | |____________________^ `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method +LL | for (i, n) in & & & + | ___________________^ + | |___________________| + | || +LL | || & &v + | ||___________- help: consider removing 5 leading `&`-references +LL | | .iter() +LL | | .enumerate() { + | |_____________________^ `&&&&&std::iter::Enumerate>` is not an iterator; maybe try calling `.iter()` or a similar method | = help: the trait `std::iter::Iterator` is not implemented for `&&&&&std::iter::Enumerate>` = note: required by `std::iter::IntoIterator::into_iter` -help: consider removing 5 references `&` - | -LL | for (i, n) in v -LL | .iter() -LL | .enumerate() { - | error: aborting due to previous error From 0b36b20651704cf7051f468aeb3b84babf940e63 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Sun, 18 Mar 2018 10:05:20 -0300 Subject: [PATCH 386/830] CodeMap functions refactored. - Using `span_take_while` to implement others. --- src/libsyntax/codemap.rs | 90 +++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 324d57c11945..73924c4270e6 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -597,21 +597,6 @@ impl CodeMap { self.span_to_source(sp, |src, start_index, _| src[..start_index].to_string()) } - /// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char` - pub fn span_until_char(&self, sp: Span, c: char) -> Span { - match self.span_to_snippet(sp) { - Ok(snippet) => { - let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right(); - if !snippet.is_empty() && !snippet.contains('\n') { - sp.with_hi(BytePos(sp.lo().0 + snippet.len() as u32)) - } else { - sp - } - } - _ => sp, - } - } - /// Extend the given `Span` to just after the previous occurrence of `c`. Return the same span /// if no character could be found or if an error occurred while retrieving the code snippet. pub fn span_extend_to_prev_char(&self, sp: Span, c: char) -> Span { @@ -646,44 +631,19 @@ impl CodeMap { sp } - /// Given a `Span`, get a new `Span` covering the first token and all its trailing whitespace or - /// the original `Span`. - /// - /// If `sp` points to `"let mut x"`, then a span pointing at `"let "` will be returned. - pub fn span_until_non_whitespace(&self, sp: Span) -> Span { - if let Ok(snippet) = self.span_to_snippet(sp) { - let mut offset = 0; - // get the bytes width of all the non-whitespace characters - for c in snippet.chars().take_while(|c| !c.is_whitespace()) { - offset += c.len_utf8(); - } - // get the bytes width of all the whitespace characters after that - for c in snippet[offset..].chars().take_while(|c| c.is_whitespace()) { - offset += c.len_utf8(); - } - if offset > 1 { - return sp.with_hi(BytePos(sp.lo().0 + offset as u32)); + /// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char` + pub fn span_until_char(&self, sp: Span, c: char) -> Span { + match self.span_to_snippet(sp) { + Ok(snippet) => { + let snippet = snippet.split(c).nth(0).unwrap_or("").trim_right(); + if !snippet.is_empty() && !snippet.contains('\n') { + sp.with_hi(BytePos(sp.lo().0 + snippet.len() as u32)) + } else { + sp + } } + _ => sp, } - sp - } - - /// Given a `Span`, get a new `Span` covering the first token without its trailing whitespace or - /// the original `Span` in case of error. - /// - /// If `sp` points to `"let mut x"`, then a span pointing at `"let"` will be returned. - pub fn span_until_whitespace(&self, sp: Span) -> Span { - if let Ok(snippet) = self.span_to_snippet(sp) { - let mut offset = 0; - // Get the bytes width of all the non-whitespace characters - for c in snippet.chars().take_while(|c| !c.is_whitespace()) { - offset += c.len_utf8(); - } - if offset > 1 { - return sp.with_hi(BytePos(sp.lo().0 + offset as u32)); - } - } - sp } /// Given a `Span`, try to get a shorter span ending just after the first occurrence of `char` @@ -697,6 +657,34 @@ impl CodeMap { sp } + /// Given a `Span`, get a new `Span` covering the first token and all its trailing whitespace or + /// the original `Span`. + /// + /// If `sp` points to `"let mut x"`, then a span pointing at `"let "` will be returned. + pub fn span_until_non_whitespace(&self, sp: Span) -> Span { + let mut whitespace_found = false; + + self.span_take_while(sp, |c| { + if !whitespace_found && c.is_whitespace() { + whitespace_found = true; + } + + if whitespace_found && !c.is_whitespace() { + false + } else { + true + } + }) + } + + /// Given a `Span`, get a new `Span` covering the first token without its trailing whitespace or + /// the original `Span` in case of error. + /// + /// If `sp` points to `"let mut x"`, then a span pointing at `"let"` will be returned. + pub fn span_until_whitespace(&self, sp: Span) -> Span { + self.span_take_while(sp, |c| !c.is_whitespace()) + } + /// Given a `Span`, get a shorter one until `predicate` yields false. pub fn span_take_while

(&self, sp: Span, predicate: P) -> Span where P: for <'r> FnMut(&'r char) -> bool From 736ba433ac2f0d2f6604a64f744f86a311a56be4 Mon Sep 17 00:00:00 2001 From: Yukio Siraichi Date: Sun, 18 Mar 2018 20:58:56 -0300 Subject: [PATCH 387/830] Cleaned comments and extras s. --- src/librustc/traits/error_reporting.rs | 38 ------------------- .../normalize_projection_ty.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- 3 files changed, 2 insertions(+), 40 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 9b01f8899b52..ab3c619dcdcd 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -575,44 +575,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { = self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); - // { - // let ty::Binder(trait_ref) = trait_ref; - // println!("TraitRef: {:?}", trait_ref); - // println!("TraitRef: id:{:?}; subst:{:?}", trait_ref.def_id, trait_ref.substs); - - // if let ty::Predicate::Trait(trait_predicate_binder) = - // trait_ref.to_predicate() { - // let trait_predicate = trait_predicate_binder.skip_binder(); - // println!("TraitPredicateBinder: {:?}", trait_predicate_binder); - // println!("TraitPredicate: {:?}", trait_predicate); - - // let trait_ty = trait_ref.self_ty(); - // println!("TraitPredicateTy: {:?}", trait_ty); - // println!("TraitPredicateTy: sty:{:?}; flags{:?}", trait_ty.sty, trait_ty.flags); - // } - - // for in_ty in trait_ref.input_types() { - // println!("\t- {:?}", in_ty); - // println!("\t\t- sty:{:?}; flags:{:?}", in_ty.sty, in_ty.flags); - // } - - // println!("Message: {:?}", message); - // println!("Label: {:?}", label); - // println!("Obligation: {:?}", obligation); - // println!("Span: {:?}", self.tcx.sess.codemap().span_to_string(span)); - - // let body_id = obligation.cause.body_id; - // println!("BodyId: {:?}", body_id); - // println!("BodyIdSpan: {:?}", self.tcx.hir.span(body_id)); - - // match self.tcx.hir.find(body_id) { - // Some(node) => println!("Node: {:?}", node), - // None => println!("Node not found."), - // } - - // println!("=------------------------------="); - // } - let mut err = struct_span_err!( self.tcx.sess, span, diff --git a/src/librustc_traits/normalize_projection_ty.rs b/src/librustc_traits/normalize_projection_ty.rs index 171bc1bd2d6d..55785d9586cc 100644 --- a/src/librustc_traits/normalize_projection_ty.rs +++ b/src/librustc_traits/normalize_projection_ty.rs @@ -36,7 +36,7 @@ crate fn normalize_projection_ty<'tcx>( ) = infcx.instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &goal); let fulfill_cx = &mut FulfillmentContext::new(); let selcx = &mut SelectionContext::new(infcx); - let cause = ObligationCause::misc(DUMMY_SP, DUMMY_NODE_ID, DUMMY_NODE_ID); + let cause = ObligationCause::misc(DUMMY_SP, DUMMY_NODE_ID); let Normalized { value: answer, obligations, diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 4943560d68be..596381d7ea67 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -298,7 +298,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'gcx, 'tcx>( }; let parent_scope = rcx.tcx.mk_region(ty::ReScope(parent_scope)); let origin = || infer::SubregionOrigin::SafeDestructor(span); - let cause = &ObligationCause::misc(span, body_id, body_id); + let cause = &ObligationCause::misc(span, body_id); let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty); debug!("dropck_outlives = {:#?}", infer_ok); let kinds = rcx.fcx.register_infer_ok_obligations(infer_ok); From eca1e18cd7021f01757640c0c5ef63717870686c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 00:11:47 +0000 Subject: [PATCH 388/830] Add stability test for sort_by_cached_key --- src/liballoc/tests/slice.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index 7d4dac1c5ec9..66c7dd75c874 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -485,7 +485,7 @@ fn test_sort_stability() { // the second item represents which occurrence of that // number this element is, i.e. the second elements // will occur in sorted order. - let mut v: Vec<_> = (0..len) + let mut orig: Vec<_> = (0..len) .map(|_| { let n = thread_rng().gen::() % 10; counts[n] += 1; @@ -493,16 +493,21 @@ fn test_sort_stability() { }) .collect(); - // only sort on the first element, so an unstable sort + let mut v = orig.clone(); + // Only sort on the first element, so an unstable sort // may mix up the counts. v.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); - // this comparison includes the count (the second item + // This comparison includes the count (the second item // of the tuple), so elements with equal first items // will need to be ordered with increasing // counts... i.e. exactly asserting that this sort is // stable. assert!(v.windows(2).all(|w| w[0] <= w[1])); + + let mut v = orig.clone(); + v.sort_by_cached_key(|&(x, _)| x); + assert!(v.windows(2).all(|w| w[0] <= w[1])); } } } From ca476dd8d3f0fa51f715d0de16800392cff82dd3 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 01:34:32 +0000 Subject: [PATCH 389/830] Revert "Remove useless powerpc64 entry from ARCH_TABLE, closes #47737" This reverts commit 16ac85ce4dce1e185f2e6ce27df3833e07a9e502. --- src/test/codegen/abi-main-signature-16bit-c-int.rs | 1 + src/test/codegen/fastcall-inreg.rs | 2 ++ src/test/codegen/global_asm.rs | 2 ++ src/test/codegen/global_asm_include.rs | 2 ++ src/test/codegen/global_asm_x2.rs | 2 ++ src/test/codegen/repr-transparent-aggregates-1.rs | 1 + src/tools/compiletest/src/util.rs | 1 + 7 files changed, 11 insertions(+) diff --git a/src/test/codegen/abi-main-signature-16bit-c-int.rs b/src/test/codegen/abi-main-signature-16bit-c-int.rs index 707531bf376a..367d509cadfe 100644 --- a/src/test/codegen/abi-main-signature-16bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-16bit-c-int.rs @@ -19,6 +19,7 @@ // ignore-mips // ignore-mips64 // ignore-powerpc +// ignore-powerpc64 // ignore-s390x // ignore-sparc // ignore-wasm32 diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs index 9bfe47d0a1f2..d6dd3f356b5f 100644 --- a/src/test/codegen/fastcall-inreg.rs +++ b/src/test/codegen/fastcall-inreg.rs @@ -23,6 +23,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm.rs b/src/test/codegen/global_asm.rs index 94b69a6cab58..6b79e79fa008 100644 --- a/src/test/codegen/global_asm.rs +++ b/src/test/codegen/global_asm.rs @@ -19,6 +19,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm_include.rs b/src/test/codegen/global_asm_include.rs index c3688077f221..3f73a1cabbf1 100644 --- a/src/test/codegen/global_asm_include.rs +++ b/src/test/codegen/global_asm_include.rs @@ -19,6 +19,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/global_asm_x2.rs b/src/test/codegen/global_asm_x2.rs index 3b8fe43fa048..3e118a50d454 100644 --- a/src/test/codegen/global_asm_x2.rs +++ b/src/test/codegen/global_asm_x2.rs @@ -19,6 +19,8 @@ // ignore-mips // ignore-mips64 // ignore-msp430 +// ignore-powerpc64 +// ignore-powerpc64le // ignore-powerpc // ignore-r600 // ignore-amdgcn diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 655e67cf7eef..2eeed2b788ce 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -14,6 +14,7 @@ // ignore-mips // ignore-mips64 // ignore-powerpc +// ignore-powerpc64 // See repr-transparent.rs #![crate_type="lib"] diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 0e3fa25b13ce..8c889cc48070 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -44,6 +44,7 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("mips", "mips"), ("msp430", "msp430"), ("powerpc", "powerpc"), + ("powerpc64", "powerpc64"), ("s390x", "s390x"), ("sparc", "sparc"), ("x86_64", "x86_64"), From a185b56b7caca17c7aa9d6f702fe1b2209c82e4e Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 18 Mar 2018 23:02:06 +0900 Subject: [PATCH 390/830] Address review comments --- src/librustc_driver/lib.rs | 8 +++++--- src/libstd/rt.rs | 15 +++++++++++++++ src/libstd/sys/unix/thread.rs | 20 +++++++++++++++++++- src/libstd/thread/mod.rs | 8 -------- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 761797239412..e39a2c2f5dcd 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1476,13 +1476,15 @@ pub fn in_rustc_thread(f: F) -> Result> } else if rlim.rlim_max < STACK_SIZE as libc::rlim_t { true } else { + std::rt::deinit_stack_guard(); rlim.rlim_cur = STACK_SIZE as libc::rlim_t; if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { let err = io::Error::last_os_error(); - error!("in_rustc_thread: error calling setrlimit: {}", err); - true + // We have already deinited the stack. Further corruption is + // not allowed. + panic!("in_rustc_thread: error calling setrlimit: {}", err); } else { - std::thread::update_stack_guard(); + std::rt::update_stack_guard(); false } } diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs index e1392762a59d..8f945470b7e9 100644 --- a/src/libstd/rt.rs +++ b/src/libstd/rt.rs @@ -73,3 +73,18 @@ fn lang_start { lang_start_internal(&move || main().report(), argc, argv) } + +/// Function used for reverting changes to the main stack before setrlimit(). +/// This is POSIX (non-Linux) specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn deinit_stack_guard() { + ::sys::thread::guard::deinit(); +} + +/// Function used for resetting the main stack guard address after setrlimit(). +/// This is POSIX specific and unlikely to be directly stabilized. +#[unstable(feature = "rustc_stack_internals", issue = "0")] +pub unsafe fn update_stack_guard() { + let main_guard = ::sys::thread::guard::init(); + ::sys_common::thread_info::reset_guard(main_guard); +} diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 72cdb9440b8e..d94e11a5207c 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -222,7 +222,7 @@ pub mod guard { #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc; - use libc::mmap; + use libc::{mmap, munmap}; use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; use ops::Range; use sys::os; @@ -336,6 +336,24 @@ pub mod guard { } } + pub unsafe fn deinit() { + if !cfg!(target_os = "linux") { + if let Some(mut stackaddr) = get_stack_start() { + // Ensure address is aligned. Same as above. + let remainder = (stackaddr as usize) % PAGE_SIZE; + if remainder != 0 { + stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) + as *mut libc::c_void; + } + + // Undo the guard page mapping. + if munmap(stackaddr, PAGE_SIZE) != 0 { + panic!("unable to deallocate the guard page"); + } + } + } + } + #[cfg(any(target_os = "macos", target_os = "bitrig", target_os = "openbsd", diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index b686ddc205ea..71aee673cfe3 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -208,14 +208,6 @@ pub use self::local::{LocalKey, AccessError}; #[unstable(feature = "libstd_thread_internals", issue = "0")] #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner; -/// Function used for resetting the main stack guard address after setrlimit(). -/// This is POSIX specific and unlikely to be directly stabilized. -#[unstable(feature = "rustc_stack_internals", issue = "0")] -pub unsafe fn update_stack_guard() { - let main_guard = imp::guard::init(); - thread_info::reset_guard(main_guard); -} - //////////////////////////////////////////////////////////////////////////////// // Builder //////////////////////////////////////////////////////////////////////////////// From 1578b1edc0a1ac9dfa289d369d88bcd0a7db22e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 16 Mar 2018 20:11:48 +0100 Subject: [PATCH 391/830] Update submodules in parallel --- src/ci/init_repo.sh | 72 ++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index 8ab4276fa3b0..f2664e6d196c 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -17,6 +17,7 @@ ci_dir=$(cd $(dirname $0) && pwd) . "$ci_dir/shared.sh" travis_fold start init_repo +travis_time_start REPO_DIR="$1" CACHE_DIR="$2" @@ -42,54 +43,39 @@ if grep -q RUST_RELEASE_CHANNEL=beta src/ci/run.sh; then git fetch origin --unshallow beta master fi -travis_fold start update_cache -travis_time_start +function fetch_submodule { + local module=$1 + local cached="download-${module//\//-}.tar.gz" + retry sh -c "rm -f $cached && \ + curl -sSL -o $cached $2" + mkdir $module + touch "$module/.git" + tar -C $module --strip-components=1 -xf $cached + rm $cached +} -# Update the cache (a pristine copy of the rust source master) -retry sh -c "rm -rf $cache_src_dir && mkdir -p $cache_src_dir && \ - git clone --depth 1 https://github.com/rust-lang/rust.git $cache_src_dir" -if [ -d $cache_src_dir/src/llvm ]; then - (cd $cache_src_dir && git rm src/llvm) -fi -if [ -d $cache_src_dir/src/llvm-emscripten ]; then - (cd $cache_src_dir && git rm src/llvm-emscripten) -fi -retry sh -c "cd $cache_src_dir && \ - git submodule deinit -f . && git submodule sync && git submodule update --init" - -travis_fold end update_cache -travis_time_finish - -travis_fold start update_submodules -travis_time_start - -# Update the submodules of the repo we're in, using the pristine repo as -# a cache for any object files -# No, `git submodule foreach` won't work: -# http://stackoverflow.com/questions/12641469/list-submodules-in-a-git-repository +included="src/llvm src/llvm-emscripten src/doc/book src/doc/rust-by-example" modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)" -for module in $modules; do - if [ "$module" = src/llvm ] || [ "$module" = src/llvm-emscripten ]; then +modules=($modules) +use_git="" +urls="$(git config --file .gitmodules --get-regexp '\.url$' | cut -d' ' -f2)" +urls=($urls) +for i in ${!modules[@]}; do + module=${modules[$i]} + if [[ " $included " = *" $module "* ]]; then commit="$(git ls-tree HEAD $module | awk '{print $3}')" git rm $module - retry sh -c "rm -f $commit.tar.gz && \ - curl -sSL -O https://github.com/rust-lang/llvm/archive/$commit.tar.gz" - tar -C src/ -xf "$commit.tar.gz" - rm "$commit.tar.gz" - mv "src/llvm-$commit" $module + url=${urls[$i]} + url=${url/\.git/} + fetch_submodule $module "$url/archive/$commit.tar.gz" & continue + else + use_git="$use_git $module" fi - if [ ! -e "$cache_src_dir/$module/.git" ]; then - echo "WARNING: $module not found in pristine repo" - retry sh -c "git submodule deinit -f $module && \ - git submodule update --init --recursive $module" - continue - fi - retry sh -c "git submodule deinit -f $module && \ - git submodule update --init --recursive --reference $cache_src_dir/$module $module" done - -travis_fold end update_submodules -travis_time_finish - +retry sh -c "git submodule deinit -f $use_git && \ + git submodule sync && \ + git submodule update -j 16 --init --recursive $use_git" +wait travis_fold end init_repo +travis_time_finish From c5c650d670f5f191ea9667b455c15a607e550fdb Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 00:26:41 -0500 Subject: [PATCH 392/830] Split out termination_trait_test feature gate --- src/libsyntax/feature_gate.rs | 3 +++ src/libsyntax/test.rs | 8 +++---- .../feature-gate-termination_trait_test.rs | 22 +++++++++++++++++++ .../termination-trait-in-test.rs | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/feature-gate-termination_trait_test.rs diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fa600cd68606..0950965233f6 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -432,6 +432,9 @@ declare_features! ( // Termination trait in main (RFC 1937) (active, termination_trait, "1.24.0", Some(43301), None), + // Termination trait in tests (RFC 1937) + (active, termination_trait_test, "1.24.0", Some(48854), None), + // Allows use of the :lifetime macro fragment specifier (active, macro_lifetime_matcher, "1.24.0", Some(46895), None), diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 9edfa767d319..d107ab59a9ad 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -332,7 +332,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { ast::ItemKind::Fn(ref decl, _, _, _, ref generics, _) => { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait { + let output_matches = if cx.features.termination_trait_test { true } else { let no_output = match decl.output { @@ -359,7 +359,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { match has_test_signature(cx, i) { Yes => true, No => { - if cx.features.termination_trait { + if cx.features.termination_trait_test { diag.span_err(i.span, "functions used as tests can not have any arguments"); } else { diag.span_err(i.span, "functions used as tests must have signature fn() -> ()"); @@ -388,7 +388,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { // If the termination trait is active, the compiler will check that the output // type implements the `Termination` trait as `libtest` enforces that. - let output_matches = if cx.features.termination_trait { + let output_matches = if cx.features.termination_trait_test { true } else { let no_output = match decl.output { @@ -416,7 +416,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool { if has_bench_attr && !has_bench_signature { let diag = cx.span_diagnostic; - if cx.features.termination_trait { + if cx.features.termination_trait_test { diag.span_err(i.span, "functions used as benches must have signature \ `fn(&mut Bencher) -> impl Termination`"); } else { diff --git a/src/test/compile-fail/feature-gate-termination_trait_test.rs b/src/test/compile-fail/feature-gate-termination_trait_test.rs new file mode 100644 index 000000000000..4af7e9467162 --- /dev/null +++ b/src/test/compile-fail/feature-gate-termination_trait_test.rs @@ -0,0 +1,22 @@ +// 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. + +// compile-flags: --test + +fn main() {} + +#[cfg(test)] +mod tests { + #[test] + fn it_works() -> Result<(), ()> { + //~^ ERROR functions used as tests must have signature fn() -> () + Ok(()) + } +} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs index 494500d522ab..11997eb69172 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-in-test.rs @@ -10,7 +10,7 @@ // compile-flags: --test -#![feature(termination_trait)] +#![feature(termination_trait_test)] #![feature(test)] extern crate test; From 612c4a95bce4c4dc0cddc5ab374fcb262039aede Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 6 Mar 2018 23:17:49 -0500 Subject: [PATCH 393/830] Impl Integer methods for Wrapping Wrapping now implements: count_ones, count_zeros, leading_zeros, trailing_zeros, rotate_left, rotate_right, swap_bytes, from_be, from_le, to_be, to_le, and pow where T is: u8, u16, u32, u64, usize, i8, i16, i32, i64, or isize. Docs were written for all these methods, as well as examples. The examples mirror the ones on u8, u16, etc... for consistency. Closes #32463 --- src/libcore/num/wrapping.rs | 299 ++++++++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index ae1b0b3ce11b..6c110aa05231 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -317,11 +317,307 @@ macro_rules! wrapping_impl { } forward_ref_unop! { impl Neg, neg for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } + )*) } wrapping_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } +macro_rules! wrapping_int_impl { + ($($t:ty)*) => ($( + impl Wrapping<$t> { + /// Returns the number of ones in the binary representation of + /// `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-0b1000_0000); + /// + /// assert_eq!(n.count_ones(), 1); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn count_ones(self) -> u32 { + self.0.count_ones() + } + + /// Returns the number of zeros in the binary representation of + /// `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-0b1000_0000); + /// + /// assert_eq!(n.count_zeros(), 7); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn count_zeros(self) -> u32 { + self.0.count_zeros() + } + + /// Returns the number of leading zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-1); + /// + /// assert_eq!(n.leading_zeros(), 0); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn leading_zeros(self) -> u32 { + self.0.leading_zeros() + } + + /// Returns the number of trailing zeros in the binary representation + /// of `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(-4); + /// + /// assert_eq!(n.trailing_zeros(), 2); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn trailing_zeros(self) -> u32 { + self.0.trailing_zeros() + } + + /// Shifts the bits to the left by a specified amount, `n`, + /// wrapping the truncated bits to the end of the resulting + /// integer. + /// + /// Please note this isn't the same operation as `>>`! + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// let m: Wrapping = Wrapping(-0x76543210FEDCBA99); + /// + /// assert_eq!(n.rotate_left(32), m); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn rotate_left(self, n: u32) -> Self { + Wrapping(self.0.rotate_left(n)) + } + + /// Shifts the bits to the right by a specified amount, `n`, + /// wrapping the truncated bits to the beginning of the resulting + /// integer. + /// + /// Please note this isn't the same operation as `<<`! + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// let m: Wrapping = Wrapping(-0xFEDCBA987654322); + /// + /// assert_eq!(n.rotate_right(4), m); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn rotate_right(self, n: u32) -> Self { + Wrapping(self.0.rotate_right(n)) + } + + /// Reverses the byte order of the integer. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0b0000000_01010101); + /// assert_eq!(n, Wrapping(85)); + /// + /// let m = n.swap_bytes(); + /// + /// assert_eq!(m, Wrapping(0b01010101_00000000)); + /// assert_eq!(m, Wrapping(21760)); + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn swap_bytes(self) -> Self { + Wrapping(self.0.swap_bytes()) + } + + /// Converts an integer from big endian to the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(Wrapping::::from_be(n), n); + /// } else { + /// assert_eq!(Wrapping::::from_be(n), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn from_be(x: Self) -> Self { + Wrapping(<$t>::from_be(x.0)) + } + + /// Converts an integer from little endian to the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(Wrapping::::from_le(n), n); + /// } else { + /// assert_eq!(Wrapping::::from_le(n), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn from_le(x: Self) -> Self { + Wrapping(<$t>::from_le(x.0)) + } + + /// Converts `self` to big endian from the target's endianness. + /// + /// On big endian this is a no-op. On little endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "big") { + /// assert_eq!(n.to_be(), n); + /// } else { + /// assert_eq!(n.to_be(), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn to_be(self) -> Self { + Wrapping(self.0.to_be()) + } + + /// Converts `self` to little endian from the target's endianness. + /// + /// On little endian this is a no-op. On big endian the bytes are + /// swapped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); + /// + /// if cfg!(target_endian = "little") { + /// assert_eq!(n.to_le(), n); + /// } else { + /// assert_eq!(n.to_le(), n.swap_bytes()); + /// } + /// ``` + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn to_le(self) -> Self { + Wrapping(self.0.to_le()) + } + + /// Raises self to the power of `exp`, using exponentiation by + /// squaring. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// let x: Wrapping = Wrapping(2); // or any other integer type + /// + /// assert_eq!(x.pow(4), Wrapping(16)); + #[inline] + #[unstable(feature = "wrapping_int_impl", issue = "32463")] + pub fn pow(self, exp: u32) -> Self { + Wrapping(self.0.pow(exp)) + } + } + )*) +} + +wrapping_int_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } + + mod shift_max { #![allow(non_upper_case_globals)] @@ -355,3 +651,6 @@ mod shift_max { pub const u64: u32 = i64; pub use self::platform::usize; } + + + From 5258af398aced119ad5ac40192fa131a2f2827d4 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Thu, 8 Mar 2018 02:31:15 -0500 Subject: [PATCH 394/830] Make Wrapping::pow use wrapping_pow, add example --- src/libcore/num/wrapping.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index 6c110aa05231..fb79ddd09517 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -606,10 +606,23 @@ macro_rules! wrapping_int_impl { /// let x: Wrapping = Wrapping(2); // or any other integer type /// /// assert_eq!(x.pow(4), Wrapping(16)); + /// ``` + /// + /// Results that are too large are wrapped: + /// + /// ``` + /// #![feature(wrapping_int_impl)] + /// use std::num::Wrapping; + /// + /// // 5 ^ 4 = 625, which is too big for a u8 + /// let x: Wrapping = Wrapping(5); + /// + /// assert_eq!(x.pow(4).0, 113); + /// ``` #[inline] #[unstable(feature = "wrapping_int_impl", issue = "32463")] pub fn pow(self, exp: u32) -> Self { - Wrapping(self.0.pow(exp)) + Wrapping(self.0.wrapping_pow(exp)) } } )*) @@ -651,6 +664,3 @@ mod shift_max { pub const u64: u32 = i64; pub use self::platform::usize; } - - - From bf101a5759fd0ddab7c9cbb1dc93d22d35f54722 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Thu, 8 Mar 2018 03:30:55 -0500 Subject: [PATCH 395/830] Fix trailing whitespace --- src/libcore/num/wrapping.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index fb79ddd09517..826883fdc3f0 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -525,7 +525,7 @@ macro_rules! wrapping_int_impl { /// use std::num::Wrapping; /// /// let n: Wrapping = Wrapping(0x0123456789ABCDEF); - /// + /// /// if cfg!(target_endian = "little") { /// assert_eq!(Wrapping::::from_le(n), n); /// } else { From 685c3c1b4a7c1949048177409ca43fc05daefd3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Mar 2018 23:01:11 -0700 Subject: [PATCH 396/830] Reduce the diagnostic span when multiple fields are missing in pattern --- src/librustc_typeck/check/_match.rs | 70 +++++++++++-------- .../ui/missing-fields-in-struct-pattern.rs | 17 +++++ 2 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.rs diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 379fd93ba2bd..0b5383f1f8d1 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -904,6 +904,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); // Keep track of which fields have already appeared in the pattern. let mut used_fields = FxHashMap(); + let mut inexistent_fields = vec![]; // Typecheck each field. for &Spanned { node: ref field, span } in fields { let field_ty = match used_fields.entry(field.name) { @@ -927,34 +928,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.field_ty(span, f, substs) }) .unwrap_or_else(|| { - let mut err = struct_span_err!( - tcx.sess, - span, - E0026, - "{} `{}` does not have a field named `{}`", - kind_name, - tcx.item_path_str(variant.did), - field.name - ); - err.span_label(span, - format!("{} `{}` does not have field `{}`", - kind_name, - tcx.item_path_str(variant.did), - field.name)); - if tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "This error indicates that a struct pattern attempted to \ - extract a non-existent field from a struct. Struct fields \ - are identified by the name used before the colon : so struct \ - patterns should resemble the declaration of the struct type \ - being matched.\n\n\ - If you are using shorthand field patterns but want to refer \ - to the struct field by a different name, you should rename \ - it explicitly." - ); - } - err.emit(); - + inexistent_fields.push((span, field.name)); tcx.types.err }) } @@ -963,6 +937,46 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); self.check_pat_walk(&field.pat, field_ty, def_bm, true); } + if inexistent_fields.len() > 0 { + let field_names = if inexistent_fields.len() == 1 { + format!("a field named `{}`", inexistent_fields[0].1) + } else { + format!("fields named {}", + inexistent_fields.iter() + .map(|(_, name)| format!("`{}`", name)) + .collect::>() + .join(", ")) + }; + let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); + let mut err = struct_span_err!(tcx.sess, + spans, + E0026, + "{} `{}` does not have {}", + kind_name, + tcx.item_path_str(variant.did), + field_names); + for (span, name) in &inexistent_fields { + err.span_label(*span, + format!("{} `{}` does not have field `{}`", + kind_name, + tcx.item_path_str(variant.did), + name)); + } + if tcx.sess.teach(&err.get_code().unwrap()) { + err.note( + "This error indicates that a struct pattern attempted to \ + extract a non-existent field from a struct. Struct fields \ + are identified by the name used before the colon : so struct \ + patterns should resemble the declaration of the struct type \ + being matched.\n\n\ + If you are using shorthand field patterns but want to refer \ + to the struct field by a different name, you should rename \ + it explicitly." + ); + } + err.emit(); + } + // Require `..` if struct has non_exhaustive attribute. if adt.is_struct() && adt.is_non_exhaustive() && !adt.did.is_local() && !etc { span_err!(tcx.sess, span, E0638, diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs new file mode 100644 index 000000000000..2469f2453454 --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct S(usize, usize, usize, usize); + +fn main() { + if let S { a, b, c, d } = S(1, 2, 3, 4) { + println!("hi"); + } +} From 97b3bf99f667736c3220a91b72a587eafe4cda49 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 01:31:04 -0500 Subject: [PATCH 397/830] Stabilize termination_trait This stabilizes `main` with non-() return types; see #48453. --- src/librustc_typeck/check/mod.rs | 33 +++++++++---------- src/librustc_typeck/lib.rs | 3 +- src/libstd/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 5 ++- .../termination-trait-main-i32.rs} | 3 +- .../termination-trait-main-wrong-type.rs | 1 - .../termination-trait-not-satisfied.rs | 2 -- .../termination-trait-for-never.rs | 2 -- ...mination-trait-for-result-box-error_err.rs | 2 -- .../termination-trait-for-empty.rs | 2 -- .../termination-trait-for-exitcode.rs | 1 - ...rmination-trait-for-result-box-error_ok.rs | 2 -- .../termination-trait-for-result.rs | 2 -- 13 files changed, 21 insertions(+), 39 deletions(-) rename src/test/compile-fail/{feature-gate-termination_trait.rs => rfc-1937-termination-trait/termination-trait-main-i32.rs} (82%) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4a685cfddb7a..42bf516a0afa 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1106,25 +1106,22 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, } fcx.demand_suptype(span, ret_ty, actual_return_ty); - if fcx.tcx.features().termination_trait { - // If the termination trait language item is activated, check that the main return type - // implements the termination trait. - if let Some(term_id) = fcx.tcx.lang_items().termination() { - if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() { - if id == fn_id { - match fcx.sess().entry_type.get() { - Some(config::EntryMain) => { - let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); - let trait_ref = ty::TraitRef::new(term_id, substs); - let cause = traits::ObligationCause::new( - span, fn_id, ObligationCauseCode::MainFunctionType); + // Check that the main return type implements the termination trait. + if let Some(term_id) = fcx.tcx.lang_items().termination() { + if let Some((id, _)) = *fcx.tcx.sess.entry_fn.borrow() { + if id == fn_id { + match fcx.sess().entry_type.get() { + Some(config::EntryMain) => { + let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); + let trait_ref = ty::TraitRef::new(term_id, substs); + let cause = traits::ObligationCause::new( + span, fn_id, ObligationCauseCode::MainFunctionType); - inherited.register_predicate( - traits::Obligation::new( - cause, param_env, trait_ref.to_predicate())); - }, - _ => {}, - } + inherited.register_predicate( + traits::Obligation::new( + cause, param_env, trait_ref.to_predicate())); + }, + _ => {}, } } } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 964c0021133a..808901404421 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -208,8 +208,7 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let actual = tcx.fn_sig(main_def_id); - let expected_return_type = if tcx.lang_items().termination().is_some() - && tcx.features().termination_trait { + let expected_return_type = if tcx.lang_items().termination().is_some() { // we take the return type of the given main function, the real check is done // in `check_fn` actual.output().skip_binder() diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70a1f82c9a15..33da0e578865 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -308,7 +308,6 @@ #![feature(str_char)] #![feature(str_internals)] #![feature(str_utf16)] -#![feature(termination_trait)] #![feature(test, rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] @@ -325,6 +324,7 @@ #![cfg_attr(test, feature(update_panic_count))] #![cfg_attr(windows, feature(used))] #![cfg_attr(stage0, feature(never_type))] +#![cfg_attr(stage0, feature(termination_trait))] #![default_lib_allocator] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 0950965233f6..781071b7f7f0 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -429,9 +429,6 @@ declare_features! ( // `foo.rs` as an alternative to `foo/mod.rs` (active, non_modrs_mods, "1.24.0", Some(44660), None), - // Termination trait in main (RFC 1937) - (active, termination_trait, "1.24.0", Some(43301), None), - // Termination trait in tests (RFC 1937) (active, termination_trait_test, "1.24.0", Some(48854), None), @@ -558,6 +555,8 @@ declare_features! ( (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/compile-fail/feature-gate-termination_trait.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs similarity index 82% rename from src/test/compile-fail/feature-gate-termination_trait.rs rename to src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 5a56445b64e5..ff2b32f3fd93 100644 --- a/src/test/compile-fail/feature-gate-termination_trait.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() -> i32 { //~ ERROR main function has wrong type [E0580] +fn main() -> i32 { +//~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277] 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index 93e2561adf75..ea39ba92f414 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -7,7 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] fn main() -> char { //~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs index e87e0ceebf1b..bab02fc55970 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - struct ReturnType {} fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs index c1dd44a91765..863de85af88f 100644 --- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-never.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - // error-pattern:oh, dear fn main() -> ! { diff --git a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs index 8ce27c0a0625..0c6cb4de9567 100644 --- a/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs +++ b/src/test/run-fail/rfc-1937-termination-trait/termination-trait-for-result-box-error_err.rs @@ -11,8 +11,6 @@ // must-compile-successfully // failure-status: 1 -#![feature(termination_trait)] - use std::io::{Error, ErrorKind}; fn main() -> Result<(), Box> { diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs index 5e534da01287..046d27a9f0fe 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-empty.rs @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - fn main() {} diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs index 80fa4d17b611..4aa7d8c3a77d 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-exitcode.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] #![feature(process_exitcode_placeholder)] use std::process::ExitCode; diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs index 269ac451cf4d..33686ed0b8fa 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result-box-error_ok.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - use std::io::Error; fn main() -> Result<(), Box> { diff --git a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs index 751db0fb5008..1c87e31e763e 100644 --- a/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs +++ b/src/test/run-pass/rfc-1937-termination-trait/termination-trait-for-result.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(termination_trait)] - use std::io::Error; fn main() -> Result<(), Error> { From 741d7a5598739f864f0f842d21665fa1e5809b41 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 19 Mar 2018 07:37:59 +0100 Subject: [PATCH 398/830] Docs: fix incorrect copy-paste for new `X?` in formatting strings --- src/liballoc/fmt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index 2c4cdef03b0f..90043e1c716b 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -114,7 +114,7 @@ //! * *nothing* ⇒ [`Display`] //! * `?` ⇒ [`Debug`] //! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers -//! * `X?` ⇒ [`Debug`] with lower-case hexadecimal integers +//! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers //! * `o` ⇒ [`Octal`](trait.Octal.html) //! * `x` ⇒ [`LowerHex`](trait.LowerHex.html) //! * `X` ⇒ [`UpperHex`](trait.UpperHex.html) From e5a55e74405dedf8bc0744300a8c506eea94bc18 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 19 Mar 2018 01:59:51 -0500 Subject: [PATCH 399/830] Stabilize termination_trait in 1.25, not 1.26 --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 781071b7f7f0..e71726bcebdc 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -551,12 +551,12 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.25.0", Some(43301), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), - // Termination trait in main (RFC 1937) - (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From 3799866063d3d6646f20f5a99292f633dce789cb Mon Sep 17 00:00:00 2001 From: Dileep Bapat Date: Mon, 19 Mar 2018 16:44:58 +0530 Subject: [PATCH 400/830] #49133 - Reworded the Error message: "`pub` not needed here" message --- src/librustc_passes/ast_validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 4215bf306a4f..e5157a071bf0 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -67,7 +67,7 @@ impl<'a> AstValidator<'a> { E0449, "unnecessary visibility qualifier"); if vis.node == VisibilityKind::Public { - err.span_label(vis.span, "`pub` not needed here"); + err.span_label(vis.span, "`pub` not permitted here because it's implied"); } if let Some(note) = note { err.note(note); From e2cf17278d1eabe30100095191f0b3c19e1f4f2a Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Mon, 19 Mar 2018 12:38:04 +0000 Subject: [PATCH 401/830] Update RELEASES.md --- RELEASES.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index e6f6e0440839..51c36c99858b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -33,7 +33,6 @@ Libraries - [`UnsafeCell::into_inner` is now safe.][47204] - [Implement libstd for CloudABI.][47268] - [`Float::{from_bits, to_bits}` is now available in libcore.][46931] - - [Implement `AsRef` for Component][46985] - [Implemented `Write` for `Cursor<&mut Vec>`][46830] - [Moved `Duration` to libcore.][46666] @@ -59,7 +58,6 @@ Cargo Misc ---- - - [Rust by example is now shipped with new releases][46196] Compatibility Notes From 8236e431ce67f0cd32e0584a826586648842eaa3 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 19 Mar 2018 22:09:47 +0900 Subject: [PATCH 402/830] Document only-X test header --- src/test/COMPILER_TESTS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md index c255294e790b..8553665c0179 100644 --- a/src/test/COMPILER_TESTS.md +++ b/src/test/COMPILER_TESTS.md @@ -54,6 +54,8 @@ be compiled or run. * `ignore-test` always ignores the test * `ignore-lldb` and `ignore-gdb` will skip a debuginfo test on that debugger. +`only-X` is the opposite. The test will run only when `X` matches. + Some examples of `X` in `ignore-X`: * Architecture: `aarch64`, `arm`, `asmjs`, `mips`, `wasm32`, `x86_64`, `x86`, ... From deae8de673af638537421804b360443af76d55e4 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 19 Mar 2018 14:33:39 +0100 Subject: [PATCH 403/830] Clarify AcqRel's docs This implied things that are not true. Fixes #49127 --- src/libcore/sync/atomic.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 25827edee7d9..fd6e5140a099 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -205,8 +205,9 @@ pub enum Ordering { /// [`Release`]: http://llvm.org/docs/Atomics.html#release #[stable(feature = "rust1", since = "1.0.0")] Acquire, - /// When coupled with a load, uses [`Acquire`] ordering, and with a store - /// [`Release`] ordering. + /// Has the effects of both [`Acquire`] and [`Release`] together. + /// + /// If you only are concerned about a load or a store, consider using one of those instead. /// /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire /// [`Release`]: http://llvm.org/docs/Atomics.html#release From a8f59aaef916849155157b11089dd209062eecc4 Mon Sep 17 00:00:00 2001 From: Dileep Bapat Date: Mon, 19 Mar 2018 16:44:58 +0530 Subject: [PATCH 404/830] #49133 - Reworded the Error message: "`pub` not needed here" message --- src/test/ui/error-codes/E0449.stderr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/ui/error-codes/E0449.stderr b/src/test/ui/error-codes/E0449.stderr index 480d8c40022d..df3b09ba7c9f 100644 --- a/src/test/ui/error-codes/E0449.stderr +++ b/src/test/ui/error-codes/E0449.stderr @@ -2,7 +2,7 @@ error[E0449]: unnecessary visibility qualifier --> $DIR/E0449.rs:17:1 | LL | pub impl Bar {} //~ ERROR E0449 - | ^^^ `pub` not needed here + | ^^^ `pub` not permitted here because it's implied | = note: place qualifiers on individual impl items instead @@ -10,13 +10,13 @@ error[E0449]: unnecessary visibility qualifier --> $DIR/E0449.rs:19:1 | LL | pub impl Foo for Bar { //~ ERROR E0449 - | ^^^ `pub` not needed here + | ^^^ `pub` not permitted here because it's implied error[E0449]: unnecessary visibility qualifier --> $DIR/E0449.rs:20:5 | LL | pub fn foo() {} //~ ERROR E0449 - | ^^^ `pub` not needed here + | ^^^ `pub` not permitted here because it's implied error: aborting due to 3 previous errors From 253ade5b31c8841f0351298c0f393fb0aba2cd24 Mon Sep 17 00:00:00 2001 From: Alan Du Date: Mon, 19 Mar 2018 10:14:13 -0400 Subject: [PATCH 405/830] Update rustfmt to 0.4.1 --- src/Cargo.lock | 139 ++++++++++++++++------------------------------ src/tools/rustfmt | 2 +- 2 files changed, 48 insertions(+), 93 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index c82588e41125..26508dec4bba 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -236,18 +236,6 @@ dependencies = [ "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cargo_metadata" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "cargo_metadata" version = "0.5.3" @@ -588,15 +576,6 @@ dependencies = [ "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "env_logger" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "env_logger" version = "0.5.5" @@ -1490,7 +1469,7 @@ dependencies = [ "rls-rustc 0.2.2 (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.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfmt-nightly 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfmt-nightly 0.4.1", "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1585,7 +1564,7 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_cratesio_shim" -version = "29.0.0" +version = "67.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1594,57 +1573,62 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "29.0.0" +version = "67.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_errors" -version = "29.0.0" +version = "67.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-serialize" -version = "29.0.0" +version = "67.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-ap-syntax" -version = "29.0.0" +version = "67.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-syntax_pos" -version = "29.0.0" +version = "67.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2066,52 +2050,26 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "0.3.8" +version = "0.4.1" dependencies = [ - "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.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 = "rustfmt-nightly" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "getopts 0.2.15 (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.39 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2146,15 +2104,6 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "semver" -version = "0.8.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)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "semver" version = "0.9.0" @@ -2424,6 +2373,15 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "term" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "termcolor" version = "0.3.5" @@ -2737,7 +2695,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" -"checksum cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "20d6fb2b5574726329c85cdba0df0347fddfec3cf9c8b588f9931708280f5643" "checksum cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5caae26de3704081ef638f87f05a6891b04f2b7d5ce9429a3de21095528ae22" "checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" @@ -2764,7 +2721,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" "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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" @@ -2858,21 +2814,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb" -"checksum rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ad5e562044ea78a6764dd75ae8afe4b21fde49f4548024b5fdf6345c21fb524" -"checksum rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c0d65325492aba7db72899e3edbab34d39af98c42ab7c7e450c9a288ffe4ad" -"checksum rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87d4ab2e06a671b5b5c5b0359dac346f164c99d059dce6a22feb08f2f56bd182" -"checksum rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0745fa445ff41c4b6699936cf35ce3ca49502377dd7b3929c829594772c3a7b" -"checksum rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82efedabe30f393161e11214a9130edfa01ad476372d1c6f3fec1f8d30488c9d" -"checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0" +"checksum rustc-ap-rustc_cratesio_shim 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "adc16e4a6e50a4ffbd4633d737aedbdfcb565bdf658159e0544266908180a919" +"checksum rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ec5f0a018fbec07f64b689ac20f7343ed77939055ca07d2aceb37c832245b1b" +"checksum rustc-ap-rustc_errors 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8301221cc07002666eed552a089b15000bc954c94b14a460c0653363a7f42f4c" +"checksum rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5212ee40fc332d791cacf202ae5fb99197341857c0a14bcdf60541fea7dfc5ed" +"checksum rustc-ap-syntax 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "168571b3878c6c61aef4bacef95c86d30fa61fb1cff04395d9535c80c196e559" +"checksum rustc-ap-syntax_pos 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd7a0486f56db583caa665c8b4ff02c4774fe279db1741509437bc8a84c53361" "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" -"checksum rustfmt-nightly 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "554256054eae37ead2f799ffa9cf8be8249496c6c3cf005c28b7cfa55f4efaa5" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4" "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" "checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum semver 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bee2bc909ab2d8d60dab26e8cad85b25d795b14603a0dcb627b78b9d30b6454b" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406" @@ -2896,6 +2850,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1605d3388ceb50252952ffebab4b5dc43017ead7e4481b175961c283bb951195" "checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" +"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" diff --git a/src/tools/rustfmt b/src/tools/rustfmt index 346238f49740..87180d9065e7 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit 346238f49740d6c98102a6a59811b1625c73a9d7 +Subproject commit 87180d9065e7c8070c0ba46eb48ddf8779ef89ac From 7dd943866228bb1037c7b9efd5e01f91862703e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 19 Mar 2018 15:14:19 +0100 Subject: [PATCH 406/830] config.toml.example: thinlto bootstrap was removed in ff227c4a2d8a2fad5abf322f6f1391ae6779197f so remove the option. --- config.toml.example | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config.toml.example b/config.toml.example index b47f9163c0da..f8cc67aee91a 100644 --- a/config.toml.example +++ b/config.toml.example @@ -239,11 +239,6 @@ # compiler. #codegen-units = 1 -# Whether to enable ThinLTO (and increase the codegen units to either a default -# or the configured value). On by default. If we want the fastest possible -# compiler, we should disable this. -#thinlto = true - # Whether or not debug assertions are enabled for the compiler and standard # library. Also enables compilation of debug! and trace! logging macros. #debug-assertions = false From 37ff4736c790f87ab957235c65e93ff8351daa80 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 19 Mar 2018 18:01:14 +0100 Subject: [PATCH 407/830] wording nits --- src/librustc_lint/builtin.rs | 8 ++++---- src/test/ui/type-alias-bounds.stderr | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2ea13b2cb6d6..f6acc085861e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1356,9 +1356,9 @@ impl TypeAliasBounds { fn suggest_changing_assoc_types(ty: &hir::Ty, err: &mut DiagnosticBuilder) { // Access to associates types should use `::Assoc`, which does not need a - // bound. Let's see of this type does that. + // bound. Let's see if this type does that. - // We use an AST visitor to walk the type. + // We use a HIR visitor to walk the type. use rustc::hir::intravisit::{self, Visitor}; use syntax::ast::NodeId; struct WalkAssocTypes<'a, 'db> where 'db: 'a { @@ -1373,8 +1373,8 @@ impl TypeAliasBounds { fn visit_qpath(&mut self, qpath: &'v hir::QPath, id: NodeId, span: Span) { if TypeAliasBounds::is_type_variable_assoc(qpath) { self.err.span_help(span, - "use absolute paths (i.e., ::Assoc) to refer to associated \ - types in type aliases"); + "use fully disambiguated paths (i.e., `::Assoc`) to refer to \ + associated types in type aliases"); } intravisit::walk_qpath(self, qpath, id, span) } diff --git a/src/test/ui/type-alias-bounds.stderr b/src/test/ui/type-alias-bounds.stderr index 5288dca79be6..2a2b0b0f26e3 100644 --- a/src/test/ui/type-alias-bounds.stderr +++ b/src/test/ui/type-alias-bounds.stderr @@ -46,7 +46,7 @@ LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^ | = help: the bound will not be checked when the type alias is used, and should be removed -help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases +help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases --> $DIR/type-alias-bounds.rs:57:21 | LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases @@ -59,7 +59,7 @@ LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliase | ^^^^^^^^ | = help: the clause will not be checked when the type alias is used, and should be removed -help: use absolute paths (i.e., ::Assoc) to refer to associated types in type aliases +help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases --> $DIR/type-alias-bounds.rs:58:29 | LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases From c05d23406ead7b5747256c02127097807db45b83 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 19 Mar 2018 18:08:12 +0100 Subject: [PATCH 408/830] update compile-fail tests: fewer warnings because this is now a HIR lint --- src/test/compile-fail/issue-17994.rs | 1 - src/test/compile-fail/private-in-public-warn.rs | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/test/compile-fail/issue-17994.rs b/src/test/compile-fail/issue-17994.rs index 7c3811e2ef28..25141b9b8255 100644 --- a/src/test/compile-fail/issue-17994.rs +++ b/src/test/compile-fail/issue-17994.rs @@ -10,5 +10,4 @@ trait Tr {} type Huh where T: Tr = isize; //~ ERROR type parameter `T` is unused - //~| WARNING where clauses are not enforced in type aliases fn main() {} diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index 8bd9b0a901d6..6eeb14638e75 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -58,7 +58,6 @@ mod traits { pub trait PubTr {} pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARNING bounds on generic parameters are not enforced in type aliases //~| WARNING hard error pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error @@ -85,7 +84,6 @@ mod traits_where { pub type Alias where T: PrivTr = T; //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error - //~| WARNING where clauses are not enforced in type aliases pub trait Tr2 where T: PrivTr {} //~^ ERROR private trait `traits_where::PrivTr` in public interface //~| WARNING hard error From 1b8f1fc2d9a387840fbd9b04eb80e6b9a42ea198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Mar 2018 18:18:35 -0700 Subject: [PATCH 409/830] Do not suggest `.into()` in `const`s --- src/librustc_typeck/check/demand.rs | 15 ++++++++++++- .../ui/suggestions/const-type-mismatch.rs | 21 +++++++++++++++++++ .../ui/suggestions/const-type-mismatch.stderr | 15 +++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/const-type-mismatch.rs create mode 100644 src/test/ui/suggestions/const-type-mismatch.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 634a7ee56991..701b896b9057 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -18,8 +18,9 @@ use syntax::ast; use syntax::util::parser::PREC_POSTFIX; use syntax_pos::{self, Span}; use rustc::hir; -use rustc::hir::print; use rustc::hir::def::Def; +use rustc::hir::map::NodeItem; +use rustc::hir::{Item, ItemConst, print}; use rustc::ty::{self, Ty, AssociatedItem}; use errors::{DiagnosticBuilder, CodeMapper}; @@ -318,6 +319,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { checked_ty: Ty<'tcx>, expected_ty: Ty<'tcx>) -> bool { + let parent_id = self.tcx.hir.get_parent_node(expr.id); + match self.tcx.hir.find(parent_id) { + Some(parent) => { + // Shouldn't suggest `.into()` on `const`s. + if let NodeItem(Item { node: ItemConst(_, _), .. }) = parent { + // FIXME(estebank): modify once we decide to suggest `as` casts + return false; + } + } + None => {} + }; + let will_truncate = "will truncate the source value"; let depending_on_isize = "will truncate or zero-extend depending on the bit width of \ `isize`"; diff --git a/src/test/ui/suggestions/const-type-mismatch.rs b/src/test/ui/suggestions/const-type-mismatch.rs new file mode 100644 index 000000000000..ddad4e79cfda --- /dev/null +++ b/src/test/ui/suggestions/const-type-mismatch.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// `const`s shouldn't suggest `.into()` + +const TEN: u8 = 10; +const TWELVE: u16 = TEN + 2; +//~^ ERROR mismatched types [E0308] + +fn main() { + const TEN: u8 = 10; + const ALSO_TEN: u16 = TEN; + //~^ ERROR mismatched types [E0308] +} diff --git a/src/test/ui/suggestions/const-type-mismatch.stderr b/src/test/ui/suggestions/const-type-mismatch.stderr new file mode 100644 index 000000000000..965995f82c53 --- /dev/null +++ b/src/test/ui/suggestions/const-type-mismatch.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/const-type-mismatch.rs:14:21 + | +LL | const TWELVE: u16 = TEN + 2; + | ^^^^^^^ expected u16, found u8 + +error[E0308]: mismatched types + --> $DIR/const-type-mismatch.rs:19:27 + | +LL | const ALSO_TEN: u16 = TEN; + | ^^^ expected u16, found u8 + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 57c74c39813c4668d3be5a0c244758f59ab32d9a Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 19 Mar 2018 12:40:42 -0700 Subject: [PATCH 410/830] Update beta to version with fixed FreeBSD support from #49023. Fixes #42681 --- src/stage0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stage0.txt b/src/stage0.txt index b9578386ce5b..96ec1e6834df 100644 --- a/src/stage0.txt +++ b/src/stage0.txt @@ -12,7 +12,7 @@ # source tarball for a stable release you'll likely see `1.x.0` for rustc and # `0.x.0` for Cargo where they were released on `date`. -date: 2018-02-20 +date: 2018-03-18 rustc: beta cargo: beta From f8fb9f18a5ad07f8ff7297957660434e7f8133f2 Mon Sep 17 00:00:00 2001 From: boats Date: Mon, 19 Mar 2018 13:13:31 -0700 Subject: [PATCH 411/830] Comment out flakey test. --- src/test/rustdoc/synthetic_auto/no-redundancy.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index 0b37f2ed3179..20d7e29f714d 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +/* This test is flakey, so it has been commented out. + pub struct Inner { field: T, } @@ -24,3 +26,5 @@ where pub struct Outer { inner_field: Inner, } + +*/ From e4d0d666b53264b0f23c3c62aaf7ae1b7e2e3007 Mon Sep 17 00:00:00 2001 From: boats Date: Mon, 19 Mar 2018 13:15:15 -0700 Subject: [PATCH 412/830] Ignore properly. --- src/test/rustdoc/synthetic_auto/no-redundancy.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index 20d7e29f714d..aabe7ae1d4d8 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/* This test is flakey, so it has been commented out. +// ignore pub struct Inner { field: T, @@ -26,5 +26,3 @@ where pub struct Outer { inner_field: Inner, } - -*/ From 2b64799365a43bf8685cb9750d9e887c006c1f22 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 14 Mar 2018 19:41:22 +0100 Subject: [PATCH 413/830] Make Atomic doc examples specific to each type --- src/libcore/sync/atomic.rs | 785 +++++++++++++++++++------------------ 1 file changed, 411 insertions(+), 374 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 25827edee7d9..fe5ed5d49422 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -948,6 +948,7 @@ macro_rules! atomic_int { $stable_from:meta, $stable_nand:meta, $s_int_type:expr, $int_ref:expr, + $extra_feature:expr, $int_type:ident $atomic_type:ident $atomic_init:ident) => { /// An integer type which can be safely shared between threads. /// @@ -959,12 +960,7 @@ macro_rules! atomic_int { /// ). For more about the differences between atomic types and /// non-atomic types, please see the [module-level documentation]. /// - /// Please note that examples are shared between atomic variants of - /// primitive integer types, so it's normal that they are all - /// demonstrating [`AtomicIsize`]. - /// /// [module-level documentation]: index.html - /// [`AtomicIsize`]: struct.AtomicIsize.html #[$stable] pub struct $atomic_type { v: UnsafeCell<$int_type>, @@ -1001,395 +997,426 @@ macro_rules! atomic_int { unsafe impl Sync for $atomic_type {} impl $atomic_type { - /// Creates a new atomic integer. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::AtomicIsize; - /// - /// let atomic_forty_two = AtomicIsize::new(42); - /// ``` - #[inline] - #[$stable] - pub const fn new(v: $int_type) -> Self { - $atomic_type {v: UnsafeCell::new(v)} - } + doc_comment! { + concat!("Creates a new atomic integer. - /// Returns a mutable reference to the underlying integer. - /// - /// This is safe because the mutable reference guarantees that no other threads are - /// concurrently accessing the atomic data. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let mut some_isize = AtomicIsize::new(10); - /// assert_eq!(*some_isize.get_mut(), 10); - /// *some_isize.get_mut() = 5; - /// assert_eq!(some_isize.load(Ordering::SeqCst), 5); - /// ``` - #[inline] - #[$stable_access] - pub fn get_mut(&mut self) -> &mut $int_type { - unsafe { &mut *self.v.get() } - } +# Examples - /// Consumes the atomic and returns the contained value. - /// - /// This is safe because passing `self` by value guarantees that no other threads are - /// concurrently accessing the atomic data. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::AtomicIsize; - /// - /// let some_isize = AtomicIsize::new(5); - /// assert_eq!(some_isize.into_inner(), 5); - /// ``` - #[inline] - #[$stable_access] - pub fn into_inner(self) -> $int_type { - self.v.into_inner() - } +``` +", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), "; - /// Loads a value from the atomic integer. - /// - /// `load` takes an [`Ordering`] argument which describes the memory ordering of this - /// operation. - /// - /// # Panics - /// - /// Panics if `order` is [`Release`] or [`AcqRel`]. - /// - /// [`Ordering`]: enum.Ordering.html - /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.load(Ordering::Relaxed), 5); - /// ``` - #[inline] - #[$stable] - pub fn load(&self, order: Ordering) -> $int_type { - unsafe { atomic_load(self.v.get(), order) } - } - - /// Stores a value into the atomic integer. - /// - /// `store` takes an [`Ordering`] argument which describes the memory ordering of this - /// operation. - /// - /// [`Ordering`]: enum.Ordering.html - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// some_isize.store(10, Ordering::Relaxed); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// ``` - /// - /// # Panics - /// - /// Panics if `order` is [`Acquire`] or [`AcqRel`]. - /// - /// [`Acquire`]: enum.Ordering.html#variant.Acquire - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - #[inline] - #[$stable] - pub fn store(&self, val: $int_type, order: Ordering) { - unsafe { atomic_store(self.v.get(), val, order); } - } - - /// Stores a value into the atomic integer, returning the previous value. - /// - /// `swap` takes an [`Ordering`] argument which describes the memory ordering of this - /// operation. - /// - /// [`Ordering`]: enum.Ordering.html - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.swap(10, Ordering::Relaxed), 5); - /// ``` - #[inline] - #[$stable] - pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_swap(self.v.get(), val, order) } - } - - /// Stores a value into the atomic integer if the current value is the same as the - /// `current` value. - /// - /// The return value is always the previous value. If it is equal to `current`, then the - /// value was updated. - /// - /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory - /// ordering of this operation. - /// - /// [`Ordering`]: enum.Ordering.html - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.compare_and_swap(5, 10, Ordering::Relaxed), 5); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// - /// assert_eq!(some_isize.compare_and_swap(6, 12, Ordering::Relaxed), 10); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// ``` - #[inline] - #[$stable] - pub fn compare_and_swap(&self, - current: $int_type, - new: $int_type, - order: Ordering) -> $int_type { - match self.compare_exchange(current, - new, - order, - strongest_failure_ordering(order)) { - Ok(x) => x, - Err(x) => x, +let atomic_forty_two = ", stringify!($atomic_type), "::new(42); +```"), + #[inline] + #[$stable] + pub const fn new(v: $int_type) -> Self { + $atomic_type {v: UnsafeCell::new(v)} } } - /// Stores a value into the atomic integer if the current value is the same as the - /// `current` value. - /// - /// The return value is a result indicating whether the new value was written and - /// containing the previous value. On success this value is guaranteed to be equal to - /// `current`. - /// - /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory - /// ordering of this operation. The first describes the required ordering if - /// the operation succeeds while the second describes the required ordering when - /// the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and - /// must be equivalent or weaker than the success ordering. - /// - /// [`Ordering`]: enum.Ordering.html - /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let some_isize = AtomicIsize::new(5); - /// - /// assert_eq!(some_isize.compare_exchange(5, 10, - /// Ordering::Acquire, - /// Ordering::Relaxed), - /// Ok(5)); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// - /// assert_eq!(some_isize.compare_exchange(6, 12, - /// Ordering::SeqCst, - /// Ordering::Acquire), - /// Err(10)); - /// assert_eq!(some_isize.load(Ordering::Relaxed), 10); - /// ``` - #[inline] - #[$stable_cxchg] - pub fn compare_exchange(&self, - current: $int_type, - new: $int_type, - success: Ordering, - failure: Ordering) -> Result<$int_type, $int_type> { - unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } - } + doc_comment! { + concat!("Returns a mutable reference to the underlying integer. - /// Stores a value into the atomic integer if the current value is the same as the - /// `current` value. - /// - /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even - /// when the comparison succeeds, which can result in more efficient code on some - /// platforms. The return value is a result indicating whether the new value was - /// written and containing the previous value. - /// - /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory - /// ordering of this operation. The first describes the required ordering if the - /// operation succeeds while the second describes the required ordering when the - /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and - /// must be equivalent or weaker than the success ordering. - /// - /// [`compare_exchange`]: #method.compare_exchange - /// [`Ordering`]: enum.Ordering.html - /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let val = AtomicIsize::new(4); - /// - /// let mut old = val.load(Ordering::Relaxed); - /// loop { - /// let new = old * 2; - /// match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { - /// Ok(_) => break, - /// Err(x) => old = x, - /// } - /// } - /// ``` - #[inline] - #[$stable_cxchg] - pub fn compare_exchange_weak(&self, - current: $int_type, - new: $int_type, - success: Ordering, - failure: Ordering) -> Result<$int_type, $int_type> { - unsafe { - atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) +This is safe because the mutable reference guarantees that no other threads are +concurrently accessing the atomic data. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let mut some_var = ", stringify!($atomic_type), "::new(10); +assert_eq!(*some_var.get_mut(), 10); +*some_var.get_mut() = 5; +assert_eq!(some_var.load(Ordering::SeqCst), 5); +```"), + #[inline] + #[$stable_access] + pub fn get_mut(&mut self) -> &mut $int_type { + unsafe { &mut *self.v.get() } } } - /// Adds to the current value, returning the previous value. - /// - /// This operation wraps around on overflow. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0); - /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0); - /// assert_eq!(foo.load(Ordering::SeqCst), 10); - /// ``` - #[inline] - #[$stable] - pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_add(self.v.get(), val, order) } + doc_comment! { + concat!("Consumes the atomic and returns the contained value. + +This is safe because passing `self` by value guarantees that no other threads are +concurrently accessing the atomic data. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), "; + +let some_var = ", stringify!($atomic_type), "::new(5); +assert_eq!(some_var.into_inner(), 5); +```"), + #[inline] + #[$stable_access] + pub fn into_inner(self) -> $int_type { + self.v.into_inner() + } } - /// Subtracts from the current value, returning the previous value. - /// - /// This operation wraps around on overflow. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0); - /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 0); - /// assert_eq!(foo.load(Ordering::SeqCst), -10); - /// ``` - #[inline] - #[$stable] - pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_sub(self.v.get(), val, order) } + doc_comment! { + concat!("Loads a value from the atomic integer. + +`load` takes an [`Ordering`] argument which describes the memory ordering of this operation. + +# Panics + +Panics if `order` is [`Release`] or [`AcqRel`]. + +[`Ordering`]: enum.Ordering.html +[`Release`]: enum.Ordering.html#variant.Release +[`AcqRel`]: enum.Ordering.html#variant.AcqRel + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.load(Ordering::Relaxed), 5); +```"), + #[inline] + #[$stable] + pub fn load(&self, order: Ordering) -> $int_type { + unsafe { atomic_load(self.v.get(), order) } + } } - /// Bitwise "and" with the current value. - /// - /// Performs a bitwise "and" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0b101101); - /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); - /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001); - #[inline] - #[$stable] - pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_and(self.v.get(), val, order) } + doc_comment! { + concat!("Stores a value into the atomic integer. + +`store` takes an [`Ordering`] argument which describes the memory ordering of this operation. + +[`Ordering`]: enum.Ordering.html + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +some_var.store(10, Ordering::Relaxed); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +``` + +# Panics + +Panics if `order` is [`Acquire`] or [`AcqRel`]. + +[`Acquire`]: enum.Ordering.html#variant.Acquire +[`AcqRel`]: enum.Ordering.html#variant.AcqRel"), + #[inline] + #[$stable] + pub fn store(&self, val: $int_type, order: Ordering) { + unsafe { atomic_store(self.v.get(), val, order); } + } } - /// Bitwise "nand" with the current value. - /// - /// Performs a bitwise "nand" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// #![feature(atomic_nand)] - /// - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0xf731); - /// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731); - /// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f)); - #[inline] - #[$stable_nand] - pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_nand(self.v.get(), val, order) } + doc_comment! { + concat!("Stores a value into the atomic integer, returning the previous value. + +`swap` takes an [`Ordering`] argument which describes the memory ordering of this operation. + +[`Ordering`]: enum.Ordering.html + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); +```"), + #[inline] + #[$stable] + pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_swap(self.v.get(), val, order) } + } } - /// Bitwise "or" with the current value. - /// - /// Performs a bitwise "or" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0b101101); - /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); - /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111); - #[inline] - #[$stable] - pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_or(self.v.get(), val, order) } + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. + +The return value is always the previous value. If it is equal to `current`, then the +value was updated. + +`compare_and_swap` also takes an [`Ordering`] argument which describes the memory +ordering of this operation. + +[`Ordering`]: enum.Ordering.html + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5); +assert_eq!(some_var.load(Ordering::Relaxed), 10); + +assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +```"), + #[inline] + #[$stable] + pub fn compare_and_swap(&self, + current: $int_type, + new: $int_type, + order: Ordering) -> $int_type { + match self.compare_exchange(current, + new, + order, + strongest_failure_ordering(order)) { + Ok(x) => x, + Err(x) => x, + } + } } - /// Bitwise "xor" with the current value. - /// - /// Performs a bitwise "xor" operation on the current value and the argument `val`, and - /// sets the new value to the result. - /// - /// Returns the previous value. - /// - /// # Examples - /// - /// ``` - /// use std::sync::atomic::{AtomicIsize, Ordering}; - /// - /// let foo = AtomicIsize::new(0b101101); - /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101); - /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110); - #[inline] - #[$stable] - pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { - unsafe { atomic_xor(self.v.get(), val, order) } + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. + +The return value is a result indicating whether the new value was written and +containing the previous value. On success this value is guaranteed to be equal to +`current`. + +`compare_exchange` takes two [`Ordering`] arguments to describe the memory +ordering of this operation. The first describes the required ordering if +the operation succeeds while the second describes the required ordering when +the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and +must be equivalent or weaker than the success ordering. + +[`Ordering`]: enum.Ordering.html +[`Release`]: enum.Ordering.html#variant.Release +[`AcqRel`]: enum.Ordering.html#variant.AcqRel + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let some_var = ", stringify!($atomic_type), "::new(5); + +assert_eq!(some_var.compare_exchange(5, 10, + Ordering::Acquire, + Ordering::Relaxed), + Ok(5)); +assert_eq!(some_var.load(Ordering::Relaxed), 10); + +assert_eq!(some_var.compare_exchange(6, 12, + Ordering::SeqCst, + Ordering::Acquire), + Err(10)); +assert_eq!(some_var.load(Ordering::Relaxed), 10); +```"), + #[inline] + #[$stable_cxchg] + pub fn compare_exchange(&self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering) -> Result<$int_type, $int_type> { + unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } + } + } + + doc_comment! { + concat!("Stores a value into the atomic integer if the current value is the same as +the `current` value. + +Unlike [`compare_exchange`], this function is allowed to spuriously fail even +when the comparison succeeds, which can result in more efficient code on some +platforms. The return value is a result indicating whether the new value was +written and containing the previous value. + +`compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory +ordering of this operation. The first describes the required ordering if the +operation succeeds while the second describes the required ordering when the +operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and +must be equivalent or weaker than the success ordering. + +[`compare_exchange`]: #method.compare_exchange +[`Ordering`]: enum.Ordering.html +[`Release`]: enum.Ordering.html#variant.Release +[`AcqRel`]: enum.Ordering.html#variant.AcqRel + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let val = ", stringify!($atomic_type), "::new(4); + +let mut old = val.load(Ordering::Relaxed); +loop { + let new = old * 2; + match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) { + Ok(_) => break, + Err(x) => old = x, + } +} +```"), + #[inline] + #[$stable_cxchg] + pub fn compare_exchange_weak(&self, + current: $int_type, + new: $int_type, + success: Ordering, + failure: Ordering) -> Result<$int_type, $int_type> { + unsafe { + atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) + } + } + } + + doc_comment! { + concat!("Adds to the current value, returning the previous value. + +This operation wraps around on overflow. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0); +assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[$stable] + pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_add(self.v.get(), val, order) } + } + } + + doc_comment! { + concat!("Subtracts from the current value, returning the previous value. + +This operation wraps around on overflow. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(20); +assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20); +assert_eq!(foo.load(Ordering::SeqCst), 10); +```"), + #[inline] + #[$stable] + pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_sub(self.v.get(), val, order) } + } + } + + doc_comment! { + concat!("Bitwise \"and\" with the current value. + +Performs a bitwise \"and\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b100001); +```"), + #[inline] + #[$stable] + pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_and(self.v.get(), val, order) } + } + } + + doc_comment! { + concat!("Bitwise \"nand\" with the current value. + +Performs a bitwise \"nand\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "#![feature(atomic_nand)] + +use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0x13); +assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13); +assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); +```"), + #[inline] + #[$stable_nand] + pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_nand(self.v.get(), val, order) } + } + } + + doc_comment! { + concat!("Bitwise \"or\" with the current value. + +Performs a bitwise \"or\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b111111); +```"), + #[inline] + #[$stable] + pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_or(self.v.get(), val, order) } + } + } + + doc_comment! { + concat!("Bitwise \"xor\" with the current value. + +Performs a bitwise \"xor\" operation on the current value and the argument `val`, and +sets the new value to the result. + +Returns the previous value. + +# Examples + +``` +", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering}; + +let foo = ", stringify!($atomic_type), "::new(0b101101); +assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101); +assert_eq!(foo.load(Ordering::SeqCst), 0b011110); +```"), + #[inline] + #[$stable] + pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_xor(self.v.get(), val, order) } + } } } } @@ -1404,6 +1431,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i8", "../../../std/primitive.i8.html", + "#![feature(integer_atomics)]\n\n", i8 AtomicI8 ATOMIC_I8_INIT } #[cfg(target_has_atomic = "8")] @@ -1415,6 +1443,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u8", "../../../std/primitive.u8.html", + "#![feature(integer_atomics)]\n\n", u8 AtomicU8 ATOMIC_U8_INIT } #[cfg(target_has_atomic = "16")] @@ -1426,6 +1455,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i16", "../../../std/primitive.i16.html", + "#![feature(integer_atomics)]\n\n", i16 AtomicI16 ATOMIC_I16_INIT } #[cfg(target_has_atomic = "16")] @@ -1437,6 +1467,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u16", "../../../std/primitive.u16.html", + "#![feature(integer_atomics)]\n\n", u16 AtomicU16 ATOMIC_U16_INIT } #[cfg(target_has_atomic = "32")] @@ -1448,6 +1479,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i32", "../../../std/primitive.i32.html", + "#![feature(integer_atomics)]\n\n", i32 AtomicI32 ATOMIC_I32_INIT } #[cfg(target_has_atomic = "32")] @@ -1459,6 +1491,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u32", "../../../std/primitive.u32.html", + "#![feature(integer_atomics)]\n\n", u32 AtomicU32 ATOMIC_U32_INIT } #[cfg(target_has_atomic = "64")] @@ -1470,6 +1503,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "i64", "../../../std/primitive.i64.html", + "#![feature(integer_atomics)]\n\n", i64 AtomicI64 ATOMIC_I64_INIT } #[cfg(target_has_atomic = "64")] @@ -1481,6 +1515,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "atomic_nand", issue = "13226"), "u64", "../../../std/primitive.u64.html", + "#![feature(integer_atomics)]\n\n", u64 AtomicU64 ATOMIC_U64_INIT } #[cfg(target_has_atomic = "ptr")] @@ -1492,6 +1527,7 @@ atomic_int!{ stable(feature = "atomic_from", since = "1.23.0"), unstable(feature = "atomic_nand", issue = "13226"), "isize", "../../../std/primitive.isize.html", + "", isize AtomicIsize ATOMIC_ISIZE_INIT } #[cfg(target_has_atomic = "ptr")] @@ -1503,6 +1539,7 @@ atomic_int!{ stable(feature = "atomic_from", since = "1.23.0"), unstable(feature = "atomic_nand", issue = "13226"), "usize", "../../../std/primitive.usize.html", + "", usize AtomicUsize ATOMIC_USIZE_INIT } From f332a9ce5676859f0f07c4d6bf2d2c415be67066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 18 Mar 2018 23:26:57 -0700 Subject: [PATCH 414/830] Single diagnostic for all non-mentioned fields in a pattern --- src/librustc_typeck/check/_match.rs | 22 ++++++++++++++----- .../ui/missing-fields-in-struct-pattern.rs | 2 ++ .../missing-fields-in-struct-pattern.stderr | 22 +++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.stderr diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0b5383f1f8d1..cc72a565ba28 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -993,13 +993,25 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); tcx.sess.span_err(span, "`..` cannot be used in union patterns"); } } else if !etc { - for field in variant.fields + let unmentioned_fields = variant.fields .iter() - .filter(|field| !used_fields.contains_key(&field.name)) { + .map(|field| field.name) + .filter(|field| !used_fields.contains_key(&field)) + .collect::>(); + if unmentioned_fields.len() > 0 { + let field_names = if unmentioned_fields.len() == 1 { + format!("field `{}`", unmentioned_fields[0]) + } else { + format!("fields {}", + unmentioned_fields.iter() + .map(|name| format!("`{}`", name)) + .collect::>() + .join(", ")) + }; let mut diag = struct_span_err!(tcx.sess, span, E0027, - "pattern does not mention field `{}`", - field.name); - diag.span_label(span, format!("missing field `{}`", field.name)); + "pattern does not mention {}", + field_names); + diag.span_label(span, format!("missing {}", field_names)); if variant.ctor_kind == CtorKind::Fn { diag.note("trying to match a tuple variant with a struct variant pattern"); } diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 2469f2453454..28ed151b9860 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -12,6 +12,8 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { + //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] + //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr new file mode 100644 index 000000000000..88fba19d14e3 --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -0,0 +1,22 @@ +error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` + --> $DIR/missing-fields-in-struct-pattern.rs:14:16 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^ ^ ^ ^ struct `S` does not have field `d` + | | | | + | | | struct `S` does not have field `c` + | | struct `S` does not have field `b` + | struct `S` does not have field `a` + +error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` + --> $DIR/missing-fields-in-struct-pattern.rs:14:12 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^^^^^^^^^^^^^^^^ missing fields `0`, `1`, `2`, `3` + | + = note: trying to match a tuple variant with a struct variant pattern + +error: aborting due to 2 previous errors + +Some errors occurred: E0026, E0027. +For more information about an error, try `rustc --explain E0026`. From bac6484a315a805287b98adc3c9c0909579c8393 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 19 Mar 2018 23:25:55 +0100 Subject: [PATCH 415/830] Fix automatic urls with backticks --- src/librustdoc/clean/mod.rs | 16 ++++++++-------- src/librustdoc/html/markdown.rs | 4 ++-- src/test/rustdoc/check-styled-link.rs | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 src/test/rustdoc/check-styled-link.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 904c24815cb7..72e303e19820 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -929,7 +929,7 @@ fn ambiguity_error(cx: &DocContext, attrs: &Attributes, select the {}", disambig1, kind1, disambig2, kind2)) - .emit(); + .emit(); } /// Given an enum variant's def, return the def of its enum and the associated fragment @@ -1074,6 +1074,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { } } +#[derive(Debug)] enum PathKind { /// can be either value or type, not a macro Unknown, @@ -1082,7 +1083,7 @@ enum PathKind { /// values, functions, consts, statics, everything in the value namespace Value, /// types, traits, everything in the type namespace - Type + Type, } impl Clean for [ast::Attribute] { @@ -1091,12 +1092,13 @@ impl Clean for [ast::Attribute] { if UnstableFeatures::from_environment().is_nightly_build() { let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new); - for link in markdown_links(&dox) { + for ori_link in markdown_links(&dox) { // bail early for real links - if link.contains('/') { + if ori_link.contains('/') { continue; } - let (def, fragment) = { + let link = ori_link.replace("`", ""); + let (def, fragment) = { let mut kind = PathKind::Unknown; let path_str = if let Some(prefix) = ["struct@", "enum@", "type@", @@ -1132,7 +1134,6 @@ impl Clean for [ast::Attribute] { continue; } - match kind { PathKind::Value => { if let Ok(def) = resolve(cx, path_str, true) { @@ -1206,9 +1207,8 @@ impl Clean for [ast::Attribute] { } }; - let id = register_def(cx, def); - attrs.links.push((link, id, fragment)); + attrs.links.push((ori_link, id, fragment)); } cx.sess().abort_if_errors(); diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 5e55353a26e6..8d1c9e4575e2 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -232,14 +232,14 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'a, I> { /// Make headings links with anchor ids and build up TOC. struct LinkReplacer<'a, 'b, I: Iterator>> { inner: I, - links: &'b [(String, String)] + links: &'b [(String, String)], } impl<'a, 'b, I: Iterator>> LinkReplacer<'a, 'b, I> { fn new(iter: I, links: &'b [(String, String)]) -> Self { LinkReplacer { inner: iter, - links + links, } } } diff --git a/src/test/rustdoc/check-styled-link.rs b/src/test/rustdoc/check-styled-link.rs new file mode 100644 index 000000000000..1633711e83d9 --- /dev/null +++ b/src/test/rustdoc/check-styled-link.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +pub struct Foo; + +// @has foo/struct.Bar.html '//a[@href="../foo/struct.Foo.html"]' 'Foo' + +/// Code-styled reference to [`Foo`]. +pub struct Bar; From c68885bd053fcff3f1698932716bec2e09371331 Mon Sep 17 00:00:00 2001 From: boats Date: Mon, 19 Mar 2018 15:34:11 -0700 Subject: [PATCH 416/830] Comment out entire test. --- src/test/rustdoc/synthetic_auto/no-redundancy.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index aabe7ae1d4d8..5ccee7811d23 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore +/* This test is flakey. Commented it out until #49123 is fixed pub struct Inner { field: T, @@ -26,3 +26,5 @@ where pub struct Outer { inner_field: Inner, } + +*/ From 6212904dd800864ca20ede8690fc827a1169fa26 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 19 Mar 2018 15:40:09 -0700 Subject: [PATCH 417/830] Don't use posix_spawn() if PATH was modified in the environment. The expected behavior is that the environment's PATH should be used to find the process. posix_spawn() could be used if we iterated PATH to search for the binary to execute. For now just skip posix_spawn() if PATH is modified. --- src/libstd/sys/unix/process/process_common.rs | 3 +++ src/libstd/sys/unix/process/process_unix.rs | 1 + src/libstd/sys_common/process.rs | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index d0486f06a143..48255489dd91 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -184,6 +184,9 @@ impl Command { let maybe_env = self.env.capture_if_changed(); maybe_env.map(|env| construct_envp(env, &mut self.saw_nul)) } + pub fn env_saw_path(&self) -> bool { + self.env.have_changed_path() + } pub fn setup_io(&self, default: Stdio, needs_stdin: bool) -> io::Result<(StdioPipes, ChildPipes)> { diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 29e33ee822ee..9d6d607e3f34 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -256,6 +256,7 @@ impl Command { if self.get_cwd().is_some() || self.get_gid().is_some() || self.get_uid().is_some() || + self.env_saw_path() || self.get_closures().len() != 0 { return Ok(None) } diff --git a/src/libstd/sys_common/process.rs b/src/libstd/sys_common/process.rs index fd1a5fdb4109..775491d762cd 100644 --- a/src/libstd/sys_common/process.rs +++ b/src/libstd/sys_common/process.rs @@ -47,6 +47,7 @@ impl EnvKey for DefaultEnvKey {} #[derive(Clone, Debug)] pub struct CommandEnv { clear: bool, + saw_path: bool, vars: BTreeMap> } @@ -54,6 +55,7 @@ impl Default for CommandEnv { fn default() -> Self { CommandEnv { clear: false, + saw_path: false, vars: Default::default() } } @@ -108,9 +110,11 @@ impl CommandEnv { // The following functions build up changes pub fn set(&mut self, key: &OsStr, value: &OsStr) { + self.maybe_saw_path(&key); self.vars.insert(key.to_owned().into(), Some(value.to_owned())); } pub fn remove(&mut self, key: &OsStr) { + self.maybe_saw_path(&key); if self.clear { self.vars.remove(key); } else { @@ -121,4 +125,12 @@ impl CommandEnv { self.clear = true; self.vars.clear(); } + pub fn have_changed_path(&self) -> bool { + self.saw_path || self.clear + } + fn maybe_saw_path(&mut self, key: &OsStr) { + if !self.saw_path && key.to_os_string() == OsString::from("PATH") { + self.saw_path = true; + } + } } From 25c8210c01db12fb9edfd2481ca81c91934c4bbd Mon Sep 17 00:00:00 2001 From: memoryleak47 Date: Mon, 19 Mar 2018 23:48:02 +0100 Subject: [PATCH 418/830] Put `#[macro_use] extern crate ` before fn main() in doctests --- src/librustdoc/test.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 117b21d47587..0f27775417d8 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -416,6 +416,7 @@ fn partition_source(s: &str) -> (String, String) { let trimline = line.trim(); let header = trimline.is_whitespace() || trimline.starts_with("#![") || + trimline.starts_with("#[macro_use] extern crate") || trimline.starts_with("extern crate"); if !header || after_header { after_header = true; @@ -825,6 +826,24 @@ assert_eq!(2+2, 4); assert_eq!(output, (expected, 2)); } + #[test] + fn make_test_manual_extern_crate_with_macro_use() { + let opts = TestOptions::default(); + let input = +"#[macro_use] extern crate asdf; +use asdf::qwop; +assert_eq!(2+2, 4);"; + let expected = +"#![allow(unused)] +#[macro_use] extern crate asdf; +fn main() { +use asdf::qwop; +assert_eq!(2+2, 4); +}".to_string(); + let output = make_test(input, Some("asdf"), false, &opts); + assert_eq!(output, (expected, 2)); + } + #[test] fn make_test_opts_attrs() { //if you supplied some doctest attributes with #![doc(test(attr(...)))], it will use those From 540021ff5d4771d3dfb8ce8ea5346a0ff2c1d060 Mon Sep 17 00:00:00 2001 From: boats Date: Mon, 19 Mar 2018 15:48:48 -0700 Subject: [PATCH 419/830] Okay this is the right way. --- src/test/rustdoc/synthetic_auto/no-redundancy.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index 5ccee7811d23..daa91c3e12bb 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -/* This test is flakey. Commented it out until #49123 is fixed +// ignore-test pub struct Inner { field: T, @@ -26,5 +26,3 @@ where pub struct Outer { inner_field: Inner, } - -*/ From 8e0faf79c0859f22d4e11268f272247a6ef73709 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 19 Mar 2018 16:15:26 -0700 Subject: [PATCH 420/830] Simplify PATH key comparison --- src/libstd/sys_common/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys_common/process.rs b/src/libstd/sys_common/process.rs index 775491d762cd..d0c5951bd6c0 100644 --- a/src/libstd/sys_common/process.rs +++ b/src/libstd/sys_common/process.rs @@ -129,7 +129,7 @@ impl CommandEnv { self.saw_path || self.clear } fn maybe_saw_path(&mut self, key: &OsStr) { - if !self.saw_path && key.to_os_string() == OsString::from("PATH") { + if !self.saw_path && key == "PATH" { self.saw_path = true; } } From 7c90189e1331cea3eac0ab0e8959f664cffba1ae Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 24 Feb 2018 22:21:33 +0300 Subject: [PATCH 421/830] Stabilize slice patterns without `..` Merge `feature(advanced_slice_patterns)` into `feature(slice_patterns)` --- .../advanced-slice-patterns.md | 35 ------------- .../src/language-features/slice-patterns.md | 30 ++++++----- src/liballoc/lib.rs | 1 - src/libcore/benches/lib.rs | 1 - src/libcore/tests/lib.rs | 1 + src/librustc/benches/lib.rs | 1 - src/librustc_apfloat/lib.rs | 2 +- src/librustc_const_eval/lib.rs | 1 - src/librustc_lint/lib.rs | 1 - src/librustc_trans/lib.rs | 2 +- src/librustc_trans_utils/lib.rs | 1 - src/librustc_typeck/diagnostics.rs | 6 --- src/librustc_typeck/lib.rs | 2 +- src/librustdoc/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 16 ++---- src/libsyntax/parse/parser.rs | 2 +- .../borrowck/borrowck-describe-lvalue.rs | 1 - .../borrowck-match-binding-is-assignment.rs | 2 - .../borrowck/borrowck-move-out-from-array.rs | 3 +- .../borrowck-vec-pattern-element-loan.rs | 1 - src/test/compile-fail/issue-12369.rs | 1 - src/test/compile-fail/issue-13482-2.rs | 2 - src/test/compile-fail/issue-13482.rs | 2 - src/test/compile-fail/issue-15381.rs | 2 - src/test/compile-fail/issue-41255.rs | 1 - src/test/compile-fail/issue-6804.rs | 1 - .../match-byte-array-patterns-2.rs | 2 - .../compile-fail/match-byte-array-patterns.rs | 2 +- src/test/compile-fail/match-ref-ice.rs | 1 - src/test/compile-fail/match-slice-patterns.rs | 2 +- src/test/compile-fail/match-vec-fixed.rs | 1 - src/test/compile-fail/match-vec-mismatch-2.rs | 2 - .../compile-fail/match-vec-unreachable.rs | 1 - src/test/compile-fail/move-out-of-slice-1.rs | 2 +- .../regions-pattern-typing-issue-19552.rs | 2 - .../uninhabited-matches-feature-gated.rs | 2 - src/test/compile-fail/uninhabited-patterns.rs | 2 +- src/test/mir-opt/uniform_array_move_out.rs | 3 +- .../auxiliary/roman_numerals.rs | 1 - src/test/run-pass/destructure-array-1.rs | 3 -- src/test/run-pass/dynamic-drop.rs | 3 +- src/test/run-pass/ignore-all-the-things.rs | 11 ++-- src/test/run-pass/issue-13027.rs | 2 - src/test/run-pass/issue-15080.rs | 1 - src/test/run-pass/issue-15104.rs | 1 - src/test/run-pass/issue-16648.rs | 3 -- src/test/run-pass/issue-17877.rs | 1 - src/test/run-pass/issue-37598.rs | 2 +- src/test/run-pass/issue-38002.rs | 2 - src/test/run-pass/issue-46855.rs | 2 - src/test/run-pass/issue-7784.rs | 2 - src/test/run-pass/match-vec-alternatives.rs | 2 - .../rfc-2005-default-binding-mode/slice.rs | 2 +- src/test/run-pass/trailing-comma.rs | 1 - src/test/run-pass/vec-matching-autoslice.rs | 3 -- src/test/run-pass/vec-matching-fixed.rs | 2 - src/test/run-pass/vec-matching-fold.rs | 2 - src/test/run-pass/vec-matching.rs | 2 - src/test/run-pass/vec-tail-matching.rs | 2 - .../borrowck/borrowck-vec-pattern-nesting.rs | 1 - .../borrowck-vec-pattern-nesting.stderr | 16 +++--- src/test/ui/error-codes/E0527.rs | 2 - src/test/ui/error-codes/E0527.stderr | 2 +- src/test/ui/error-codes/E0529.rs | 2 - src/test/ui/error-codes/E0529.stderr | 2 +- .../feature-gate-advanced-slice-features.rs | 22 -------- ...eature-gate-advanced-slice-features.stderr | 19 ------- src/test/ui/feature-gate-slice-patterns.rs | 13 ++++- .../ui/feature-gate-slice-patterns.stderr | 50 +++++++++++++++++-- src/test/ui/mismatched_types/issue-38371.rs | 2 - .../ui/mismatched_types/issue-38371.stderr | 8 +-- src/test/ui/non-exhaustive-pattern-witness.rs | 1 - .../ui/non-exhaustive-pattern-witness.stderr | 14 +++--- src/test/ui/pat-slice-old-style.rs | 4 +- .../ui/rfc-2005-default-binding-mode/slice.rs | 2 +- 75 files changed, 125 insertions(+), 227 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/advanced-slice-patterns.md delete mode 100644 src/test/ui/feature-gate-advanced-slice-features.rs delete mode 100644 src/test/ui/feature-gate-advanced-slice-features.stderr 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 deleted file mode 100644 index e8256469b145..000000000000 --- a/src/doc/unstable-book/src/language-features/advanced-slice-patterns.md +++ /dev/null @@ -1,35 +0,0 @@ -# `advanced_slice_patterns` - -The tracking issue for this feature is: [#23121] - -[#23121]: https://github.com/rust-lang/rust/issues/23121 - -See also [`slice_patterns`](language-features/slice-patterns.html). - ------------------------- - - -The `advanced_slice_patterns` gate lets you use `..` to indicate any number of -elements inside a pattern matching a slice. This wildcard can only be used once -for a given array. If there's an identifier before the `..`, the result of the -slice will be bound to that name. For example: - -```rust -#![feature(advanced_slice_patterns, slice_patterns)] - -fn is_symmetric(list: &[u32]) -> bool { - match list { - &[] | &[_] => true, - &[x, ref inside.., y] if x == y => is_symmetric(inside), - _ => false - } -} - -fn main() { - let sym = &[0, 1, 4, 2, 4, 1, 0]; - assert!(is_symmetric(sym)); - - let not_sym = &[0, 1, 7, 2, 4, 1, 0]; - assert!(!is_symmetric(not_sym)); -} -``` 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 69857297582d..133174268ef9 100644 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ b/src/doc/unstable-book/src/language-features/slice-patterns.md @@ -4,25 +4,29 @@ The tracking issue for this feature is: [#23121] [#23121]: https://github.com/rust-lang/rust/issues/23121 -See also -[`advanced_slice_patterns`](language-features/advanced-slice-patterns.html). - ------------------------ - -If you want to match against a slice or array, you can use `&` with the -`slice_patterns` feature: +The `slice_patterns` feature gate lets you use `..` to indicate any number of +elements inside a pattern matching a slice. This wildcard can only be used once +for a given array. If there's an pattern before the `..`, the subslice will be +matched against that pattern. For example: ```rust #![feature(slice_patterns)] -fn main() { - let v = vec!["match_this", "1"]; - - match &v[..] { - &["match_this", second] => println!("The second element is {}", second), - _ => {}, +fn is_symmetric(list: &[u32]) -> bool { + match list { + &[] | &[_] => true, + &[x, ref inside.., y] if x == y => is_symmetric(inside), + &[..] => false, } } -``` +fn main() { + let sym = &[0, 1, 4, 2, 4, 1, 0]; + assert!(is_symmetric(sym)); + + let not_sym = &[0, 1, 7, 2, 4, 1, 0]; + assert!(!is_symmetric(not_sym)); +} +``` diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 2727bcaa28a9..45bb38855744 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -110,7 +110,6 @@ #![feature(ptr_internals)] #![feature(rustc_attrs)] #![feature(slice_get_slice)] -#![feature(slice_patterns)] #![feature(slice_rsplit)] #![feature(specialization)] #![feature(staged_api)] diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs index 201064e823b1..c947b003ccbf 100644 --- a/src/libcore/benches/lib.rs +++ b/src/libcore/benches/lib.rs @@ -11,7 +11,6 @@ #![deny(warnings)] #![feature(flt2dec)] -#![feature(slice_patterns)] #![feature(test)] extern crate core; diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1c876fa0bd7d..e9a8113ef107 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -37,6 +37,7 @@ #![feature(raw)] #![feature(refcell_replace_swap)] #![feature(slice_patterns)] +#![feature(slice_rotate)] #![feature(sort_internals)] #![feature(specialization)] #![feature(step_trait)] diff --git a/src/librustc/benches/lib.rs b/src/librustc/benches/lib.rs index 24294ec49cee..278e0f9a26e4 100644 --- a/src/librustc/benches/lib.rs +++ b/src/librustc/benches/lib.rs @@ -10,7 +10,6 @@ #![deny(warnings)] -#![feature(slice_patterns)] #![feature(test)] extern crate test; diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 3afc2f684009..565658804b00 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -47,7 +47,7 @@ #![forbid(unsafe_code)] #![feature(i128_type)] -#![feature(slice_patterns)] +#![cfg_attr(stage0, feature(slice_patterns))] #![feature(try_from)] // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index 459aa9ea488f..2b0775e86952 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -20,7 +20,6 @@ #![deny(warnings)] #![feature(rustc_diagnostic_macros)] -#![feature(slice_patterns)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(macro_lifetime_matcher)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 8b86c9054895..ce896bfb701b 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -31,7 +31,6 @@ #![feature(macro_vis_matcher)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#![feature(slice_patterns)] #![cfg_attr(stage0, feature(never_type))] #[macro_use] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 3645e7288420..337f85a38139 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -30,7 +30,7 @@ #![feature(libc)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#![feature(slice_patterns)] +#![cfg_attr(stage0, feature(slice_patterns))] #![feature(conservative_impl_trait)] #![feature(optin_builtin_traits)] #![feature(inclusive_range_fields)] diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 6a3fd21f3a77..0af5f4679345 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -24,7 +24,6 @@ #![feature(i128_type)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#![feature(slice_patterns)] #![feature(conservative_impl_trait)] extern crate ar; diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 24044fd2d721..f5337118e30d 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3559,8 +3559,6 @@ elements in the array being matched. Example of erroneous code: ```compile_fail,E0527 -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4]; match r { &[a, b] => { // error: pattern requires 2 elements but array @@ -3625,8 +3623,6 @@ An array or slice pattern was matched against some other type. Example of erroneous code: ```compile_fail,E0529 -#![feature(slice_patterns)] - let r: f32 = 1.0; match r { [a, b] => { // error: expected an array or slice, found `f32` @@ -3639,8 +3635,6 @@ Ensure that the pattern and the expression being matched on are of consistent types: ``` -#![feature(slice_patterns)] - let r = [1.0, 2.0]; match r { [a, b] => { // ok! diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 964c0021133a..9f98932f24b5 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -72,7 +72,7 @@ This API is completely unstable and subject to change. #![allow(non_camel_case_types)] -#![feature(advanced_slice_patterns)] +#![cfg_attr(stage0, feature(advanced_slice_patterns))] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(conservative_impl_trait)] diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index da52fd5aa372..bec25a98227a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -20,7 +20,7 @@ #![feature(box_syntax)] #![feature(fs_read_write)] #![feature(set_stdio)] -#![feature(slice_patterns)] +#![cfg_attr(stage0, feature(slice_patterns))] #![feature(test)] #![feature(unicode)] #![feature(vec_remove_item)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fa600cd68606..915396d29fe2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -145,7 +145,6 @@ declare_features! ( // rustc internal (active, rustc_diagnostic_macros, "1.0.0", None, None), (active, rustc_const_unstable, "1.0.0", None, None), - (active, advanced_slice_patterns, "1.0.0", Some(23121), None), (active, box_syntax, "1.0.0", Some(27779), None), (active, placement_in_syntax, "1.0.0", Some(27779), None), (active, unboxed_closures, "1.0.0", Some(29625), None), @@ -474,6 +473,8 @@ declare_features! ( (removed, allocator, "1.0.0", None, None), // Allows the `#[simd]` attribute -- removed in favor of `#[repr(simd)]` (removed, simd, "1.0.0", Some(27731), None), + // Merged into `slice_patterns` + (removed, advanced_slice_patterns, "1.0.0", Some(23121), None), ); declare_features! ( @@ -1655,17 +1656,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_pat(&mut self, pattern: &'a ast::Pat) { match pattern.node { - PatKind::Slice(_, Some(_), ref last) if !last.is_empty() => { - gate_feature_post!(&self, advanced_slice_patterns, - pattern.span, - "multiple-element slice matches anywhere \ - but at the end of a slice (e.g. \ - `[0, ..xs, 0]`) are experimental") - } - PatKind::Slice(..) => { + PatKind::Slice(_, Some(ref subslice), _) => { gate_feature_post!(&self, slice_patterns, - pattern.span, - "slice pattern syntax is experimental"); + subslice.span, + "syntax for subslices in slice patterns is not yet stabilized"); } PatKind::Box(..) => { gate_feature_post!(&self, box_patterns, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cb5010a638df..6d8975197d55 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3618,7 +3618,7 @@ impl<'a> Parser<'a> { slice = Some(P(Pat { id: ast::DUMMY_NODE_ID, node: PatKind::Wild, - span: self.span, + span: self.prev_span, })); before_slice = false; } diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs index 1d08b8074658..fa475949b36b 100644 --- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs @@ -13,7 +13,6 @@ //[mir]compile-flags: -Z borrowck=mir #![feature(slice_patterns)] -#![feature(advanced_slice_patterns)] pub struct Foo { x: u32 diff --git a/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs b/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs index 32a573911ece..30047f84041f 100644 --- a/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs +++ b/src/test/compile-fail/borrowck/borrowck-match-binding-is-assignment.rs @@ -13,8 +13,6 @@ // Test that immutable pattern bindings cannot be reassigned. -#![feature(slice_patterns)] - enum E { Foo(isize) } diff --git a/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs b/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs index e01161734623..0db31cef0ed7 100644 --- a/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs +++ b/src/test/compile-fail/borrowck/borrowck-move-out-from-array.rs @@ -11,7 +11,8 @@ // revisions: ast mir //[mir]compile-flags: -Z borrowck=mir -#![feature(box_syntax, slice_patterns, advanced_slice_patterns)] +#![feature(box_syntax)] +#![feature(slice_patterns)] fn move_out_from_begin_and_end() { let a = [box 1, box 2]; diff --git a/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs index eb5d69d49bd6..0fd6923326ab 100644 --- a/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs +++ b/src/test/compile-fail/borrowck/borrowck-vec-pattern-element-loan.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] fn a<'a>() -> &'a [isize] { diff --git a/src/test/compile-fail/issue-12369.rs b/src/test/compile-fail/issue-12369.rs index 4df1e24dcfbd..1b9af393ccce 100644 --- a/src/test/compile-fail/issue-12369.rs +++ b/src/test/compile-fail/issue-12369.rs @@ -9,7 +9,6 @@ // except according to those terms. #![feature(slice_patterns)] -#![allow(unused_variables)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/compile-fail/issue-13482-2.rs b/src/test/compile-fail/issue-13482-2.rs index 6885c8d94c6b..fe7fbb176cc5 100644 --- a/src/test/compile-fail/issue-13482-2.rs +++ b/src/test/compile-fail/issue-13482-2.rs @@ -10,8 +10,6 @@ // compile-flags:-Z verbose -#![feature(slice_patterns)] - fn main() { let x = [1,2]; let y = match x { diff --git a/src/test/compile-fail/issue-13482.rs b/src/test/compile-fail/issue-13482.rs index 82e82df31861..32a63b79a32d 100644 --- a/src/test/compile-fail/issue-13482.rs +++ b/src/test/compile-fail/issue-13482.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - fn main() { let x = [1,2]; let y = match x { diff --git a/src/test/compile-fail/issue-15381.rs b/src/test/compile-fail/issue-15381.rs index d0964d2aabea..1cdd803971b4 100644 --- a/src/test/compile-fail/issue-15381.rs +++ b/src/test/compile-fail/issue-15381.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - fn main() { let values: Vec = vec![1,2,3,4,5,6,7,8]; diff --git a/src/test/compile-fail/issue-41255.rs b/src/test/compile-fail/issue-41255.rs index ac85e43cf4f0..bdd502d44203 100644 --- a/src/test/compile-fail/issue-41255.rs +++ b/src/test/compile-fail/issue-41255.rs @@ -10,7 +10,6 @@ // Matching against float literals should result in a linter error -#![feature(slice_patterns)] #![feature(exclusive_range_pattern)] #![allow(unused)] #![forbid(illegal_floating_point_literal_pattern)] diff --git a/src/test/compile-fail/issue-6804.rs b/src/test/compile-fail/issue-6804.rs index 9191dfa155c6..fffa27ab842a 100644 --- a/src/test/compile-fail/issue-6804.rs +++ b/src/test/compile-fail/issue-6804.rs @@ -10,7 +10,6 @@ // Matching against NaN should result in a warning -#![feature(slice_patterns)] #![allow(unused)] #![deny(illegal_floating_point_literal_pattern)] diff --git a/src/test/compile-fail/match-byte-array-patterns-2.rs b/src/test/compile-fail/match-byte-array-patterns-2.rs index ad7e931a0ec9..abb770df107f 100644 --- a/src/test/compile-fail/match-byte-array-patterns-2.rs +++ b/src/test/compile-fail/match-byte-array-patterns-2.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns, slice_patterns)] - fn main() { let buf = &[0, 1, 2, 3]; diff --git a/src/test/compile-fail/match-byte-array-patterns.rs b/src/test/compile-fail/match-byte-array-patterns.rs index 1ff07eae1c9c..9db4319b7868 100644 --- a/src/test/compile-fail/match-byte-array-patterns.rs +++ b/src/test/compile-fail/match-byte-array-patterns.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns, slice_patterns)] +#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/compile-fail/match-ref-ice.rs b/src/test/compile-fail/match-ref-ice.rs index 1cdbba17f658..cb8f8fad532f 100644 --- a/src/test/compile-fail/match-ref-ice.rs +++ b/src/test/compile-fail/match-ref-ice.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] #![deny(unreachable_patterns)] // The arity of `ref x` is always 1. If the pattern is compared to some non-structural type whose diff --git a/src/test/compile-fail/match-slice-patterns.rs b/src/test/compile-fail/match-slice-patterns.rs index fd4bd1c7b944..a8ec95da3d87 100644 --- a/src/test/compile-fail/match-slice-patterns.rs +++ b/src/test/compile-fail/match-slice-patterns.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns, slice_patterns)] +#![feature(slice_patterns)] fn check(list: &[Option<()>]) { match list { diff --git a/src/test/compile-fail/match-vec-fixed.rs b/src/test/compile-fail/match-vec-fixed.rs index dd9379c756d1..05971d70167b 100644 --- a/src/test/compile-fail/match-vec-fixed.rs +++ b/src/test/compile-fail/match-vec-fixed.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn a() { diff --git a/src/test/compile-fail/match-vec-mismatch-2.rs b/src/test/compile-fail/match-vec-mismatch-2.rs index 375d855d1fd3..52c5375f4e7d 100644 --- a/src/test/compile-fail/match-vec-mismatch-2.rs +++ b/src/test/compile-fail/match-vec-mismatch-2.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - fn main() { match () { [()] => { } diff --git a/src/test/compile-fail/match-vec-unreachable.rs b/src/test/compile-fail/match-vec-unreachable.rs index 472b054b0877..d6e3fdbe0884 100644 --- a/src/test/compile-fail/match-vec-unreachable.rs +++ b/src/test/compile-fail/match-vec-unreachable.rs @@ -10,7 +10,6 @@ #![feature(slice_patterns)] #![deny(unreachable_patterns)] -#![allow(unused_variables)] fn main() { let x: Vec<(isize, isize)> = Vec::new(); diff --git a/src/test/compile-fail/move-out-of-slice-1.rs b/src/test/compile-fail/move-out-of-slice-1.rs index 9ca9e0984e47..5efbef549ddc 100644 --- a/src/test/compile-fail/move-out-of-slice-1.rs +++ b/src/test/compile-fail/move-out-of-slice-1.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns, box_patterns)] +#![feature(box_patterns)] struct A; diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs index 8e83177090bb..3401dd1becdd 100644 --- a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs +++ b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - fn assert_static(_t: T) {} fn main() { diff --git a/src/test/compile-fail/uninhabited-matches-feature-gated.rs b/src/test/compile-fail/uninhabited-matches-feature-gated.rs index 0c3ea53a903a..1d3f8ff12d86 100644 --- a/src/test/compile-fail/uninhabited-matches-feature-gated.rs +++ b/src/test/compile-fail/uninhabited-matches-feature-gated.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - enum Void {} fn main() { diff --git a/src/test/compile-fail/uninhabited-patterns.rs b/src/test/compile-fail/uninhabited-patterns.rs index 9f943f08232d..e130df5c845b 100644 --- a/src/test/compile-fail/uninhabited-patterns.rs +++ b/src/test/compile-fail/uninhabited-patterns.rs @@ -9,9 +9,9 @@ // except according to those terms. #![feature(box_patterns)] -#![feature(slice_patterns)] #![feature(box_syntax)] #![feature(exhaustive_patterns)] +#![feature(slice_patterns)] #![deny(unreachable_patterns)] mod foo { diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs index 482b69a59ddb..fa5f62f89f63 100644 --- a/src/test/mir-opt/uniform_array_move_out.rs +++ b/src/test/mir-opt/uniform_array_move_out.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(box_syntax, slice_patterns, advanced_slice_patterns)] +#![feature(box_syntax)] +#![feature(slice_patterns)] fn move_out_from_end() { let a = [box 1, box 2]; diff --git a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs index 26419a51513f..17cf39372c0e 100644 --- a/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs +++ b/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs @@ -12,7 +12,6 @@ #![crate_type="dylib"] #![feature(plugin_registrar, rustc_private)] -#![feature(slice_patterns)] extern crate syntax; extern crate syntax_pos; diff --git a/src/test/run-pass/destructure-array-1.rs b/src/test/run-pass/destructure-array-1.rs index 0d24f0bd0d7b..43271162c181 100644 --- a/src/test/run-pass/destructure-array-1.rs +++ b/src/test/run-pass/destructure-array-1.rs @@ -11,9 +11,6 @@ // Ensure that we can do a destructuring bind of a fixed-size array, // even when the element type has a destructor. - -#![feature(slice_patterns)] - struct D { x: u8 } impl Drop for D { fn drop(&mut self) { } } diff --git a/src/test/run-pass/dynamic-drop.rs b/src/test/run-pass/dynamic-drop.rs index 4d0bd3f3412f..1f543f7be0e8 100644 --- a/src/test/run-pass/dynamic-drop.rs +++ b/src/test/run-pass/dynamic-drop.rs @@ -13,7 +13,8 @@ // ignore-wasm32-bare compiled with panic=abort by default -#![feature(generators, generator_trait, untagged_unions, slice_patterns, advanced_slice_patterns)] +#![feature(generators, generator_trait, untagged_unions)] +#![feature(slice_patterns)] use std::cell::{Cell, RefCell}; use std::ops::Generator; diff --git a/src/test/run-pass/ignore-all-the-things.rs b/src/test/run-pass/ignore-all-the-things.rs index 711f2dd6c667..c14f3dc72916 100644 --- a/src/test/run-pass/ignore-all-the-things.rs +++ b/src/test/run-pass/ignore-all-the-things.rs @@ -10,7 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] struct Foo(isize, isize, isize, isize); @@ -20,11 +19,11 @@ pub fn main() { let Foo(..) = Foo(5, 5, 5, 5); let Foo(..) = Foo(5, 5, 5, 5); let Bar{..} = Bar{a: 5, b: 5, c: 5, d: 5}; - //let (..) = (5, 5, 5, 5); - //let Foo(a, b, ..) = Foo(5, 5, 5, 5); - //let Foo(.., d) = Foo(5, 5, 5, 5); - //let (a, b, ..) = (5, 5, 5, 5); - //let (.., c, d) = (5, 5, 5, 5); + let (..) = (5, 5, 5, 5); + let Foo(a, b, ..) = Foo(5, 5, 5, 5); + let Foo(.., d) = Foo(5, 5, 5, 5); + let (a, b, ..) = (5, 5, 5, 5); + let (.., c, d) = (5, 5, 5, 5); let Bar{b: b, ..} = Bar{a: 5, b: 5, c: 5, d: 5}; match [5, 5, 5, 5] { [..] => { } diff --git a/src/test/run-pass/issue-13027.rs b/src/test/run-pass/issue-13027.rs index 149874847117..d28ea94ec1a0 100644 --- a/src/test/run-pass/issue-13027.rs +++ b/src/test/run-pass/issue-13027.rs @@ -12,8 +12,6 @@ // Tests that match expression handles overlapped literal and range // properly in the presence of guard function. -#![feature(slice_patterns)] - fn val() -> usize { 1 } static CONST: usize = 1; diff --git a/src/test/run-pass/issue-15080.rs b/src/test/run-pass/issue-15080.rs index 14e003788469..59267f79e264 100644 --- a/src/test/run-pass/issue-15080.rs +++ b/src/test/run-pass/issue-15080.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - #![feature(slice_patterns)] fn main() { diff --git a/src/test/run-pass/issue-15104.rs b/src/test/run-pass/issue-15104.rs index 508360cb7011..2878f2795c59 100644 --- a/src/test/run-pass/issue-15104.rs +++ b/src/test/run-pass/issue-15104.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - #![feature(slice_patterns)] fn main() { diff --git a/src/test/run-pass/issue-16648.rs b/src/test/run-pass/issue-16648.rs index e1b94179764b..bf272308fa9d 100644 --- a/src/test/run-pass/issue-16648.rs +++ b/src/test/run-pass/issue-16648.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(slice_patterns)] - fn main() { let x: (isize, &[isize]) = (2, &[1, 2]); assert_eq!(match x { diff --git a/src/test/run-pass/issue-17877.rs b/src/test/run-pass/issue-17877.rs index 6c87e8d35fbf..d3fe0903a1d6 100644 --- a/src/test/run-pass/issue-17877.rs +++ b/src/test/run-pass/issue-17877.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - #![feature(slice_patterns)] fn main() { diff --git a/src/test/run-pass/issue-37598.rs b/src/test/run-pass/issue-37598.rs index d32d2fc29544..e97c8d9f4176 100644 --- a/src/test/run-pass/issue-37598.rs +++ b/src/test/run-pass/issue-37598.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns, slice_patterns)] +#![feature(slice_patterns)] fn check(list: &[u8]) { match list { diff --git a/src/test/run-pass/issue-38002.rs b/src/test/run-pass/issue-38002.rs index 489d35e9147a..dd6ccec973fc 100644 --- a/src/test/run-pass/issue-38002.rs +++ b/src/test/run-pass/issue-38002.rs @@ -10,8 +10,6 @@ // Check that constant ADTs are translated OK, part k of N. -#![feature(slice_patterns)] - enum Bar { C } diff --git a/src/test/run-pass/issue-46855.rs b/src/test/run-pass/issue-46855.rs index d864d55c9397..28aa6c731ec8 100644 --- a/src/test/run-pass/issue-46855.rs +++ b/src/test/run-pass/issue-46855.rs @@ -10,8 +10,6 @@ // compile-flags: -Zmir-opt-level=1 -#![feature(slice_patterns)] - use std::mem; #[derive(Copy, Clone)] diff --git a/src/test/run-pass/issue-7784.rs b/src/test/run-pass/issue-7784.rs index badc013cd621..8d21594aa12c 100644 --- a/src/test/run-pass/issue-7784.rs +++ b/src/test/run-pass/issue-7784.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] use std::ops::Add; diff --git a/src/test/run-pass/match-vec-alternatives.rs b/src/test/run-pass/match-vec-alternatives.rs index fa609593c24b..7d03d9c2abe2 100644 --- a/src/test/run-pass/match-vec-alternatives.rs +++ b/src/test/run-pass/match-vec-alternatives.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str { diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs b/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs index 1717d0d54c02..6178f613b4b8 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] #![feature(match_default_bindings)] +#![feature(slice_patterns)] fn slice_pat() { let sl: &[u8] = b"foo"; diff --git a/src/test/run-pass/trailing-comma.rs b/src/test/run-pass/trailing-comma.rs index b9eda0846537..02bae5aa4551 100644 --- a/src/test/run-pass/trailing-comma.rs +++ b/src/test/run-pass/trailing-comma.rs @@ -10,7 +10,6 @@ // pretty-expanded FIXME #23616 -#![feature(advanced_slice_patterns,)] #![feature(slice_patterns)] fn f(_: T,) {} diff --git a/src/test/run-pass/vec-matching-autoslice.rs b/src/test/run-pass/vec-matching-autoslice.rs index 9df777e7af0d..7268536a51fa 100644 --- a/src/test/run-pass/vec-matching-autoslice.rs +++ b/src/test/run-pass/vec-matching-autoslice.rs @@ -8,9 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(slice_patterns)] - pub fn main() { let x = [1, 2, 3]; match x { diff --git a/src/test/run-pass/vec-matching-fixed.rs b/src/test/run-pass/vec-matching-fixed.rs index 1ed6ddc41107..060d152488a9 100644 --- a/src/test/run-pass/vec-matching-fixed.rs +++ b/src/test/run-pass/vec-matching-fixed.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] fn a() { diff --git a/src/test/run-pass/vec-matching-fold.rs b/src/test/run-pass/vec-matching-fold.rs index ac80a4211ada..1a30f875580c 100644 --- a/src/test/run-pass/vec-matching-fold.rs +++ b/src/test/run-pass/vec-matching-fold.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] use std::fmt::Debug; diff --git a/src/test/run-pass/vec-matching.rs b/src/test/run-pass/vec-matching.rs index bd0731a555cb..ace418f21606 100644 --- a/src/test/run-pass/vec-matching.rs +++ b/src/test/run-pass/vec-matching.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] fn a() { diff --git a/src/test/run-pass/vec-tail-matching.rs b/src/test/run-pass/vec-tail-matching.rs index d123eb36a7d4..4f31405ead50 100644 --- a/src/test/run-pass/vec-tail-matching.rs +++ b/src/test/run-pass/vec-tail-matching.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - - #![feature(slice_patterns)] struct Foo { diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs index 07b268f1a4b0..111968e9c931 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(slice_patterns)] diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr index e11702df80a9..6673549e2390 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `vec[..]` because it is borrowed - --> $DIR/borrowck-vec-pattern-nesting.rs:21:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:20:13 | LL | [box ref _a, _, _] => { | ------ borrow of `vec[..]` occurs here @@ -8,7 +8,7 @@ LL | vec[0] = box 4; //~ ERROR cannot assign | ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here error[E0506]: cannot assign to `vec[..]` because it is borrowed - --> $DIR/borrowck-vec-pattern-nesting.rs:33:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:32:13 | LL | &mut [ref _b..] => { | ------ borrow of `vec[..]` occurs here @@ -17,7 +17,7 @@ LL | vec[0] = box 4; //~ ERROR cannot assign | ^^^^^^^^^^^^^^ assignment to borrowed `vec[..]` occurs here error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:43:14 + --> $DIR/borrowck-vec-pattern-nesting.rs:42:14 | LL | &mut [_a, //~ ERROR cannot move out | ^-- hint: to prevent move, use `ref _a` or `ref mut _a` @@ -30,7 +30,7 @@ LL | | ] => { | |_________^ cannot move out of here error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:56:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:55:13 | LL | let a = vec[0]; //~ ERROR cannot move out | ^^^^^^ @@ -39,7 +39,7 @@ LL | let a = vec[0]; //~ ERROR cannot move out | help: consider using a reference instead: `&vec[0]` error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:64:14 + --> $DIR/borrowck-vec-pattern-nesting.rs:63:14 | LL | &mut [ //~ ERROR cannot move out | ______________^ @@ -50,7 +50,7 @@ LL | | _b] => {} | hint: to prevent move, use `ref _b` or `ref mut _b` error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:69:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:68:13 | LL | let a = vec[0]; //~ ERROR cannot move out | ^^^^^^ @@ -59,7 +59,7 @@ LL | let a = vec[0]; //~ ERROR cannot move out | help: consider using a reference instead: `&vec[0]` error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:77:14 + --> $DIR/borrowck-vec-pattern-nesting.rs:76:14 | LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out | ^--^^--^^--^ @@ -70,7 +70,7 @@ LL | &mut [_a, _b, _c] => {} //~ ERROR cannot move out | cannot move out of here error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:81:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:80:13 | LL | let a = vec[0]; //~ ERROR cannot move out | ^^^^^^ diff --git a/src/test/ui/error-codes/E0527.rs b/src/test/ui/error-codes/E0527.rs index 67d222e867e6..a90ccec9cf5e 100644 --- a/src/test/ui/error-codes/E0527.rs +++ b/src/test/ui/error-codes/E0527.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - fn main() { let r = &[1, 2, 3, 4]; match r { diff --git a/src/test/ui/error-codes/E0527.stderr b/src/test/ui/error-codes/E0527.stderr index 2060f1e69e0c..1e764c185877 100644 --- a/src/test/ui/error-codes/E0527.stderr +++ b/src/test/ui/error-codes/E0527.stderr @@ -1,5 +1,5 @@ error[E0527]: pattern requires 2 elements but array has 4 - --> $DIR/E0527.rs:16:10 + --> $DIR/E0527.rs:14:10 | LL | &[a, b] => { | ^^^^^^ expected 4 elements diff --git a/src/test/ui/error-codes/E0529.rs b/src/test/ui/error-codes/E0529.rs index 5262ad7b716f..2459054da89a 100644 --- a/src/test/ui/error-codes/E0529.rs +++ b/src/test/ui/error-codes/E0529.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - fn main() { let r: f32 = 1.0; match r { diff --git a/src/test/ui/error-codes/E0529.stderr b/src/test/ui/error-codes/E0529.stderr index fcada0007906..b2e7ae23fb0e 100644 --- a/src/test/ui/error-codes/E0529.stderr +++ b/src/test/ui/error-codes/E0529.stderr @@ -1,5 +1,5 @@ error[E0529]: expected an array or slice, found `f32` - --> $DIR/E0529.rs:16:9 + --> $DIR/E0529.rs:14:9 | LL | [a, b] => { | ^^^^^^ pattern cannot match with input type `f32` diff --git a/src/test/ui/feature-gate-advanced-slice-features.rs b/src/test/ui/feature-gate-advanced-slice-features.rs deleted file mode 100644 index dc9b4e634ab7..000000000000 --- a/src/test/ui/feature-gate-advanced-slice-features.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2014 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. - -// gate-test-advanced_slice_patterns - -#![feature(slice_patterns)] - -fn main() { - let x = [ 1, 2, 3, 4, 5 ]; - match x { - [ xs.., 4, 5 ] => {} //~ ERROR multiple-element slice matches - [ 1, xs.., 5 ] => {} //~ ERROR multiple-element slice matches - [ 1, 2, xs.. ] => {} // OK without feature gate - } -} diff --git a/src/test/ui/feature-gate-advanced-slice-features.stderr b/src/test/ui/feature-gate-advanced-slice-features.stderr deleted file mode 100644 index 9d9e75549761..000000000000 --- a/src/test/ui/feature-gate-advanced-slice-features.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0658]: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121) - --> $DIR/feature-gate-advanced-slice-features.rs:18:9 - | -LL | [ xs.., 4, 5 ] => {} //~ ERROR multiple-element slice matches - | ^^^^^^^^^^^^^^ - | - = help: add #![feature(advanced_slice_patterns)] to the crate attributes to enable - -error[E0658]: multiple-element slice matches anywhere but at the end of a slice (e.g. `[0, ..xs, 0]`) are experimental (see issue #23121) - --> $DIR/feature-gate-advanced-slice-features.rs:19:9 - | -LL | [ 1, xs.., 5 ] => {} //~ ERROR multiple-element slice matches - | ^^^^^^^^^^^^^^ - | - = help: add #![feature(advanced_slice_patterns)] to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-slice-patterns.rs b/src/test/ui/feature-gate-slice-patterns.rs index 625cb2d35155..fd058f651721 100644 --- a/src/test/ui/feature-gate-slice-patterns.rs +++ b/src/test/ui/feature-gate-slice-patterns.rs @@ -8,11 +8,20 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that slice pattern syntax is gated by `slice_patterns` feature gate +// Test that slice pattern syntax with `..` is gated by `slice_patterns` feature gate fn main() { let x = [1, 2, 3, 4, 5]; match x { - [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental + [1, 2, ..] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [1, .., 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [.., 4, 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + } + + let x = [ 1, 2, 3, 4, 5 ]; + match x { + [ xs.., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [ 1, xs.., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + [ 1, 2, xs.. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized } } diff --git a/src/test/ui/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gate-slice-patterns.stderr index 7c216fad933e..d560dcd54eef 100644 --- a/src/test/ui/feature-gate-slice-patterns.stderr +++ b/src/test/ui/feature-gate-slice-patterns.stderr @@ -1,11 +1,51 @@ -error[E0658]: slice pattern syntax is experimental (see issue #23121) - --> $DIR/feature-gate-slice-patterns.rs:16:9 +error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121) + --> $DIR/feature-gate-slice-patterns.rs:16:16 | -LL | [1, 2, xs..] => {} //~ ERROR slice pattern syntax is experimental - | ^^^^^^^^^^^^ +LL | [1, 2, ..] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + | ^^ | = help: add #![feature(slice_patterns)] to the crate attributes to enable -error: aborting due to previous error +error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121) + --> $DIR/feature-gate-slice-patterns.rs:17:13 + | +LL | [1, .., 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + | ^^ + | + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121) + --> $DIR/feature-gate-slice-patterns.rs:18:10 + | +LL | [.., 4, 5] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + | ^^ + | + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121) + --> $DIR/feature-gate-slice-patterns.rs:23:11 + | +LL | [ xs.., 4, 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + | ^^ + | + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121) + --> $DIR/feature-gate-slice-patterns.rs:24:14 + | +LL | [ 1, xs.., 5 ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + | ^^ + | + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error[E0658]: syntax for subslices in slice patterns is not yet stabilized (see issue #23121) + --> $DIR/feature-gate-slice-patterns.rs:25:17 + | +LL | [ 1, 2, xs.. ] => {} //~ ERROR syntax for subslices in slice patterns is not yet stabilized + | ^^ + | + = help: add #![feature(slice_patterns)] to the crate attributes to enable + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/mismatched_types/issue-38371.rs b/src/test/ui/mismatched_types/issue-38371.rs index b9b6b05996b6..8e613d4edba1 100644 --- a/src/test/ui/mismatched_types/issue-38371.rs +++ b/src/test/ui/mismatched_types/issue-38371.rs @@ -7,8 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - struct Foo { } diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr index 1bf1521e39e0..dd5da7690751 100644 --- a/src/test/ui/mismatched_types/issue-38371.stderr +++ b/src/test/ui/mismatched_types/issue-38371.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-38371.rs:16:8 + --> $DIR/issue-38371.rs:14:8 | LL | fn foo(&foo: Foo) { //~ ERROR mismatched types | ^^^^ expected struct `Foo`, found reference @@ -9,7 +9,7 @@ LL | fn foo(&foo: Foo) { //~ ERROR mismatched types = help: did you mean `foo: &Foo`? error[E0308]: mismatched types - --> $DIR/issue-38371.rs:30:9 + --> $DIR/issue-38371.rs:28:9 | LL | fn agh(&&bar: &u32) { //~ ERROR mismatched types | ^^^^ expected u32, found reference @@ -19,7 +19,7 @@ LL | fn agh(&&bar: &u32) { //~ ERROR mismatched types = help: did you mean `bar: &u32`? error[E0308]: mismatched types - --> $DIR/issue-38371.rs:33:8 + --> $DIR/issue-38371.rs:31:8 | LL | fn bgh(&&bar: u32) { //~ ERROR mismatched types | ^^^^^ expected u32, found reference @@ -28,7 +28,7 @@ LL | fn bgh(&&bar: u32) { //~ ERROR mismatched types found type `&_` error[E0529]: expected an array or slice, found `u32` - --> $DIR/issue-38371.rs:36:9 + --> $DIR/issue-38371.rs:34:9 | LL | fn ugh(&[bar]: &u32) { //~ ERROR expected an array or slice | ^^^^^ pattern cannot match with input type `u32` diff --git a/src/test/ui/non-exhaustive-pattern-witness.rs b/src/test/ui/non-exhaustive-pattern-witness.rs index 0b12a9acbcb9..dd14a10a2bce 100644 --- a/src/test/ui/non-exhaustive-pattern-witness.rs +++ b/src/test/ui/non-exhaustive-pattern-witness.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(advanced_slice_patterns)] #![feature(slice_patterns)] struct Foo { diff --git a/src/test/ui/non-exhaustive-pattern-witness.stderr b/src/test/ui/non-exhaustive-pattern-witness.stderr index 7179b4b135a1..e364e822ea87 100644 --- a/src/test/ui/non-exhaustive-pattern-witness.stderr +++ b/src/test/ui/non-exhaustive-pattern-witness.stderr @@ -1,41 +1,41 @@ error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:20:11 + --> $DIR/non-exhaustive-pattern-witness.rs:19:11 | LL | match (Foo { first: true, second: None }) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered error[E0004]: non-exhaustive patterns: `Red` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:36:11 + --> $DIR/non-exhaustive-pattern-witness.rs:35:11 | LL | match Color::Red { | ^^^^^^^^^^ pattern `Red` not covered error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:48:11 + --> $DIR/non-exhaustive-pattern-witness.rs:47:11 | LL | match Direction::North { | ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered - --> $DIR/non-exhaustive-pattern-witness.rs:59:11 + --> $DIR/non-exhaustive-pattern-witness.rs:58:11 | LL | match ExcessiveEnum::First { | ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:67:11 + --> $DIR/non-exhaustive-pattern-witness.rs:66:11 | LL | match Color::Red { | ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:83:11 + --> $DIR/non-exhaustive-pattern-witness.rs:82:11 | LL | match *x { | ^^ pattern `[Second(true), Second(false)]` not covered error[E0004]: non-exhaustive patterns: `((), false)` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:96:11 + --> $DIR/non-exhaustive-pattern-witness.rs:95:11 | LL | match ((), false) { | ^^^^^^^^^^^ pattern `((), false)` not covered diff --git a/src/test/ui/pat-slice-old-style.rs b/src/test/ui/pat-slice-old-style.rs index 4ff1e94b0872..65578e76d6d6 100644 --- a/src/test/ui/pat-slice-old-style.rs +++ b/src/test/ui/pat-slice-old-style.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] - // NB: this test was introduced in #23121 and will have to change when default match binding modes // stabilizes. +#![feature(slice_patterns)] + fn slice_pat(x: &[u8]) { // OLD! match x { diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs index 40aa957242cb..20ef0624bf91 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(slice_patterns)] #![feature(match_default_bindings)] +#![feature(slice_patterns)] pub fn main() { let sl: &[u8] = b"foo"; From c43b1a09e034f978317bf087214f8f4cde80ba40 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 15 Mar 2018 18:56:20 -0400 Subject: [PATCH 422/830] Convert SerializedDepGraph to be a struct-of-arrays Fixes #47326 --- src/librustc/dep_graph/graph.rs | 7 +++---- src/librustc/dep_graph/prev.rs | 8 ++++---- src/librustc/dep_graph/serialized.rs | 6 +++++- src/librustc_data_structures/indexed_vec.rs | 7 +++++++ src/librustc_incremental/persist/save.rs | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 0ad79eacd2b0..d60c22064d3a 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -476,10 +476,8 @@ impl DepGraph { fingerprints.resize(current_dep_graph.nodes.len(), Fingerprint::ZERO); } - let nodes: IndexVec<_, (DepNode, Fingerprint)> = - current_dep_graph.nodes.iter_enumerated().map(|(idx, &dep_node)| { - (dep_node, fingerprints[idx]) - }).collect(); + let fingerprints = fingerprints.clone().convert_index_type(); + let nodes = current_dep_graph.nodes.clone().convert_index_type(); let total_edge_count: usize = current_dep_graph.edges.iter() .map(|v| v.len()) @@ -503,6 +501,7 @@ impl DepGraph { SerializedDepGraph { nodes, + fingerprints, edge_list_indices, edge_list_data, } diff --git a/src/librustc/dep_graph/prev.rs b/src/librustc/dep_graph/prev.rs index 504b60e763e2..669a99019aa6 100644 --- a/src/librustc/dep_graph/prev.rs +++ b/src/librustc/dep_graph/prev.rs @@ -23,7 +23,7 @@ impl PreviousDepGraph { pub fn new(data: SerializedDepGraph) -> PreviousDepGraph { let index: FxHashMap<_, _> = data.nodes .iter_enumerated() - .map(|(idx, &(dep_node, _))| (dep_node, idx)) + .map(|(idx, &dep_node)| (dep_node, idx)) .collect(); PreviousDepGraph { data, index } } @@ -41,7 +41,7 @@ impl PreviousDepGraph { #[inline] pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode { - self.data.nodes[dep_node_index].0 + self.data.nodes[dep_node_index] } #[inline] @@ -58,14 +58,14 @@ impl PreviousDepGraph { pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { self.index .get(dep_node) - .map(|&node_index| self.data.nodes[node_index].1) + .map(|&node_index| self.data.fingerprints[node_index]) } #[inline] pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { - self.data.nodes[dep_node_index].1 + self.data.fingerprints[dep_node_index] } pub fn node_count(&self) -> usize { diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs index c96040ab9b6e..60fc813a25d5 100644 --- a/src/librustc/dep_graph/serialized.rs +++ b/src/librustc/dep_graph/serialized.rs @@ -20,7 +20,10 @@ newtype_index!(SerializedDepNodeIndex); #[derive(Debug, RustcEncodable, RustcDecodable)] pub struct SerializedDepGraph { /// The set of all DepNodes in the graph - pub nodes: IndexVec, + pub nodes: IndexVec, + /// The set of all Fingerprints in the graph. Each Fingerprint corresponds to + /// the DepNode at the same index in the nodes vector. + pub fingerprints: IndexVec, /// For each DepNode, stores the list of edges originating from that /// DepNode. Encoded as a [start, end) pair indexing into edge_list_data, /// which holds the actual DepNodeIndices of the target nodes. @@ -35,6 +38,7 @@ impl SerializedDepGraph { pub fn new() -> SerializedDepGraph { SerializedDepGraph { nodes: IndexVec::new(), + fingerprints: IndexVec::new(), edge_list_indices: IndexVec::new(), edge_list_data: Vec::new(), } diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index a5b1a7e57ab4..cbb3ff517159 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -503,6 +503,13 @@ impl IndexVec { (c1, c2) } } + + pub fn convert_index_type(self) -> IndexVec { + IndexVec { + raw: self.raw, + _marker: PhantomData, + } + } } impl IndexVec { diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index ca1e3563089d..a5bc1106ba0b 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -162,7 +162,7 @@ fn encode_dep_graph(tcx: TyCtxt, let mut counts: FxHashMap<_, Stat> = FxHashMap(); - for (i, &(node, _)) in serialized_graph.nodes.iter_enumerated() { + for (i, &node) in serialized_graph.nodes.iter_enumerated() { let stat = counts.entry(node.kind).or_insert(Stat { kind: node.kind, node_counter: 0, From 062a46fdd1d49b1ccdc4f713433521463224d7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 19 Mar 2018 14:13:57 -0700 Subject: [PATCH 423/830] Reduce diagnostic verbosity by removing labels --- src/librustc_typeck/check/_match.rs | 17 +++++++++-------- .../compile-fail/struct-pat-derived-error.rs | 6 ++---- src/test/ui/error-codes/E0026-teach.stderr | 2 +- src/test/ui/error-codes/E0026.stderr | 2 +- src/test/ui/missing-fields-in-struct-pattern.rs | 2 +- .../ui/missing-fields-in-struct-pattern.stderr | 6 +----- src/test/ui/numeric-fields.stderr | 2 +- src/test/ui/type-check/issue-41314.stderr | 2 +- src/test/ui/union/union-fields-2.stderr | 2 +- 9 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index cc72a565ba28..7965806af5d0 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -938,14 +938,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); } if inexistent_fields.len() > 0 { - let field_names = if inexistent_fields.len() == 1 { - format!("a field named `{}`", inexistent_fields[0].1) + let (field_names, t, plural) = if inexistent_fields.len() == 1 { + (format!("a field named `{}`", inexistent_fields[0].1), "this", "") } else { - format!("fields named {}", - inexistent_fields.iter() + (format!("fields named {}", + inexistent_fields.iter() .map(|(_, name)| format!("`{}`", name)) .collect::>() - .join(", ")) + .join(", ")), "these", "s") }; let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); let mut err = struct_span_err!(tcx.sess, @@ -955,12 +955,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); kind_name, tcx.item_path_str(variant.did), field_names); - for (span, name) in &inexistent_fields { + if let Some((span, _)) = inexistent_fields.last() { err.span_label(*span, - format!("{} `{}` does not have field `{}`", + format!("{} `{}` does not have {} field{}", kind_name, tcx.item_path_str(variant.did), - name)); + t, + plural)); } if tcx.sess.teach(&err.get_code().unwrap()) { err.note( diff --git a/src/test/compile-fail/struct-pat-derived-error.rs b/src/test/compile-fail/struct-pat-derived-error.rs index f525ec373753..d3130c4e831f 100644 --- a/src/test/compile-fail/struct-pat-derived-error.rs +++ b/src/test/compile-fail/struct-pat-derived-error.rs @@ -16,10 +16,8 @@ struct a { impl a { fn foo(&self) { let a { x, y } = self.d; //~ ERROR no field `d` on type `&a` - //~^ ERROR struct `a` does not have a field named `x` - //~^^ ERROR struct `a` does not have a field named `y` - //~^^^ ERROR pattern does not mention field `b` - //~^^^^ ERROR pattern does not mention field `c` + //~^ ERROR struct `a` does not have fields named `x`, `y` + //~| ERROR pattern does not mention fields `b`, `c` } } diff --git a/src/test/ui/error-codes/E0026-teach.stderr b/src/test/ui/error-codes/E0026-teach.stderr index 63d072fe03d0..67ea32fba86d 100644 --- a/src/test/ui/error-codes/E0026-teach.stderr +++ b/src/test/ui/error-codes/E0026-teach.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026-teach.rs:21:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field | = note: This error indicates that a struct pattern attempted to extract a non-existent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched. diff --git a/src/test/ui/error-codes/E0026.stderr b/src/test/ui/error-codes/E0026.stderr index af8519511276..9dabbc8a775f 100644 --- a/src/test/ui/error-codes/E0026.stderr +++ b/src/test/ui/error-codes/E0026.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026.rs:19:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field error: aborting due to previous error diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 28ed151b9860..dfde37994998 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -13,7 +13,7 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] - //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] + //~| ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr index 88fba19d14e3..d1c3260f11e3 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.stderr +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -2,11 +2,7 @@ error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` --> $DIR/missing-fields-in-struct-pattern.rs:14:16 | LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { - | ^ ^ ^ ^ struct `S` does not have field `d` - | | | | - | | | struct `S` does not have field `c` - | | struct `S` does not have field `b` - | struct `S` does not have field `a` + | ^ ^ ^ ^ struct `S` does not have these fields error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` --> $DIR/missing-fields-in-struct-pattern.rs:14:12 diff --git a/src/test/ui/numeric-fields.stderr b/src/test/ui/numeric-fields.stderr index 607980ba3bf5..68a87da8ded3 100644 --- a/src/test/ui/numeric-fields.stderr +++ b/src/test/ui/numeric-fields.stderr @@ -10,7 +10,7 @@ error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:17:17 | LL | S{0: a, 0x1: b, ..} => {} - | ^^^^^^ struct `S` does not have field `0x1` + | ^^^^^^ struct `S` does not have this field error: aborting due to 2 previous errors diff --git a/src/test/ui/type-check/issue-41314.stderr b/src/test/ui/type-check/issue-41314.stderr index bcb0f9a99a77..f7d4bb9a02f4 100644 --- a/src/test/ui/type-check/issue-41314.stderr +++ b/src/test/ui/type-check/issue-41314.stderr @@ -2,7 +2,7 @@ error[E0026]: variant `X::Y` does not have a field named `number` --> $DIR/issue-41314.rs:17:16 | LL | X::Y { number } => {} //~ ERROR does not have a field named `number` - | ^^^^^^ variant `X::Y` does not have field `number` + | ^^^^^^ variant `X::Y` does not have this field error[E0027]: pattern does not mention field `0` --> $DIR/issue-41314.rs:17:9 diff --git a/src/test/ui/union/union-fields-2.stderr b/src/test/ui/union/union-fields-2.stderr index 3ea4d3426dad..cfb5bc7520b5 100644 --- a/src/test/ui/union/union-fields-2.stderr +++ b/src/test/ui/union/union-fields-2.stderr @@ -52,7 +52,7 @@ error[E0026]: union `U` does not have a field named `c` --> $DIR/union-fields-2.rs:28:19 | LL | let U { a, b, c } = u; //~ ERROR union patterns should have exactly one field - | ^ union `U` does not have field `c` + | ^ union `U` does not have this field error: union patterns should have exactly one field --> $DIR/union-fields-2.rs:28:9 From 57e3df3f879090207f5a128a497b66916aeabb6b Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Mon, 19 Mar 2018 23:35:23 -0400 Subject: [PATCH 424/830] Fix ordering of auto-generated trait bounds in rustdoc output While the order of the where clauses was deterministic, the ordering of bounds and lifetimes was not. This made the order flip- flop randomly when new traits and impls were added to libstd. This PR makes the ordering of bounds and lifetimes deterministic, and re-enables the test that was causing the issue. Fixes #49123 --- src/librustdoc/clean/auto_trait.rs | 102 ++++++++++++------ .../rustdoc/synthetic_auto/no-redundancy.rs | 2 - 2 files changed, 67 insertions(+), 37 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 370fc9bbca24..918bc1df0b1d 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -9,6 +9,7 @@ // except according to those terms. use rustc::ty::TypeFoldable; +use std::fmt::Debug; use super::*; @@ -1081,18 +1082,25 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { return None; } + let mut bounds_vec = bounds.into_iter().collect(); + self.sort_where_bounds(&mut bounds_vec); + Some(WherePredicate::BoundPredicate { ty, - bounds: bounds.into_iter().collect(), + bounds: bounds_vec, }) }) .chain( lifetime_to_bounds .into_iter() .filter(|&(_, ref bounds)| !bounds.is_empty()) - .map(|(lifetime, bounds)| WherePredicate::RegionPredicate { - lifetime, - bounds: bounds.into_iter().collect(), + .map(|(lifetime, bounds)| { + let mut bounds_vec = bounds.into_iter().collect(); + self.sort_where_lifetimes(&mut bounds_vec); + WherePredicate::RegionPredicate { + lifetime, + bounds: bounds_vec, + } }), ) .collect() @@ -1372,40 +1380,64 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // a given set of predicates always appears in the same order - // both for visual consistency between 'rustdoc' runs, and to // make writing tests much easier - fn sort_where_predicates(&self, predicates: &mut Vec) { + #[inline] + fn sort_where_predicates(&self, mut predicates: &mut Vec) { // We should never have identical bounds - and if we do, // they're visually identical as well. Therefore, using // an unstable sort is fine. - predicates.sort_unstable_by(|first, second| { - // This might look horrendously hacky, but it's actually not that bad. - // - // For performance reasons, we use several different FxHashMaps - // in the process of computing the final set of where predicates. - // However, the iteration order of a HashMap is completely unspecified. - // In fact, the iteration of an FxHashMap can even vary between platforms, - // since FxHasher has different behavior for 32-bit and 64-bit platforms. - // - // Obviously, it's extremely undesireable for documentation rendering - // to be depndent on the platform it's run on. Apart from being confusing - // to end users, it makes writing tests much more difficult, as predicates - // can appear in any order in the final result. - // - // To solve this problem, we sort WherePredicates by their Debug - // string. The thing to keep in mind is that we don't really - // care what the final order is - we're synthesizing an impl - // ourselves, so any order can be considered equally valid. - // By sorting the predicates, however, we ensure that for - // a given codebase, all auto-trait impls always render - // in exactly the same way. - // - // Using the Debug impementation for sorting prevents - // us from needing to write quite a bit of almost - // entirely useless code (e.g. how should two - // Types be sorted relative to each other). - // This approach is probably somewhat slower, but - // the small number of items involved (impls - // rarely have more than a few bounds) means - // that it shouldn't matter in practice. + self.unstable_debug_sort(&mut predicates); + } + + // Ensure that the bounds are in a consistent order. The precise + // ordering doesn't actually matter, but it's important that + // a given set of bounds always appears in the same order - + // both for visual consistency between 'rustdoc' runs, and to + // make writing tests much easier + #[inline] + fn sort_where_bounds(&self, mut bounds: &mut Vec) { + // We should never have identical bounds - and if we do, + // they're visually identical as well. Therefore, using + // an unstable sort is fine. + self.unstable_debug_sort(&mut bounds); + } + + #[inline] + fn sort_where_lifetimes(&self, mut bounds: &mut Vec) { + // We should never have identical bounds - and if we do, + // they're visually identical as well. Therefore, using + // an unstable sort is fine. + self.unstable_debug_sort(&mut bounds); + } + + // This might look horrendously hacky, but it's actually not that bad. + // + // For performance reasons, we use several different FxHashMaps + // in the process of computing the final set of where predicates. + // However, the iteration order of a HashMap is completely unspecified. + // In fact, the iteration of an FxHashMap can even vary between platforms, + // since FxHasher has different behavior for 32-bit and 64-bit platforms. + // + // Obviously, it's extremely undesireable for documentation rendering + // to be depndent on the platform it's run on. Apart from being confusing + // to end users, it makes writing tests much more difficult, as predicates + // can appear in any order in the final result. + // + // To solve this problem, we sort WherePredicates and TyParamBounds + // by their Debug string. The thing to keep in mind is that we don't really + // care what the final order is - we're synthesizing an impl or bound + // ourselves, so any order can be considered equally valid. By sorting the + // predicates and bounds, however, we ensure that for a given codebase, all + // auto-trait impls always render in exactly the same way. + // + // Using the Debug impementation for sorting prevents us from needing to + // write quite a bit of almost entirely useless code (e.g. how should two + // Types be sorted relative to each other). It also allows us to solve the + // problem for both WherePredicates and TyParamBounds at the same time. This + // approach is probably somewhat slower, but the small number of items + // involved (impls rarely have more than a few bounds) means that it + // shouldn't matter in practice. + fn unstable_debug_sort(&self, vec: &mut Vec) { + vec.sort_unstable_by(|first, second| { format!("{:?}", first).cmp(&format!("{:?}", second)) }); } diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index daa91c3e12bb..0b37f2ed3179 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test - pub struct Inner { field: T, } From 7daf3f941af996d6b816aa778aab4b9348d26703 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 20 Mar 2018 01:02:15 -0400 Subject: [PATCH 425/830] Fix tidy trailing whitespace --- src/librustdoc/clean/auto_trait.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 918bc1df0b1d..9ff3d25a45ae 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -1387,7 +1387,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // an unstable sort is fine. self.unstable_debug_sort(&mut predicates); } - + // Ensure that the bounds are in a consistent order. The precise // ordering doesn't actually matter, but it's important that // a given set of bounds always appears in the same order - @@ -1400,7 +1400,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { // an unstable sort is fine. self.unstable_debug_sort(&mut bounds); } - + #[inline] fn sort_where_lifetimes(&self, mut bounds: &mut Vec) { // We should never have identical bounds - and if we do, From be29e52c5a3d9da894a0292f9175106a955071c9 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 00:02:17 -0500 Subject: [PATCH 426/830] Match against friendly error message --- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index ff2b32f3fd93..67ee39d10d91 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:`main` can only return types that implement std::process::Termination, not `i32` fn main() -> i32 { -//~^ ERROR the trait bound `i32: std::process::Termination` is not satisfied [E0277] 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index ea39ba92f414..5f4ccf2b5862 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// error-pattern:`main` can only return types that implement std::process::Termination, not `char fn main() -> char { -//~^ ERROR: the trait bound `char: std::process::Termination` is not satisfied ' ' } From 5ccf3ffab24a4237e467b884af6783b1af54bdd8 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 00:06:46 -0500 Subject: [PATCH 427/830] diagnostics: Remove main return type errors from E0580 --- src/librustc/diagnostics.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b3a904f2f5fe..7627071e5603 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1764,12 +1764,12 @@ The `main` function was incorrectly declared. Erroneous code example: ```compile_fail,E0580 -fn main() -> i32 { // error: main function has wrong type - 0 +fn main(x: i32) { // error: main function has wrong type + println!("{}", x); } ``` -The `main` function prototype should never take arguments or return type. +The `main` function prototype should never take arguments. Example: ``` From 4eff4d9500968e8a6275185eac153e102996edb5 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Tue, 20 Mar 2018 08:25:25 +0100 Subject: [PATCH 428/830] ignore emscripten in run-pass test --- src/test/run-pass/simd-intrinsic-generic-select.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/run-pass/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd-intrinsic-generic-select.rs index bf0a59309ca2..8e94d797e894 100644 --- a/src/test/run-pass/simd-intrinsic-generic-select.rs +++ b/src/test/run-pass/simd-intrinsic-generic-select.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten + // Test that the simd_select intrinsics produces correct results. #![feature(repr_simd, platform_intrinsics)] From 619003d1d414167630331efffe83702f74413be6 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 20 Mar 2018 05:33:59 -0400 Subject: [PATCH 429/830] Implement some trivial size_hints for various iterators This also implements ExactSizeIterator where applicable. Addresses most of the Iterator traits mentioned in #23708. --- src/libcore/char.rs | 5 ++++ src/libcore/iter/traits.rs | 4 ++++ src/libcore/option.rs | 5 ++++ src/librustc/hir/pat_util.rs | 4 ++++ src/librustc/mir/traversal.rs | 26 +++++++++++++++++++++ src/librustc/session/search_paths.rs | 7 ++++++ src/librustc/traits/util.rs | 5 ++++ src/librustc_data_structures/bitvec.rs | 5 ++++ src/librustc_data_structures/graph/mod.rs | 13 +++++++++++ src/librustc_driver/pretty.rs | 7 ++++++ src/librustc_typeck/check/method/suggest.rs | 7 ++++++ src/librustdoc/clean/mod.rs | 5 ++++ src/libsyntax_ext/format_foreign.rs | 9 +++++++ 13 files changed, 102 insertions(+) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 1638f9710f59..2f56238a4638 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -902,6 +902,11 @@ impl> Iterator for DecodeUtf8 { } }) } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } } #[unstable(feature = "decode_utf8", issue = "33906")] diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 0267fcd37545..5e4622f804af 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -901,6 +901,10 @@ impl Iterator for ResultShunt None => None, } } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } } #[stable(feature = "iter_arith_traits_result", since="1.16.0")] diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 570f745f8330..1ca69f3f503d 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1188,6 +1188,11 @@ impl> FromIterator> for Option { None => None, } } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } } let mut adapter = Adapter { iter: iter.into_iter(), found_none: false }; diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 2bec224362ea..1f00a3ab1f5d 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -31,6 +31,10 @@ impl Iterator for EnumerateAndAdjust where I: Iterator { (if i < self.gap_pos { i } else { i + self.gap_len }, elem) }) } + + fn size_hint(&self) -> (usize, Option) { + self.enumerate.size_hint() + } } pub trait EnumerateAndAdjustIterator { diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index 74c3408c4c2f..666ca5eabe81 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -77,8 +77,18 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { None } + + fn size_hint(&self) -> (usize, Option) { + // All the blocks, minus the number of blocks we've visited. + let remaining = self.mir.basic_blocks().len() - self.visited.count(); + + // We will visit all remaining blocks exactly once. + (remaining, Some(remaining)) + } } +impl<'a, 'tcx> ExactSizeIterator for Preorder<'a, 'tcx> {} + /// Postorder traversal of a graph. /// /// Postorder traversal is when each node is visited after all of it's @@ -210,8 +220,18 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { next.map(|(bb, _)| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option) { + // All the blocks, minus the number of blocks we've visited. + let remaining = self.mir.basic_blocks().len() - self.visited.count(); + + // We will visit all remaining blocks exactly once. + (remaining, Some(remaining)) + } } +impl<'a, 'tcx> ExactSizeIterator for Postorder<'a, 'tcx> {} + /// Reverse postorder traversal of a graph /// /// Reverse postorder is the reverse order of a postorder traversal. @@ -276,4 +296,10 @@ impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> { self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb])) } + + fn size_hint(&self) -> (usize, Option) { + (self.idx, Some(self.idx)) + } } + +impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {} diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 5bbc6841693e..d2dca9f60845 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -78,4 +78,11 @@ impl<'a> Iterator for Iter<'a> { } } } + + fn size_hint(&self) -> (usize, Option) { + // This iterator will never return more elements than the base iterator; + // but it can ignore all the remaining elements. + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 8f7a24057472..9e38911f53c9 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -347,6 +347,11 @@ impl<'tcx,I:Iterator>> Iterator for FilterToTraits { } } } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.base_iterator.size_hint(); + (0, upper) + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_data_structures/bitvec.rs b/src/librustc_data_structures/bitvec.rs index 54565afa4c6c..28e3180063c1 100644 --- a/src/librustc_data_structures/bitvec.rs +++ b/src/librustc_data_structures/bitvec.rs @@ -132,6 +132,11 @@ impl<'a> Iterator for BitVectorIter<'a> { self.idx += offset + 1; return Some(self.idx - 1); } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } impl FromIterator for BitVector { diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 1945b82c0314..e2b393071ff5 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -334,6 +334,11 @@ impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> { self.next = edge.next_edge[self.direction.repr]; Some((edge_index, edge)) } + + fn size_hint(&self) -> (usize, Option) { + // At most, all the edges in the graph. + (0, Some(self.graph.len_edges())) + } } pub struct DepthFirstTraversal<'g, N, E> @@ -383,8 +388,16 @@ impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> { } next } + + fn size_hint(&self) -> (usize, Option) { + // We will visit every node in the graph exactly once. + let remaining = self.graph.len_nodes() - self.visited.count(); + (remaining, Some(remaining)) + } } +impl<'g, N: Debug, E: Debug> ExactSizeIterator for DepthFirstTraversal<'g, N, E> {} + impl Edge { pub fn source(&self) -> NodeIndex { self.source diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 4ae6a93d6983..c5e7fdb30d36 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -584,6 +584,13 @@ impl<'a, 'hir> Iterator for NodesMatchingUII<'a, 'hir> { &mut NodesMatchingSuffix(ref mut iter) => iter.next(), } } + + fn size_hint(&self) -> (usize, Option) { + match self { + &NodesMatchingDirect(ref iter) => iter.size_hint(), + &NodesMatchingSuffix(ref iter) => iter.size_hint(), + } + } } impl UserIdentifiedItem { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 61afac97d640..a75369805033 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -718,8 +718,15 @@ impl<'a> Iterator for AllTraits<'a> { TraitInfo::new(*info) }) } + + fn size_hint(&self) -> (usize, Option) { + let len = self.borrow.as_ref().unwrap().len() - self.idx; + (len, Some(len)) + } } +impl<'a> ExactSizeIterator for AllTraits<'a> {} + struct UsePlacementFinder<'a, 'tcx: 'a, 'gcx: 'tcx> { target_module: ast::NodeId, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 904c24815cb7..a2a0e878fd88 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -602,6 +602,11 @@ impl<'a> Iterator for ListAttributesIter<'a> { None } + + fn size_hint(&self) -> (usize, Option) { + let lower = self.current_list.len(); + (lower, None) + } } pub trait AttributesExt { diff --git a/src/libsyntax_ext/format_foreign.rs b/src/libsyntax_ext/format_foreign.rs index 0476d7d4fcc1..e95c6f2e1243 100644 --- a/src/libsyntax_ext/format_foreign.rs +++ b/src/libsyntax_ext/format_foreign.rs @@ -272,6 +272,11 @@ pub mod printf { self.s = tail; Some(sub) } + + fn size_hint(&self) -> (usize, Option) { + // Substitutions are at least 2 characters long. + (0, Some(self.s.len() / 2)) + } } enum State { @@ -782,6 +787,10 @@ pub mod shell { None => None, } } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.s.len())) + } } /// Parse the next substitution from the input string. From 13bfbe1394732163c7130dd57e6b0a86e147c7e8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 20 Mar 2018 10:36:45 +0100 Subject: [PATCH 430/830] Encode/decode extern statics in metadata and incremental cache --- src/librustc/mir/interpret/mod.rs | 14 +++++++++++++ src/librustc/ty/maps/on_disk_cache.rs | 2 +- src/librustc_metadata/encoder.rs | 4 ++-- .../incremental/extern_static/issue-49153.rs | 21 +++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/test/incremental/extern_static/issue-49153.rs diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 04ffb9af29ed..e242ec4985ab 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -156,6 +156,8 @@ impl ::rustc_serialize::UseSpecializedDecodable for AllocId {} pub const ALLOC_DISCRIMINANT: usize = 0; pub const FN_DISCRIMINANT: usize = 1; +pub const EXTERN_STATIC_DISCRIMINANT: usize = 2; +pub const SHORTHAND_START: usize = 3; pub fn specialized_encode_alloc_id< 'a, 'tcx, @@ -173,6 +175,7 @@ pub fn specialized_encode_alloc_id< trace!("encoding {:?} with {:#?}", alloc_id, alloc); ALLOC_DISCRIMINANT.encode(encoder)?; alloc.encode(encoder)?; + // encode whether this allocation is the root allocation of a static tcx.interpret_interner .get_corresponding_static_def_id(alloc_id) .encode(encoder)?; @@ -180,6 +183,10 @@ pub fn specialized_encode_alloc_id< trace!("encoding {:?} with {:#?}", alloc_id, fn_instance); FN_DISCRIMINANT.encode(encoder)?; fn_instance.encode(encoder)?; + } else if let Some(did) = tcx.interpret_interner.get_corresponding_static_def_id(alloc_id) { + // extern "C" statics don't have allocations, just encode its def_id + EXTERN_STATIC_DISCRIMINANT.encode(encoder)?; + did.encode(encoder)?; } else { bug!("alloc id without corresponding allocation: {}", alloc_id); } @@ -225,6 +232,13 @@ pub fn specialized_decode_alloc_id< cache(decoder, pos, id); Ok(id) }, + EXTERN_STATIC_DISCRIMINANT => { + trace!("creating extern static alloc id at {}", pos); + let did = DefId::decode(decoder)?; + let alloc_id = tcx.interpret_interner.reserve(); + tcx.interpret_interner.cache(did, alloc_id); + Ok(alloc_id) + }, shorthand => { trace!("loading shorthand {}", shorthand); short(decoder, shorthand) diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index e56d8f8e818d..d636246b57f1 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -819,7 +819,7 @@ impl<'enc, 'a, 'tcx, E> SpecializedEncoder for CacheEncoder< // of the metadata file, because that would end up making our indices // not special. It is essentially impossible for that to happen, // but let's make sure - assert!(pos != interpret::ALLOC_DISCRIMINANT && pos != interpret::FN_DISCRIMINANT); + assert!(pos >= interpret::SHORTHAND_START); entry.insert(pos); None }, diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 0da23c2caf4a..6b3453f2c99e 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -203,9 +203,9 @@ impl<'a, 'tcx> SpecializedEncoder for EncodeContext<'a, 'tcx Entry::Occupied(entry) => Some(entry.get().clone()), Entry::Vacant(entry) => { // ensure that we don't place any AllocIds at the very beginning - // of the metadata file, because that would end up making our 0 and 1 indices + // of the metadata file, because that would end up making our indices // not special. This is essentially impossible, but let's make sure - assert!(pos != 0 && pos != 1); + assert!(pos >= interpret::SHORTHAND_START); entry.insert(pos); None }, diff --git a/src/test/incremental/extern_static/issue-49153.rs b/src/test/incremental/extern_static/issue-49153.rs new file mode 100644 index 000000000000..e0538e09c647 --- /dev/null +++ b/src/test/incremental/extern_static/issue-49153.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49153 + +// revisions:rpass1 rpass2 + +extern "C" { + pub static __ImageBase: u8; +} + +pub static FOO: &'static u8 = unsafe { &__ImageBase }; + +fn main() {} From eae6d512f0549307947e5fe1b8ee646916b82320 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 19:07:13 +0000 Subject: [PATCH 431/830] Add more canonicalisations for OS_TABLE and ARCH_TABLE --- src/tools/compiletest/src/util.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 8c889cc48070..b73f3e2f6495 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -14,21 +14,25 @@ use common::Config; /// Conversion table from triple OS name to Rust SYSNAME const OS_TABLE: &'static [(&'static str, &'static str)] = &[ ("android", "android"), + ("androideabi", "android"), ("bitrig", "bitrig"), ("cloudabi", "cloudabi"), ("darwin", "macos"), ("dragonfly", "dragonfly"), + ("emscripten", "emscripten"), ("freebsd", "freebsd"), + ("fuchsia", "fuchsia"), ("haiku", "haiku"), ("ios", "ios"), + ("l4re", "l4re"), ("linux", "linux"), ("mingw32", "windows"), ("netbsd", "netbsd"), ("openbsd", "openbsd"), + ("redox", "redox"), + ("solaris", "solaris"), ("win32", "windows"), ("windows", "windows"), - ("solaris", "solaris"), - ("emscripten", "emscripten"), ]; const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ @@ -36,21 +40,33 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("amd64", "x86_64"), ("arm", "arm"), ("arm64", "aarch64"), + ("armv4t", "arm"), + ("armv5te", "arm"), + ("armv7", "arm"), + ("armv7s", "arm"), + ("asmjs", "asmjs"), ("hexagon", "hexagon"), ("i386", "x86"), ("i586", "x86"), ("i686", "x86"), - ("mips64", "mips64"), ("mips", "mips"), + ("mips64", "mips64"), + ("mips64el", "mips64"), + ("mipsel", "mips"), ("msp430", "msp430"), ("powerpc", "powerpc"), ("powerpc64", "powerpc64"), + ("powerpc64le", "powerpc64"), ("s390x", "s390x"), ("sparc", "sparc"), + ("sparc64", "sparc64"), + ("sparcv9", "sparc64"), + ("thumbv6m", "thumb"), + ("thumbv7em", "thumb"), + ("thumbv7m", "thumb"), + ("wasm32", "wasm32"), ("x86_64", "x86_64"), ("xcore", "xcore"), - ("asmjs", "asmjs"), - ("wasm32", "wasm32"), ]; pub fn matches_os(triple: &str, name: &str) -> bool { From 1af952cc490b62a1f43f48c9fd809cf99aff2630 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Tue, 20 Mar 2018 07:31:22 -0400 Subject: [PATCH 432/830] Remove StdioRaw doc additions, add backticks --- src/libstd/io/stdio.rs | 9 --------- src/libstd/net/addr.rs | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 9a4cde7e1628..1f73054e3bee 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -30,27 +30,18 @@ thread_local! { /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdin_raw` function. -/// -/// The size of a StdinRaw struct may vary depending on the target operating -/// system. struct StdinRaw(stdio::Stdin); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stdout_raw` function. -/// -/// The size of a StdoutRaw struct may vary depending on the target operating -/// system. struct StdoutRaw(stdio::Stdout); /// A handle to a raw instance of the standard output stream of this process. /// /// This handle is not synchronized or buffered in any fashion. Constructed via /// the `std::io::stdio::stderr_raw` function. -/// -/// The size of a StderrRaw struct may vary depending on the target operating -/// system. struct StderrRaw(stdio::Stderr); /// Constructs a new raw handle to the standard input of this process. diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index f985c1f2bc8c..57efc3095fc9 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -28,7 +28,7 @@ use slice; /// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and /// [`SocketAddrV6`]'s respective documentation for more details. /// -/// The size of a SocketAddr instance may vary depending on the target operating +/// The size of a `SocketAddr` instance may vary depending on the target operating /// system. /// /// [IP address]: ../../std/net/enum.IpAddr.html From 61e1fbc659103513e68eae29ea830d798e2ec2d5 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 01:36:53 +0000 Subject: [PATCH 433/830] Make compiletest do exact matching on triples This avoids the issues of the previous substring matching, ensuring `ARCH_TABLE` and `OS_TABLE` will no longer contain redundant entries. --- src/tools/compiletest/src/util.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index b73f3e2f6495..c612f0117aaf 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -75,16 +75,18 @@ pub fn matches_os(triple: &str, name: &str) -> bool { if triple == "wasm32-unknown-unknown" { return name == "emscripten" || name == "wasm32-bare" } + let triple: Vec<_> = triple.split('-').collect(); for &(triple_os, os) in OS_TABLE { - if triple.contains(triple_os) { + if triple.contains(&triple_os) { return os == name; } } panic!("Cannot determine OS from triple"); } pub fn get_arch(triple: &str) -> &'static str { + let triple: Vec<_> = triple.split('-').collect(); for &(triple_arch, arch) in ARCH_TABLE { - if triple.contains(triple_arch) { + if triple.contains(&triple_arch) { return arch; } } From 8c8a72f8224b9cbf283cd120d87397c032ed62f1 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 20 Mar 2018 21:15:21 +0900 Subject: [PATCH 434/830] Reinit the stack guard on unexpected failure --- src/librustc_driver/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e39a2c2f5dcd..e56c9928dccd 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -1480,9 +1480,9 @@ pub fn in_rustc_thread(f: F) -> Result> rlim.rlim_cur = STACK_SIZE as libc::rlim_t; if libc::setrlimit(libc::RLIMIT_STACK, &mut rlim) != 0 { let err = io::Error::last_os_error(); - // We have already deinited the stack. Further corruption is - // not allowed. - panic!("in_rustc_thread: error calling setrlimit: {}", err); + error!("in_rustc_thread: error calling setrlimit: {}", err); + std::rt::update_stack_guard(); + true } else { std::rt::update_stack_guard(); false From 8d9774713df3b5d0b3a1bdbb4ecd55658d401d75 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 19 Mar 2018 21:57:41 +0300 Subject: [PATCH 435/830] Update Cargo to fix regression This should fix regressions in Cargo after swithing to clap: * If an external subcommand name was close to built-in one, clap errored (fixed by updating clap version) * External subcomands didn't received their name as a first arg --- src/Cargo.lock | 14 +++++++------- src/tools/cargo | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 26508dec4bba..675457905ead 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -184,7 +184,7 @@ version = "0.27.0" dependencies = [ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "crates-io 0.16.0", "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -273,7 +273,7 @@ dependencies = [ [[package]] name = "clap" -version = "2.31.1" +version = "2.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -840,7 +840,7 @@ version = "0.1.0" name = "installer" version = "0.0.0" dependencies = [ - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1033,7 +1033,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1322,7 +1322,7 @@ name = "racer" version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1533,7 +1533,7 @@ dependencies = [ name = "rustbook" version = "0.1.0" dependencies = [ - "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2699,7 +2699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc18f6f4005132120d9711636b32c46a233fad94df6217fa1d81c5e97a9f200" +"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" diff --git a/src/tools/cargo b/src/tools/cargo index d6c3983fe3bd..d10ec661b064 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d6c3983fe3bd8fa06b54712e53fb23645598188b +Subproject commit d10ec661b06420654bbc4ed0ccd32295698aa1dc From 2928c7a8a253b655132ac9f2beb4ca74540f0e14 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 20 Mar 2018 21:22:45 +0900 Subject: [PATCH 436/830] Refactor the stack addr aligning code into a function --- src/libstd/sys/unix/thread.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index d94e11a5207c..4364089a1818 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -284,10 +284,10 @@ pub mod guard { ret } - pub unsafe fn init() -> Option { - PAGE_SIZE = os::page_size(); - - let mut stackaddr = get_stack_start()?; + // Precondition: PAGE_SIZE is initialized. + unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { + assert!(PAGE_SIZE != 0); + let stackaddr = get_stack_start()?; // Ensure stackaddr is page aligned! A parent process might // have reset RLIMIT_STACK to be non-page aligned. The @@ -296,10 +296,17 @@ pub mod guard { // page-aligned, calculate the fix such that stackaddr < // new_page_aligned_stackaddr < stackaddr + stacksize let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } + Some(if remainder == 0 { + stackaddr + } else { + ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void + }) + } + + pub unsafe fn init() -> Option { + PAGE_SIZE = os::page_size(); + + let stackaddr = get_stack_start_aligned()?; if cfg!(target_os = "linux") { // Linux doesn't allocate the whole stack right away, and @@ -338,14 +345,7 @@ pub mod guard { pub unsafe fn deinit() { if !cfg!(target_os = "linux") { - if let Some(mut stackaddr) = get_stack_start() { - // Ensure address is aligned. Same as above. - let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } - + if let Some(stackaddr) = get_stack_start_aligned() { // Undo the guard page mapping. if munmap(stackaddr, PAGE_SIZE) != 0 { panic!("unable to deallocate the guard page"); From 1b5eb17d61f1651d6b9d412a5be586dfb80fd447 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 16 Mar 2018 12:10:47 -0700 Subject: [PATCH 437/830] ci: Print out how long each step takes on CI This commit updates CI configuration to inform rustbuild that it should print out how long each step takes on CI. This'll hopefully allow us to track the duration of steps over time and follow regressions a bit more closesly (as well as have closer analysis of differences between two builds). cc #48829 --- config.toml.example | 4 +++ src/bootstrap/bin/rustc.rs | 65 ++++++++++++++++++++++++++------------ src/bootstrap/builder.rs | 29 +++++++++++++++-- src/bootstrap/config.rs | 3 ++ src/ci/run.sh | 2 ++ 5 files changed, 81 insertions(+), 22 deletions(-) diff --git a/config.toml.example b/config.toml.example index aec5e5a0e2c8..e92807d5aaaa 100644 --- a/config.toml.example +++ b/config.toml.example @@ -186,6 +186,10 @@ # essentially skipping stage0 as the local compiler is recompiling itself again. #local-rebuild = false +# Print out how long each rustbuild step took (mostly intended for CI and +# tracking over time) +#print-step-timings = false + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 4be16475590f..6701f58ba8e9 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -31,9 +31,11 @@ extern crate bootstrap; use std::env; use std::ffi::OsString; -use std::str::FromStr; +use std::io; use std::path::PathBuf; -use std::process::{Command, ExitStatus}; +use std::process::Command; +use std::str::FromStr; +use std::time::Instant; fn main() { let mut args = env::args_os().skip(1).collect::>(); @@ -90,7 +92,7 @@ fn main() { }; let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); - let mut on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of)); + let on_fail = env::var_os("RUSTC_ON_FAIL").map(|of| Command::new(of)); let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); @@ -103,6 +105,7 @@ fn main() { .arg(format!("stage{}", stage)) .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); + let mut maybe_crate = None; if let Some(target) = target { // The stage0 compiler has a special sysroot distinct from what we @@ -134,6 +137,7 @@ fn main() { .find(|a| &*a[0] == "--crate-name") .unwrap(); let crate_name = &*crate_name[1]; + maybe_crate = Some(crate_name); // If we're compiling specifically the `panic_abort` crate then we pass // the `-C panic=abort` option. Note that we do not do this for any @@ -281,31 +285,52 @@ fn main() { eprintln!("libdir: {:?}", libdir); } - // Actually run the compiler! - std::process::exit(if let Some(ref mut on_fail) = on_fail { - match cmd.status() { - Ok(s) if s.success() => 0, - _ => { - println!("\nDid not run successfully:\n{:?}\n-------------", cmd); - exec_cmd(on_fail).expect("could not run the backup command"); - 1 + if let Some(mut on_fail) = on_fail { + let e = match cmd.status() { + Ok(s) if s.success() => std::process::exit(0), + e => e, + }; + println!("\nDid not run successfully: {:?}\n{:?}\n-------------", e, cmd); + exec_cmd(&mut on_fail).expect("could not run the backup command"); + std::process::exit(1); + } + + if env::var_os("RUSTC_PRINT_STEP_TIMINGS").is_some() { + if let Some(krate) = maybe_crate { + let start = Instant::now(); + let status = cmd + .status() + .expect(&format!("\n\n failed to run {:?}", cmd)); + let dur = start.elapsed(); + + let is_test = args.iter().any(|a| a == "--test"); + eprintln!("[RUSTC-TIMING] {} test:{} {}.{:03}", + krate.to_string_lossy(), + is_test, + dur.as_secs(), + dur.subsec_nanos() / 1_000_000); + + match status.code() { + Some(i) => std::process::exit(i), + None => { + eprintln!("rustc exited with {}", status); + std::process::exit(0xfe); + } } } - } else { - std::process::exit(match exec_cmd(&mut cmd) { - Ok(s) => s.code().unwrap_or(0xfe), - Err(e) => panic!("\n\nfailed to run {:?}: {}\n\n", cmd, e), - }) - }) + } + + let code = exec_cmd(&mut cmd).expect(&format!("\n\n failed to run {:?}", cmd)); + std::process::exit(code); } #[cfg(unix)] -fn exec_cmd(cmd: &mut Command) -> ::std::io::Result { +fn exec_cmd(cmd: &mut Command) -> io::Result { use std::os::unix::process::CommandExt; Err(cmd.exec()) } #[cfg(not(unix))] -fn exec_cmd(cmd: &mut Command) -> ::std::io::Result { - cmd.status() +fn exec_cmd(cmd: &mut Command) -> io::Result { + cmd.status().map(|status| status.code().unwrap()) } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437ee..3fd50f17ef3e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -9,7 +9,7 @@ // except according to those terms. use std::any::Any; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; use std::env; use std::fmt::Debug; @@ -18,6 +18,7 @@ use std::hash::Hash; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::process::Command; +use std::time::{Instant, Duration}; use compile; use install; @@ -40,6 +41,7 @@ pub struct Builder<'a> { pub kind: Kind, cache: Cache, stack: RefCell>>, + time_spent_on_dependencies: Cell, } impl<'a> Deref for Builder<'a> { @@ -343,6 +345,7 @@ impl<'a> Builder<'a> { kind, cache: Cache::new(), stack: RefCell::new(Vec::new()), + time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), }; let builder = &builder; @@ -383,6 +386,7 @@ impl<'a> Builder<'a> { kind, cache: Cache::new(), stack: RefCell::new(Vec::new()), + time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), }; if kind == Kind::Dist { @@ -662,6 +666,10 @@ impl<'a> Builder<'a> { cargo.env("RUSTC_ON_FAIL", on_fail); } + if self.config.print_step_timings { + cargo.env("RUSTC_PRINT_STEP_TIMINGS", "1"); + } + cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity)); // Throughout the build Cargo can execute a number of build scripts @@ -818,7 +826,24 @@ impl<'a> Builder<'a> { self.build.verbose(&format!("{}> {:?}", " ".repeat(stack.len()), step)); stack.push(Box::new(step.clone())); } - let out = step.clone().run(self); + + let (out, dur) = { + let start = Instant::now(); + let zero = Duration::new(0, 0); + let parent = self.time_spent_on_dependencies.replace(zero); + let out = step.clone().run(self); + let dur = start.elapsed(); + let deps = self.time_spent_on_dependencies.replace(parent + dur); + (out, dur - deps) + }; + + if self.build.config.print_step_timings && dur > Duration::from_millis(100) { + println!("[TIMING] {:?} -- {}.{:03}", + step, + dur.as_secs(), + dur.subsec_nanos() / 1_000_000); + } + { let mut stack = self.stack.borrow_mut(); let cur_step = stack.pop().expect("step stack empty"); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 920a8ffc2fc8..3ef4b0f8ae7a 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -121,6 +121,7 @@ pub struct Config { pub quiet_tests: bool, pub test_miri: bool, pub save_toolstates: Option, + pub print_step_timings: bool, // Fallback musl-root for all targets pub musl_root: Option, @@ -204,6 +205,7 @@ struct Build { openssl_static: Option, configure_args: Option>, local_rebuild: Option, + print_step_timings: Option, } /// TOML representation of various global install decisions. @@ -413,6 +415,7 @@ impl Config { set(&mut config.openssl_static, build.openssl_static); set(&mut config.configure_args, build.configure_args); set(&mut config.local_rebuild, build.local_rebuild); + set(&mut config.print_step_timings, build.print_step_timings); config.verbose = cmp::max(config.verbose, flags.verbose); if let Some(ref install) = toml.install { diff --git a/src/ci/run.sh b/src/ci/run.sh index e3f38e4834a9..9a26043c92c1 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -25,6 +25,8 @@ source "$ci_dir/shared.sh" if [ "$TRAVIS" == "true" ] && [ "$TRAVIS_BRANCH" != "auto" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-quiet-tests" +else + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.print-step-timings" fi RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-sccache" From 859640a3ca99490ea7415449d84ccf87ee7c439c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 20 Mar 2018 15:33:22 +0100 Subject: [PATCH 438/830] Run the `run-make` tests last, so more tests run on Windows when `make` is unavailable --- src/bootstrap/builder.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437ee..07026cbe2650 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -308,12 +308,14 @@ impl<'a> Builder<'a> { test::UiFullDeps, test::RunPassFullDeps, test::RunFailFullDeps, test::CompileFailFullDeps, test::IncrementalFullDeps, test::Rustdoc, test::Pretty, test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty, - test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake, + test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::Crate, test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck, test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample, test::TheBook, test::UnstableBook, - test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme), + test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme, + // Run run-make last, since these won't pass without make on Windows + test::RunMake), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, From de9e6652480ad3de5f6dc52348f8e51865d7cf69 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Mar 2018 15:11:26 +0000 Subject: [PATCH 439/830] Improve comments for Rule Implemented-From-Impl --- src/librustc_traits/lowering.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index c9666f55d440..a69f9988f371 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -118,15 +118,24 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId return Lrc::new(vec![]); } - // Rule Implemented-From-Impl + // Rule Implemented-From-Impl (see rustc guide) // - // (see rustc guide) + // `impl Trait for A0 where WC { .. }` + // + // ``` + // forall { + // Implemented(A0: Trait) :- WC + // } + // ``` let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); - let trait_ref = ty::TraitPredicate { trait_ref }.lower(); + // `Implemented(A0: Trait)` + let trait_pred = ty::TraitPredicate { trait_ref }.lower(); + // `WC` let where_clauses = tcx.predicates_of(def_id).predicates.lower(); - let clause = Clause::Implies(where_clauses, trait_ref); + // `Implemented(A0: Trait) :- WC` + let clause = Clause::Implies(where_clauses, trait_pred); Lrc::new(vec![clause]) } From b8c75d98f9c3fe01b23f50c42b36b491e256c7a1 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Mar 2018 15:13:44 +0000 Subject: [PATCH 440/830] Implement Rule Implemented-From-Env This extends the Chalk lowering pass with the "Implemented-From-Env" rule for generating program clauses from a trait definition as part of #49177. --- src/librustc_traits/lowering.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index a69f9988f371..1092e826a35f 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -12,6 +12,7 @@ use rustc::hir::{self, ImplPolarity}; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::ty::{self, TyCtxt}; +use rustc::ty::subst::Substs; use rustc::traits::{QuantifierKind, Goal, DomainGoal, Clause, WhereClauseAtom}; use syntax::ast; use rustc_data_structures::sync::Lrc; @@ -104,6 +105,7 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let item = tcx.hir.expect_item(node_id); match item.node { + hir::ItemTrait(..) => program_clauses_for_trait(tcx, def_id), hir::ItemImpl(..) => program_clauses_for_impl(tcx, def_id), // FIXME: other constructions e.g. traits, associated types... @@ -111,6 +113,36 @@ crate fn program_clauses_for<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefI } } +fn program_clauses_for_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) + -> Lrc>> +{ + // Rule Implemented-From-Env (see rustc guide) + // + // `trait Trait where WC { .. } // P0 == Self` + // + // ``` + // forall { + // Implemented(Self: Trait) :- FromEnv(Self: Trait) + // } + // ``` + + // `Self: Trait` + let trait_pred = ty::TraitPredicate { + trait_ref: ty::TraitRef { + def_id, + substs: Substs::identity_for_item(tcx, def_id) + } + }; + // `FromEnv(Self: Trait)` + let from_env = Goal::DomainGoal(DomainGoal::FromEnv(trait_pred.lower())); + // `Implemented(Self: Trait)` + let impl_trait = DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred)); + + // `Implemented(Self: Trait) :- FromEnv(Self: Trait)` + let clause = Clause::Implies(vec![from_env], impl_trait); + Lrc::new(vec![clause]) +} + fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Lrc>> { From 7791995ad5200b65cd9c8391703a76a18f492664 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Mar 2018 15:23:54 +0000 Subject: [PATCH 441/830] Add unit test for Implemented-From-Env --- src/test/ui/chalkify/lower_trait.rs | 22 ++++++++++++++++++++++ src/test/ui/chalkify/lower_trait.stderr | 8 ++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/test/ui/chalkify/lower_trait.rs create mode 100644 src/test/ui/chalkify/lower_trait.stderr diff --git a/src/test/ui/chalkify/lower_trait.rs b/src/test/ui/chalkify/lower_trait.rs new file mode 100644 index 000000000000..010cb77edc3f --- /dev/null +++ b/src/test/ui/chalkify/lower_trait.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_attrs)] + +#[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo) :- +trait Foo { + fn s(S) -> S; + fn t(T) -> T; + fn u(U) -> U; +} + +fn main() { + println!("hello"); +} diff --git a/src/test/ui/chalkify/lower_trait.stderr b/src/test/ui/chalkify/lower_trait.stderr new file mode 100644 index 000000000000..6da1e2fd8edd --- /dev/null +++ b/src/test/ui/chalkify/lower_trait.stderr @@ -0,0 +1,8 @@ +error: Implemented(Self: Foo) :- FromEnv(Self: Foo). + --> $DIR/lower_trait.rs:13:1 + | +LL | #[rustc_dump_program_clauses] //~ ERROR Implemented(Self: Foo) :- + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From df76629da77b58cd9a63d41b7bc1cc987dcc2bb8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 20 Mar 2018 17:14:33 +0100 Subject: [PATCH 442/830] Remove outdated comment --- src/librustc/ty/sty.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index bb5c7b5fd2a5..3fe310c54bfe 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1667,7 +1667,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub struct Const<'tcx> { pub ty: Ty<'tcx>, - // FIXME(eddyb) Replace this with a miri value. pub val: ConstVal<'tcx>, } From 5e93394d321823ec2f54e130150791ab95b6f755 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 20 Mar 2018 11:18:42 -0500 Subject: [PATCH 443/830] talk about --display-warnings --- src/doc/rustdoc/src/unstable-features.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 93489f89626f..6a786c198514 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -329,3 +329,19 @@ When rendering docs, `rustdoc` creates several CSS and JavaScript files as part all these files are linked from every page, changing where they are can be cumbersome if you need to specially cache them. This flag will rename all these files in the output to include the suffix in the filename. For example, `main.css` would become `main-suf.css` with the above command. + +### `--display-warnings`: display warnings when documenting or running documentation tests + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --display-warnings +$ rustdoc --test src/lib.rs -Z unstable-options --display-warnings +``` + +The intent behind this flag is to allow the user to see warnings that occur within their library or +their documentation tests, which are usually suppressed. However, [due to a +bug][issue-display-warnings], this flag doesn't 100% work as intended. See the linked issue for +details. + +[issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574 From 83e9f395d17afc95d259febe8d675084f1baf497 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 20 Mar 2018 11:23:48 -0500 Subject: [PATCH 444/830] talk about force-unstable-if-unmarked --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 6a786c198514..ac69cc1007d8 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -345,3 +345,16 @@ bug][issue-display-warnings], this flag doesn't 100% work as intended. See the l details. [issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574 + +### `-Z force-unstable-if-unmarked` + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z force-unstable-if-unmarked +``` + +This is an internal flag intended for the standard library and compiler that applies an +`#[unstable]` attribute to any dependent crate that doesn't have another stability attribute. This +allows `rustdoc` to be able to generate documentation for the compiler crates and the standard +library, as an equivalent command-line argument is provided to `rustc` when building those crates. From 3c8d55549728ec117fb6e3de93ce3d96fb6622d4 Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Wed, 14 Mar 2018 20:30:06 -0700 Subject: [PATCH 445/830] rename epoch to edition --- src/librustc/lint/context.rs | 12 ++--- src/librustc/lint/mod.rs | 20 ++++----- src/librustc/session/config.rs | 24 +++++----- src/librustc/session/mod.rs | 10 ++--- src/librustc_driver/driver.rs | 2 +- src/librustc_lint/lib.rs | 34 +++++++------- src/librustc_typeck/check/method/probe.rs | 2 +- src/libsyntax/config.rs | 6 +-- src/libsyntax/{epoch.rs => edition.rs} | 44 +++++++++---------- src/libsyntax/feature_gate.rs | 20 ++++----- src/libsyntax/lib.rs | 2 +- ....rs => edition-raw-pointer-method-2015.rs} | 4 +- ....rs => edition-raw-pointer-method-2018.rs} | 4 +- src/test/run-pass/dyn-trait.rs | 2 +- src/test/run-pass/epoch-gate-feature.rs | 2 +- ...ference-variable-behind-raw-pointer.stderr | 2 +- 16 files changed, 95 insertions(+), 95 deletions(-) rename src/libsyntax/{epoch.rs => edition.rs} (56%) rename src/test/compile-fail/{epoch-raw-pointer-method-2015.rs => edition-raw-pointer-method-2015.rs} (85%) rename src/test/compile-fail/{epoch-raw-pointer-method-2018.rs => edition-raw-pointer-method-2018.rs} (85%) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4fa6594df169..936aa71f16ce 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -41,7 +41,7 @@ use util::nodemap::FxHashMap; use std::default::Default as StdDefault; use std::cell::{Ref, RefCell}; use syntax::ast; -use syntax::epoch; +use syntax::edition; use syntax_pos::{MultiSpan, Span}; use errors::DiagnosticBuilder; use hir; @@ -103,9 +103,9 @@ pub struct FutureIncompatibleInfo { pub id: LintId, /// e.g., a URL for an issue/PR/RFC or error code pub reference: &'static str, - /// If this is an epoch fixing lint, the epoch in which + /// If this is an edition fixing lint, the edition in which /// this lint becomes obsolete - pub epoch: Option, + pub edition: Option, } /// The target of the `by_name` map, which accounts for renaming/deprecation. @@ -201,11 +201,11 @@ impl LintStore { sess: Option<&Session>, lints: Vec) { - for epoch in epoch::ALL_EPOCHS { - let lints = lints.iter().filter(|f| f.epoch == Some(*epoch)).map(|f| f.id) + for edition in edition::ALL_EPOCHS { + let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { - self.register_group(sess, false, epoch.lint_name(), lints) + self.register_group(sess, false, edition.lint_name(), lints) } } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 7c103dc27210..cd038d067a1f 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -42,7 +42,7 @@ use session::{Session, DiagnosticMessageId}; use std::hash; use syntax::ast; use syntax::codemap::MultiSpan; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::symbol::Symbol; use syntax::visit as ast_visit; use syntax_pos::Span; @@ -77,8 +77,8 @@ pub struct Lint { /// e.g. "imports that are never used" pub desc: &'static str, - /// Deny lint after this epoch - pub epoch_deny: Option, + /// Deny lint after this edition + pub edition_deny: Option, } impl Lint { @@ -88,8 +88,8 @@ impl Lint { } pub fn default_level(&self, session: &Session) -> Level { - if let Some(epoch_deny) = self.epoch_deny { - if session.epoch() >= epoch_deny { + if let Some(edition_deny) = self.edition_deny { + if session.edition() >= edition_deny { return Level::Deny } } @@ -100,12 +100,12 @@ impl Lint { /// Declare a static item of type `&'static Lint`. #[macro_export] macro_rules! declare_lint { - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $epoch: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $edition: expr) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - epoch_deny: Some($epoch) + edition_deny: Some($edition) }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( @@ -113,7 +113,7 @@ macro_rules! declare_lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, - epoch_deny: None, + edition_deny: None, }; ); } @@ -499,8 +499,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session, // Check for future incompatibility lints and issue a stronger warning. let lints = sess.lint_store.borrow(); if let Some(future_incompatible) = lints.future_incompatible(LintId::of(lint)) { - let future = if let Some(epoch) = future_incompatible.epoch { - format!("the {} epoch", epoch) + let future = if let Some(edition) = future_incompatible.edition { + format!("the {} edition", edition) } else { "a future release".to_owned() }; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 0d91074e946b..4ba634f8b25c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -28,7 +28,7 @@ use middle::cstore; use syntax::ast::{self, IntTy, UintTy}; use syntax::codemap::{FileName, FilePathMapping}; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::parse::token; use syntax::parse; use syntax::symbol::Symbol; @@ -771,7 +771,7 @@ macro_rules! options { Some("`string` or `string=string`"); pub const parse_lto: Option<&'static str> = Some("one of `thin`, `fat`, or omitted"); - pub const parse_epoch: Option<&'static str> = + pub const parse_edition: Option<&'static str> = Some("one of: `2015`, `2018`"); } @@ -780,7 +780,7 @@ macro_rules! options { use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto}; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; use std::path::PathBuf; - use syntax::epoch::Epoch; + use syntax::edition::Edition; $( pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool { @@ -983,11 +983,11 @@ macro_rules! options { true } - fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool { + fn parse_edition(slot: &mut Edition, v: Option<&str>) -> bool { match v { Some(s) => { - let epoch = s.parse(); - if let Ok(parsed) = epoch { + let edition = s.parse(); + if let Ok(parsed) = edition { *slot = parsed; true } else { @@ -1280,10 +1280,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, `everybody_loops` (all function bodies replaced with `loop {}`), `hir` (the HIR), `hir,identified`, or `hir,typed` (HIR with types for each node)."), - epoch: Epoch = (Epoch::Epoch2015, parse_epoch, [TRACKED], - "The epoch to build Rust with. Newer epochs may include features - that require breaking changes. The default epoch is 2015 (the first - epoch). Crates compiled with different epochs can be linked together."), + edition: Edition = (Edition::Edition2015, parse_edition, [TRACKED], + "The edition to build Rust with. Newer editions may include features + that require breaking changes. The default edition is 2015 (the first + edition). Crates compiled with different editions can be linked together."), run_dsymutil: Option = (None, parse_opt_bool, [TRACKED], "run `dsymutil` and delete intermediate object files"), ui_testing: bool = (false, parse_bool, [UNTRACKED], @@ -2258,7 +2258,7 @@ mod dep_tracking { use std::hash::Hash; use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; - use super::{CrateType, DebugInfoLevel, Epoch, ErrorOutputType, Lto, OptLevel, OutputTypes, + use super::{CrateType, DebugInfoLevel, Edition, ErrorOutputType, Lto, OptLevel, OutputTypes, Passes, Sanitizer}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2320,7 +2320,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind); impl_dep_tracking_hash_via_hash!(Sanitizer); impl_dep_tracking_hash_via_hash!(Option); - impl_dep_tracking_hash_via_hash!(Epoch); + impl_dep_tracking_hash_via_hash!(Edition); impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 3f52ecfc0999..556255e06ed0 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -31,7 +31,7 @@ use rustc_data_structures::sync::{Lrc, Lock}; use syntax::ast::NodeId; use errors::{self, DiagnosticBuilder, DiagnosticId}; use errors::emitter::{Emitter, EmitterWriter}; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use syntax::json::JsonEmitter; use syntax::feature_gate; use syntax::symbol::Symbol; @@ -976,13 +976,13 @@ impl Session { self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code) } - /// Are we allowed to use features from the Rust 2018 epoch? + /// Are we allowed to use features from the Rust 2018 edition? pub fn rust_2018(&self) -> bool { - self.opts.debugging_opts.epoch >= Epoch::Epoch2018 + self.opts.debugging_opts.edition >= Edition::Edition2018 } - pub fn epoch(&self) -> Epoch { - self.opts.debugging_opts.epoch + pub fn edition(&self) -> Edition { + self.opts.debugging_opts.edition } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f2fe6542db17..a3115544f30b 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -648,7 +648,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, { let (mut krate, features) = syntax::config::features(krate, &sess.parse_sess, sess.opts.test, - sess.opts.debugging_opts.epoch); + sess.opts.debugging_opts.edition); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index ce896bfb701b..59d2d3e8fdc0 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -48,7 +48,7 @@ use rustc::session; use rustc::util; use session::Session; -use syntax::epoch::Epoch; +use syntax::edition::Edition; use lint::LintId; use lint::FutureIncompatibleInfo; @@ -197,82 +197,82 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { FutureIncompatibleInfo { id: LintId::of(PRIVATE_IN_PUBLIC), reference: "issue #34537 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), reference: "issue #34537 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), reference: "issue #35203 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(SAFE_EXTERN_STATICS), reference: "issue #36247 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), reference: "issue #36887 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP), reference: "issue #37872 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_IMPORTS), reference: "issue #38260 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY), reference: "issue #39207 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(MISSING_FRAGMENT_SPECIFIER), reference: "issue #40107 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), reference: "issue #41620 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(ANONYMOUS_PARAMETERS), reference: "issue #41686 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), reference: "issue #42238 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS), reference: "issue #42868 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(SAFE_PACKED_BORROWS), reference: "issue #46043 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(INCOHERENT_FUNDAMENTAL_IMPLS), reference: "issue #46205 ", - epoch: None, + edition: None, }, FutureIncompatibleInfo { id: LintId::of(TYVAR_BEHIND_RAW_POINTER), reference: "issue #46906 ", - epoch: Some(Epoch::Epoch2018), + edition: Some(Edition::Edition2018), } ]); diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 4d344eb27990..c7921d2bd458 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -326,7 +326,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if reached_raw_pointer && !self.tcx.features().arbitrary_self_types { // this case used to be allowed by the compiler, - // so we do a future-compat lint here for the 2015 epoch + // so we do a future-compat lint here for the 2015 edition // (see https://github.com/rust-lang/rust/issues/46906) if self.tcx.sess.rust_2018() { span_err!(self.tcx.sess, span, E0908, diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 6013c20daf23..56b1306e5b33 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -13,7 +13,7 @@ use feature_gate::{feature_err, EXPLAIN_STMT_ATTR_SYNTAX, Features, get_features use {fold, attr}; use ast; use codemap::Spanned; -use epoch::Epoch; +use edition::Edition; use parse::{token, ParseSess}; use ptr::P; @@ -27,7 +27,7 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoch: Epoch) +pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, edition: Edition) -> (ast::Crate, Features) { let features; { @@ -47,7 +47,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool, epoc return (krate, Features::new()); } - features = get_features(&sess.span_diagnostic, &krate.attrs, epoch); + features = get_features(&sess.span_diagnostic, &krate.attrs, edition); // Avoid reconfiguring malformed `cfg_attr`s if err_count == sess.span_diagnostic.err_count() { diff --git a/src/libsyntax/epoch.rs b/src/libsyntax/edition.rs similarity index 56% rename from src/libsyntax/epoch.rs rename to src/libsyntax/edition.rs index 32cbc79c550e..12ac6410ce19 100644 --- a/src/libsyntax/epoch.rs +++ b/src/libsyntax/edition.rs @@ -11,58 +11,58 @@ use std::fmt; use std::str::FromStr; -/// The epoch of the compiler (RFC 2052) +/// The edition of the compiler (RFC 2052) #[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)] #[non_exhaustive] -pub enum Epoch { - // epochs must be kept in order, newest to oldest +pub enum Edition { + // editions must be kept in order, newest to oldest - /// The 2015 epoch - Epoch2015, - /// The 2018 epoch - Epoch2018, + /// The 2015 edition + Edition2015, + /// The 2018 edition + Edition2018, - // when adding new epochs, be sure to update: + // when adding new editions, be sure to update: // - // - the list in the `parse_epoch` static in librustc::session::config + // - the list in the `parse_edition` static in librustc::session::config // - add a `rust_####()` function to the session // - update the enum in Cargo's sources as well // - // When -Zepoch becomes --epoch, there will - // also be a check for the epoch being nightly-only + // When -Zedition becomes --edition, there will + // also be a check for the edition being nightly-only // somewhere. That will need to be updated - // whenever we're stabilizing/introducing a new epoch + // whenever we're stabilizing/introducing a new edition // as well as changing the default Cargo template. } // must be in order from oldest to newest -pub const ALL_EPOCHS: &[Epoch] = &[Epoch::Epoch2015, Epoch::Epoch2018]; +pub const ALL_EPOCHS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; -impl fmt::Display for Epoch { +impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let s = match *self { - Epoch::Epoch2015 => "2015", - Epoch::Epoch2018 => "2018", + Edition::Edition2015 => "2015", + Edition::Edition2018 => "2018", }; write!(f, "{}", s) } } -impl Epoch { +impl Edition { pub fn lint_name(&self) -> &'static str { match *self { - Epoch::Epoch2015 => "epoch_2015", - Epoch::Epoch2018 => "epoch_2018", + Edition::Edition2015 => "edition_2015", + Edition::Edition2018 => "edition_2018", } } } -impl FromStr for Epoch { +impl FromStr for Edition { type Err = (); fn from_str(s: &str) -> Result { match s { - "2015" => Ok(Epoch::Epoch2015), - "2018" => Ok(Epoch::Epoch2018), + "2015" => Ok(Edition::Edition2015), + "2018" => Ok(Edition::Edition2018), _ => Err(()) } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 915396d29fe2..8feb8d6a4020 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -28,7 +28,7 @@ use self::AttributeGate::*; use abi::Abi; use ast::{self, NodeId, PatKind, RangeEnd}; use attr; -use epoch::Epoch; +use edition::Edition; use codemap::Spanned; use syntax_pos::{Span, DUMMY_SP}; use errors::{DiagnosticBuilder, Handler, FatalError}; @@ -55,13 +55,13 @@ macro_rules! set { } macro_rules! declare_features { - ($((active, $feature: ident, $ver: expr, $issue: expr, $epoch: expr),)+) => { + ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => { /// Represents active features that are currently being implemented or /// currently being considered for addition/removal. const ACTIVE_FEATURES: &'static [(&'static str, &'static str, Option, - Option, fn(&mut Features, Span))] = - &[$((stringify!($feature), $ver, $issue, $epoch, set!($feature))),+]; + Option, fn(&mut Features, Span))] = + &[$((stringify!($feature), $ver, $issue, $edition, set!($feature))),+]; /// A set of features to be used by later passes. #[derive(Clone)] @@ -402,7 +402,7 @@ declare_features! ( (active, match_default_bindings, "1.22.0", Some(42640), None), // Trait object syntax with `dyn` prefix - (active, dyn_trait, "1.22.0", Some(44662), Some(Epoch::Epoch2018)), + (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), // `crate` as visibility modifier, synonymous to `pub(crate)` (active, crate_visibility_modifier, "1.23.0", Some(45388), None), @@ -1800,16 +1800,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - epoch: Epoch) -> Features { + edition: Edition) -> Features { let mut features = Features::new(); let mut feature_checker = FeatureChecker::default(); - for &(.., f_epoch, set) in ACTIVE_FEATURES.iter() { - if let Some(f_epoch) = f_epoch { - if epoch >= f_epoch { + for &(.., f_edition, set) in ACTIVE_FEATURES.iter() { + if let Some(f_edition) = f_edition { + if edition >= f_edition { // FIXME(Manishearth) there is currently no way to set - // lang features by epoch + // lang features by edition set(&mut features, DUMMY_SP); } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 5f58b3bc3a05..74f1ee373ec6 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -145,7 +145,7 @@ pub mod codemap; #[macro_use] pub mod config; pub mod entry; -pub mod epoch; +pub mod edition; pub mod feature_gate; pub mod fold; pub mod parse; diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs b/src/test/compile-fail/edition-raw-pointer-method-2015.rs similarity index 85% rename from src/test/compile-fail/epoch-raw-pointer-method-2015.rs rename to src/test/compile-fail/edition-raw-pointer-method-2015.rs index 6aa83a38b7ee..fdc9b4f704cd 100644 --- a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2015.rs @@ -9,9 +9,9 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zepoch=2015 -Zunstable-options +// compile-flags: -Zedition=2015 -Zunstable-options -// tests that epochs work with the tyvar warning-turned-error +// tests that editions work with the tyvar warning-turned-error #[deny(warnings)] fn main() { diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs b/src/test/compile-fail/edition-raw-pointer-method-2018.rs similarity index 85% rename from src/test/compile-fail/epoch-raw-pointer-method-2018.rs rename to src/test/compile-fail/edition-raw-pointer-method-2018.rs index c4815de2306e..58b34591029b 100644 --- a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs +++ b/src/test/compile-fail/edition-raw-pointer-method-2018.rs @@ -9,9 +9,9 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags: -Zepoch=2018 -Zunstable-options +// compile-flags: -Zedition=2018 -Zunstable-options -// tests that epochs work with the tyvar warning-turned-error +// tests that editions work with the tyvar warning-turned-error #[deny(warnings)] fn main() { diff --git a/src/test/run-pass/dyn-trait.rs b/src/test/run-pass/dyn-trait.rs index fdec6a26ac94..399823ec92d0 100644 --- a/src/test/run-pass/dyn-trait.rs +++ b/src/test/run-pass/dyn-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty `dyn ::foo` parses differently in the current epoch +// ignore-pretty `dyn ::foo` parses differently in the current edition #![feature(dyn_trait)] diff --git a/src/test/run-pass/epoch-gate-feature.rs b/src/test/run-pass/epoch-gate-feature.rs index 37d092c06e02..f3d8f216e113 100644 --- a/src/test/run-pass/epoch-gate-feature.rs +++ b/src/test/run-pass/epoch-gate-feature.rs @@ -11,7 +11,7 @@ // Checks if the correct registers are being used to pass arguments // when the sysv64 ABI is specified. -// compile-flags: -Zepoch=2018 +// compile-flags: -Zedition=2018 pub trait Foo {} diff --git a/src/test/ui/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference-variable-behind-raw-pointer.stderr index eb40151615da..fe6dc0b07482 100644 --- a/src/test/ui/inference-variable-behind-raw-pointer.stderr +++ b/src/test/ui/inference-variable-behind-raw-pointer.stderr @@ -5,6 +5,6 @@ LL | if data.is_null() {} | ^^^^^^^ | = note: #[warn(tyvar_behind_raw_pointer)] on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 epoch! + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #46906 From 11f14060a4da7776c5f56e7dc53cc9545e4ab25f Mon Sep 17 00:00:00 2001 From: Kurtis Nusbaum Date: Wed, 14 Mar 2018 20:56:13 -0700 Subject: [PATCH 446/830] change all appropriate EPOCH to EDITION --- src/librustc/lint/context.rs | 2 +- src/libsyntax/edition.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 936aa71f16ce..3c833251f72a 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -201,7 +201,7 @@ impl LintStore { sess: Option<&Session>, lints: Vec) { - for edition in edition::ALL_EPOCHS { + for edition in edition::ALL_EDITIONS { let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { diff --git a/src/libsyntax/edition.rs b/src/libsyntax/edition.rs index 12ac6410ce19..61246d4493ca 100644 --- a/src/libsyntax/edition.rs +++ b/src/libsyntax/edition.rs @@ -36,7 +36,7 @@ pub enum Edition { } // must be in order from oldest to newest -pub const ALL_EPOCHS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; +pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 53c6d9b49764a05cc87a06888dfa3e24999ff4ce Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 20 Mar 2018 19:21:38 +0100 Subject: [PATCH 447/830] Don't check interpret_interner when accessing a static to fix miri mutable statics --- src/librustc_mir/interpret/place.rs | 32 +++++++++-------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index d27de3ef6bfc..456f5fd75db0 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -197,29 +197,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { }, Static(ref static_) => { - let alloc = self - .tcx - .interpret_interner - .get_cached(static_.def_id); let layout = self.layout_of(self.place_ty(mir_place))?; - if let Some(alloc) = alloc { - Place::Ptr { - ptr: MemoryPointer::new(alloc, 0).into(), - align: layout.align, - extra: PlaceExtra::None, - } - } else { - let instance = ty::Instance::mono(*self.tcx, static_.def_id); - let cid = GlobalId { - instance, - promoted: None - }; - let alloc = Machine::init_static(self, cid)?; - Place::Ptr { - ptr: MemoryPointer::new(alloc, 0).into(), - align: layout.align, - extra: PlaceExtra::None, - } + let instance = ty::Instance::mono(*self.tcx, static_.def_id); + let cid = GlobalId { + instance, + promoted: None + }; + let alloc = Machine::init_static(self, cid)?; + Place::Ptr { + ptr: MemoryPointer::new(alloc, 0).into(), + align: layout.align, + extra: PlaceExtra::None, } } From 72334fee6fad3c51a036d7f592915ea472959714 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 14:19:16 -0500 Subject: [PATCH 448/830] typeck: Report main return type errors on return type span --- src/librustc_typeck/check/mod.rs | 3 ++- .../termination-trait-main-wrong-type.rs | 3 +-- .../termination-trait-main-wrong-type.stderr | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) rename src/test/{compile-fail => ui}/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs (80%) create mode 100644 src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 42bf516a0afa..a951fa7eb220 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1114,8 +1114,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>, Some(config::EntryMain) => { let substs = fcx.tcx.mk_substs(iter::once(Kind::from(ret_ty))); let trait_ref = ty::TraitRef::new(term_id, substs); + let return_ty_span = decl.output.span(); let cause = traits::ObligationCause::new( - span, fn_id, ObligationCauseCode::MainFunctionType); + return_ty_span, fn_id, ObligationCauseCode::MainFunctionType); inherited.register_predicate( traits::Obligation::new( diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs similarity index 80% rename from src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs rename to src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs index 5f4ccf2b5862..425f51ca2fb5 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types that implement std::process::Termination, not `char -fn main() -> char { +fn main() -> char { //~ ERROR ' ' } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr new file mode 100644 index 000000000000..d09aac3ac2f2 --- /dev/null +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `char: std::process::Termination` is not satisfied + --> $DIR/termination-trait-main-wrong-type.rs:11:14 + | +LL | fn main() -> char { //~ ERROR + | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | + = help: the trait `std::process::Termination` is not implemented for `char` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From a9cbfaa29687395452208a823502cc906a493ae2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 14 Mar 2018 17:29:09 -0400 Subject: [PATCH 449/830] rewrite to use a custom folder --- src/librustc/infer/anon_types/mod.rs | 92 +++++++++++++++------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index eb26f0c1188b..6a4f4072f53d 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -14,8 +14,8 @@ use infer::outlives::free_region_map::FreeRegionRelations; use rustc_data_structures::fx::FxHashMap; use syntax::ast; use traits::{self, PredicateObligation}; -use ty::{self, Ty}; -use ty::fold::{BottomUpFolder, TypeFoldable}; +use ty::{self, Ty, TyCtxt}; +use ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; use ty::outlives::Component; use ty::subst::{Kind, UnpackedKind, Substs}; use util::nodemap::DefIdMap; @@ -458,55 +458,63 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, // after producing an error for each of them. - let definition_ty = gcx.fold_regions(&instantiated_ty, &mut false, |r, _| { - match *r { - // 'static and early-bound regions are valid. - ty::ReStatic | ty::ReEmpty => r, - - // All other regions, we map them appropriately to their adjusted - // indices, erroring if we find any lifetimes that were not mapped - // into the new set. - _ => if let Some(UnpackedKind::Lifetime(r1)) = map.get(&r.into()) - .map(|k| k.unpack()) { - r1 - } else { - // No mapping was found. This means that - // it is either a disallowed lifetime, - // which will be caught by regionck, or it - // is a region in a non-upvar closure - // generic, which is explicitly - // allowed. If that surprises you, read - // on. - // - // The case of closure is a somewhat - // subtle (read: hacky) consideration. The - // problem is that our closure types - // currently include all the lifetime - // parameters declared on the enclosing - // function, even if they are unused by - // the closure itself. We can't readily - // filter them out, so here we replace - // those values with `'empty`. This can't - // really make a difference to the rest of - // the compiler; those regions are ignored - // for the outlives relation, and hence - // don't affect trait selection or auto - // traits, and they are erased during - // trans. - gcx.types.re_empty - }, - } - }); - + let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper { tcx: self.tcx, map }); debug!( "infer_anon_definition_from_instantiation: definition_ty={:?}", definition_ty ); + // We can unwrap here because our reverse mapper always + // produces things with 'gcx lifetime, though the type folder + // obscures that. + let definition_ty = gcx.lift(&definition_ty).unwrap(); + definition_ty } } +struct ReverseMapper<'cx, 'gcx: 'tcx, 'tcx: 'cx> { + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + map: FxHashMap, Kind<'gcx>> +} + +impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> { + fn tcx(&self) -> TyCtxt<'_, 'gcx, 'tcx> { + self.tcx + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + // ignore bound regions that appear in the type (e.g., this + // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. + if let ty::ReLateBound(..) = *r { + return r; + } + + match self.map.get(&r.into()).map(|k| k.unpack()) { + Some(UnpackedKind::Lifetime(r1)) => r1, + Some(u) => panic!("region mapped to unexpected kind: {:?}", u), + None => { + // No mapping was found. This means that it is either a + // disallowed lifetime, which will be caught by regionck, + // or it is a region in a non-upvar closure generic, which + // is explicitly allowed. If that surprises you, read on. + // + // The case of closure is a somewhat subtle (read: hacky) + // consideration. The problem is that our closure types + // currently include all the lifetime parameters declared + // on the enclosing function, even if they are unused by + // the closure itself. We can't readily filter them out, + // so here we replace those values with `'empty`. This + // can't really make a difference to the rest of the + // compiler; those regions are ignored for the outlives + // relation, and hence don't affect trait selection or + // auto traits, and they are erased during trans. + self.tcx.types.re_empty + } + } + } +} + struct Instantiator<'a, 'gcx: 'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, parent_def_id: DefId, From 25abe4830769e7bfceff75dc27d443c6d625fe13 Mon Sep 17 00:00:00 2001 From: Mrowqa Date: Tue, 20 Mar 2018 22:12:31 +0100 Subject: [PATCH 450/830] Pass attributes to hir::TyParam --- src/librustc/hir/lowering.rs | 1 + src/librustc/hir/map/mod.rs | 1 + src/librustc/hir/mod.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1439410f7e9a..a35af56bd97b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1585,6 +1585,7 @@ impl<'a> LoweringContext<'a> { .filter(|attr| attr.check_name("rustc_synthetic")) .map(|_| hir::SyntheticTyParamKind::ImplTrait) .nth(0), + attrs: self.lower_attrs(&tp.attrs), } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 61fae4609d54..e8bcbfbb77a1 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -962,6 +962,7 @@ impl<'hir> Map<'hir> { Some(NodeField(ref f)) => Some(&f.attrs[..]), Some(NodeExpr(ref e)) => Some(&*e.attrs), Some(NodeStmt(ref s)) => Some(s.node.attrs()), + Some(NodeTyParam(tp)) => Some(&tp.attrs[..]), // unit/tuple structs take the attributes straight from // the struct definition. Some(NodeStructCtor(_)) => { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 5ae84f5685ea..d6810b2468bc 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -414,6 +414,7 @@ pub struct TyParam { pub span: Span, pub pure_wrt_drop: bool, pub synthetic: Option, + pub attrs: HirVec, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] From 20e65f11f3bb0538c5676425e74b593676bd0f12 Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 21 Mar 2018 02:59:07 +0800 Subject: [PATCH 451/830] Apply a fix to travis-ci/dpl#788 manually until dpl 1.9.5 is released. --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index 41ea0c9afa87..b2aba305aedc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -318,6 +318,8 @@ before_deploy: deploy: - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -334,6 +336,8 @@ deploy: # this is the same as the above deployment provider except that it uploads to # a slightly different directory and has a different trigger - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -351,6 +355,8 @@ deploy: # try branch. Travis does not appear to provide a way to use "or" in these # conditions. - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -365,6 +371,8 @@ deploy: condition: $DEPLOY = 1 - provider: s3 + edge: + branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy From 1f51840db0d846c2370f7d726eb8e41424431850 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Mar 2018 23:08:04 +0100 Subject: [PATCH 452/830] Propose a variant if it is an enum for E0599 --- src/librustc_typeck/check/method/suggest.rs | 17 +++++++++++++++-- src/test/ui/issue-23217.stderr | 2 ++ src/test/ui/issue-28971.stderr | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 61afac97d640..06bec8f6ff65 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -22,12 +22,14 @@ use rustc::traits::{Obligation, SelectionContext}; use util::nodemap::FxHashSet; use syntax::ast; +use syntax::util::lev_distance::find_best_match_for_name; use errors::DiagnosticBuilder; use syntax_pos::Span; use rustc::hir; use rustc::hir::print; use rustc::infer::type_variable::TypeVariableOrigin; +use rustc::ty::TyAdt; use std::cell; use std::cmp::Ordering; @@ -179,9 +181,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let actual = self.resolve_type_vars_if_possible(&rcvr_ty); let ty_string = self.ty_to_string(actual); let is_method = mode == Mode::MethodCall; + let mut suggestion = None; let type_str = if is_method { "method" } else if actual.is_enum() { + if let TyAdt(ref adt_def, _) = actual.sty { + let names = adt_def.variants.iter().map(|s| &s.name); + suggestion = find_best_match_for_name(names, + &item_name.as_str(), + None); + } "variant" } else { match (item_name.as_str().chars().next(), actual.is_fresh_ty()) { @@ -256,7 +265,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err.emit(); return; } else { - struct_span_err!( + let mut err = struct_span_err!( tcx.sess, span, E0599, @@ -264,7 +273,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { type_str, item_name, ty_string - ) + ); + if let Some(suggestion) = suggestion { + err.note(&format!("did you mean `{}::{}`?", type_str, suggestion)); + } + err } } else { tcx.sess.diagnostic().struct_dummy() diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr index be9ec9d73c21..d542a10e9b60 100644 --- a/src/test/ui/issue-23217.stderr +++ b/src/test/ui/issue-23217.stderr @@ -5,6 +5,8 @@ LL | pub enum SomeEnum { | ----------------- variant `A` not found here LL | B = SomeEnum::A, | ^^^^^^^^^^^ variant not found in `SomeEnum` + | + = note: did you mean `variant::B`? error: aborting due to previous error diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr index 81d8d97963bd..df114351ff57 100644 --- a/src/test/ui/issue-28971.stderr +++ b/src/test/ui/issue-28971.stderr @@ -6,6 +6,8 @@ LL | enum Foo { ... LL | Foo::Baz(..) => (), | ^^^^^^^^^^^^ variant not found in `Foo` + | + = note: did you mean `variant::Bar`? error: aborting due to previous error From 57896abc38f56dce27ca9d4642c18f44be8db620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 20 Mar 2018 00:48:41 +0100 Subject: [PATCH 453/830] Make resuming generators unsafe instead of the creation of immovable generators. Fixes #47787 --- .../src/language-features/generators.md | 20 ++++++------- src/liballoc/boxed.rs | 2 +- src/libcore/ops/generator.rs | 12 +++++--- src/librustc_mir/diagnostics.rs | 10 +++---- src/librustc_mir/transform/check_unsafety.rs | 12 ++------ src/test/run-pass/dynamic-drop.rs | 2 +- .../run-pass/generator/conditional-drop.rs | 8 +++--- src/test/run-pass/generator/control-flow.rs | 2 +- src/test/run-pass/generator/drop-env.rs | 4 +-- src/test/run-pass/generator/issue-44197.rs | 6 ++-- src/test/run-pass/generator/iterator-count.rs | 4 ++- .../generator/live-upvar-across-yield.rs | 2 +- .../run-pass/generator/nested_generators.rs | 2 +- src/test/run-pass/generator/panic-drops.rs | 4 +-- src/test/run-pass/generator/panic-safe.rs | 4 +-- .../run-pass/generator/resume-after-return.rs | 4 +-- src/test/run-pass/generator/smoke.rs | 28 +++++++++---------- .../run-pass/generator/static-generators.rs | 18 ++++++------ .../run-pass/generator/xcrate-reachable.rs | 2 +- src/test/run-pass/generator/xcrate.rs | 6 ++-- src/test/ui/generator/borrowing.rs | 2 +- src/test/ui/generator/borrowing.stderr | 10 +++---- src/test/ui/generator/dropck.rs | 2 +- src/test/ui/generator/sized-yield.rs | 2 +- src/test/ui/generator/sized-yield.stderr | 6 ++-- src/test/ui/generator/unsafe-immovable.rs | 17 ----------- src/test/ui/generator/unsafe-immovable.stderr | 11 -------- .../ui/generator/yield-while-iterating.rs | 6 ++-- .../generator/yield-while-local-borrowed.rs | 6 ++-- .../generator/yield-while-ref-reborrowed.rs | 6 ++-- 30 files changed, 96 insertions(+), 124 deletions(-) delete mode 100644 src/test/ui/generator/unsafe-immovable.rs delete mode 100644 src/test/ui/generator/unsafe-immovable.stderr diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md index e8e2132dca25..8e888de90a95 100644 --- a/src/doc/unstable-book/src/language-features/generators.md +++ b/src/doc/unstable-book/src/language-features/generators.md @@ -36,11 +36,11 @@ fn main() { return "foo" }; - match generator.resume() { + match unsafe { generator.resume() } { GeneratorState::Yielded(1) => {} _ => panic!("unexpected value from resume"), } - match generator.resume() { + match unsafe { generator.resume() } { GeneratorState::Complete("foo") => {} _ => panic!("unexpected value from resume"), } @@ -69,9 +69,9 @@ fn main() { }; println!("1"); - generator.resume(); + unsafe { generator.resume() }; println!("3"); - generator.resume(); + unsafe { generator.resume() }; println!("5"); } ``` @@ -92,7 +92,7 @@ The `Generator` trait in `std::ops` currently looks like: pub trait Generator { type Yield; type Return; - fn resume(&mut self) -> GeneratorState; + unsafe fn resume(&mut self) -> GeneratorState; } ``` @@ -175,8 +175,8 @@ fn main() { return ret }; - generator.resume(); - generator.resume(); + unsafe { generator.resume() }; + unsafe { generator.resume() }; } ``` @@ -200,7 +200,7 @@ fn main() { type Yield = i32; type Return = &'static str; - fn resume(&mut self) -> GeneratorState { + unsafe fn resume(&mut self) -> GeneratorState { use std::mem; match mem::replace(self, __Generator::Done) { __Generator::Start(s) => { @@ -223,8 +223,8 @@ fn main() { __Generator::Start(ret) }; - generator.resume(); - generator.resume(); + unsafe { generator.resume() }; + unsafe { generator.resume() }; } ``` diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index b776556d59f1..a86ab87ec185 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -892,7 +892,7 @@ impl Generator for Box { type Yield = T::Yield; type Return = T::Return; - fn resume(&mut self) -> GeneratorState { + unsafe fn resume(&mut self) -> GeneratorState { (**self).resume() } } diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs index dc7669d195c1..4b70c5398be4 100644 --- a/src/libcore/ops/generator.rs +++ b/src/libcore/ops/generator.rs @@ -56,11 +56,11 @@ pub enum GeneratorState { /// return "foo" /// }; /// -/// match generator.resume() { +/// match unsafe { generator.resume() } { /// GeneratorState::Yielded(1) => {} /// _ => panic!("unexpected return from resume"), /// } -/// match generator.resume() { +/// match unsafe { generator.resume() } { /// GeneratorState::Complete("foo") => {} /// _ => panic!("unexpected return from resume"), /// } @@ -98,6 +98,10 @@ pub trait Generator { /// generator will continue executing until it either yields or returns, at /// which point this function will return. /// + /// The function is unsafe because it can be used on an immovable generator. + /// After such a call, the immovable generator must not move again, but + /// this is not enforced by the compiler. + /// /// # Return value /// /// The `GeneratorState` enum returned from this function indicates what @@ -116,7 +120,7 @@ pub trait Generator { /// been returned previously. While generator literals in the language are /// guaranteed to panic on resuming after `Complete`, this is not guaranteed /// for all implementations of the `Generator` trait. - fn resume(&mut self) -> GeneratorState; + unsafe fn resume(&mut self) -> GeneratorState; } #[unstable(feature = "generator_trait", issue = "43122")] @@ -125,7 +129,7 @@ impl<'a, T> Generator for &'a mut T { type Yield = T::Yield; type Return = T::Return; - fn resume(&mut self) -> GeneratorState { + unsafe fn resume(&mut self) -> GeneratorState { (**self).resume() } } diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 2000ebea25d7..4f36c3888b96 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -2247,7 +2247,7 @@ let mut b = || { yield (); // ...is still in scope here, when the yield occurs. println!("{}", a); }; -b.resume(); +unsafe { b.resume() }; ``` At present, it is not permitted to have a yield that occurs while a @@ -2265,7 +2265,7 @@ let mut b = || { yield (); println!("{}", a); }; -b.resume(); +unsafe { b.resume() }; ``` This is a very simple case, of course. In more complex cases, we may @@ -2283,7 +2283,7 @@ let mut b = || { yield x; // ...when this yield occurs. } }; -b.resume(); +unsafe { b.resume() }; ``` Such cases can sometimes be resolved by iterating "by value" (or using @@ -2298,7 +2298,7 @@ let mut b = || { yield x; // <-- Now yield is OK. } }; -b.resume(); +unsafe { b.resume() }; ``` If taking ownership is not an option, using indices can work too: @@ -2314,7 +2314,7 @@ let mut b = || { yield x; // <-- Now yield is OK. } }; -b.resume(); +unsafe { b.resume() }; // (*) -- Unfortunately, these temporaries are currently required. // See . diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 86d08dec2b9c..033fb493d735 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -125,21 +125,13 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { &AggregateKind::Array(..) | &AggregateKind::Tuple | &AggregateKind::Adt(..) => {} - &AggregateKind::Closure(def_id, _) => { + &AggregateKind::Closure(def_id, _) | + &AggregateKind::Generator(def_id, _, _) => { let UnsafetyCheckResult { violations, unsafe_blocks } = self.tcx.unsafety_check_result(def_id); self.register_violations(&violations, &unsafe_blocks); } - &AggregateKind::Generator(def_id, _, interior) => { - let UnsafetyCheckResult { - violations, unsafe_blocks - } = self.tcx.unsafety_check_result(def_id); - self.register_violations(&violations, &unsafe_blocks); - if !interior.movable { - self.require_unsafe("construction of immovable generator") - } - } } } self.super_rvalue(rvalue, location); diff --git a/src/test/run-pass/dynamic-drop.rs b/src/test/run-pass/dynamic-drop.rs index 4d0bd3f3412f..abbce16b77cf 100644 --- a/src/test/run-pass/dynamic-drop.rs +++ b/src/test/run-pass/dynamic-drop.rs @@ -178,7 +178,7 @@ fn generator(a: &Allocator, run_count: usize) { ); }; for _ in 0..run_count { - gen.resume(); + unsafe { gen.resume(); } } } diff --git a/src/test/run-pass/generator/conditional-drop.rs b/src/test/run-pass/generator/conditional-drop.rs index 8329684e1a39..3d39c46186be 100644 --- a/src/test/run-pass/generator/conditional-drop.rs +++ b/src/test/run-pass/generator/conditional-drop.rs @@ -42,9 +42,9 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n + 1); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n + 1); } @@ -58,8 +58,8 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n); - a.resume(); + unsafe { a.resume() }; assert_eq!(A.load(Ordering::SeqCst), n + 1); } diff --git a/src/test/run-pass/generator/control-flow.rs b/src/test/run-pass/generator/control-flow.rs index 60a00b4e4675..09971410e556 100644 --- a/src/test/run-pass/generator/control-flow.rs +++ b/src/test/run-pass/generator/control-flow.rs @@ -16,7 +16,7 @@ fn finish(mut amt: usize, mut t: T) -> T::Return where T: Generator { loop { - match t.resume() { + match unsafe { t.resume() } { GeneratorState::Yielded(()) => amt = amt.checked_sub(1).unwrap(), GeneratorState::Complete(ret) => { assert_eq!(amt, 0); diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs index ac42a25899db..ef4dc24472e6 100644 --- a/src/test/run-pass/generator/drop-env.rs +++ b/src/test/run-pass/generator/drop-env.rs @@ -37,7 +37,7 @@ fn t1() { }; let n = A.load(Ordering::SeqCst); - drop(foo.resume()); + drop(unsafe { foo.resume() }); assert_eq!(A.load(Ordering::SeqCst), n); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); @@ -50,7 +50,7 @@ fn t2() { }; let n = A.load(Ordering::SeqCst); - drop(foo.resume()); + drop(unsafe { foo.resume() }); assert_eq!(A.load(Ordering::SeqCst), n + 1); drop(foo); assert_eq!(A.load(Ordering::SeqCst), n + 1); diff --git a/src/test/run-pass/generator/issue-44197.rs b/src/test/run-pass/generator/issue-44197.rs index 7cb80ea8b21b..8ce4fc6affab 100644 --- a/src/test/run-pass/generator/issue-44197.rs +++ b/src/test/run-pass/generator/issue-44197.rs @@ -35,6 +35,8 @@ fn bar2(baz: String) -> impl Generator { } fn main() { - assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new())); - assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(())); + unsafe { + assert_eq!(bar(String::new()).resume(), GeneratorState::Yielded(String::new())); + assert_eq!(bar2(String::new()).resume(), GeneratorState::Complete(())); + } } diff --git a/src/test/run-pass/generator/iterator-count.rs b/src/test/run-pass/generator/iterator-count.rs index 9afe95f9e865..654b18928c07 100644 --- a/src/test/run-pass/generator/iterator-count.rs +++ b/src/test/run-pass/generator/iterator-count.rs @@ -14,11 +14,13 @@ use std::ops::{GeneratorState, Generator}; struct W(T); +// This impl isn't safe in general, but the generator used in this test is movable +// so it won't cause problems. impl> Iterator for W { type Item = T::Yield; fn next(&mut self) -> Option { - match self.0.resume() { + match unsafe { self.0.resume() } { GeneratorState::Complete(..) => None, GeneratorState::Yielded(v) => Some(v), } diff --git a/src/test/run-pass/generator/live-upvar-across-yield.rs b/src/test/run-pass/generator/live-upvar-across-yield.rs index e34b0b3100c3..28e7da232ce0 100644 --- a/src/test/run-pass/generator/live-upvar-across-yield.rs +++ b/src/test/run-pass/generator/live-upvar-across-yield.rs @@ -17,5 +17,5 @@ fn main() { let mut a = || { b(yield); }; - a.resume(); + unsafe { a.resume() }; } diff --git a/src/test/run-pass/generator/nested_generators.rs b/src/test/run-pass/generator/nested_generators.rs index f70d4144a3c9..29808da85a7a 100644 --- a/src/test/run-pass/generator/nested_generators.rs +++ b/src/test/run-pass/generator/nested_generators.rs @@ -20,7 +20,7 @@ fn main() { yield 2; }; - match sub_generator.resume() { + match unsafe { sub_generator.resume() } { GeneratorState::Yielded(x) => { yield x; } diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs index 36e401a54bcd..3d7b60ab6b90 100644 --- a/src/test/run-pass/generator/panic-drops.rs +++ b/src/test/run-pass/generator/panic-drops.rs @@ -42,7 +42,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 0); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); @@ -57,7 +57,7 @@ fn main() { assert_eq!(A.load(Ordering::SeqCst), 1); let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); assert_eq!(A.load(Ordering::SeqCst), 1); diff --git a/src/test/run-pass/generator/panic-safe.rs b/src/test/run-pass/generator/panic-safe.rs index 0d5bae7876bd..ace5cdde51d8 100644 --- a/src/test/run-pass/generator/panic-safe.rs +++ b/src/test/run-pass/generator/panic-safe.rs @@ -24,13 +24,13 @@ fn main() { }; let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); for _ in 0..10 { let res = panic::catch_unwind(panic::AssertUnwindSafe(|| { - foo.resume() + unsafe { foo.resume() } })); assert!(res.is_err()); } diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/run-pass/generator/resume-after-return.rs index 56511dcd53a6..06e7615d2619 100644 --- a/src/test/run-pass/generator/resume-after-return.rs +++ b/src/test/run-pass/generator/resume-after-return.rs @@ -23,12 +23,12 @@ fn main() { yield; }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } - match panic::catch_unwind(move || foo.resume()) { + match panic::catch_unwind(move || unsafe { foo.resume() }) { Ok(_) => panic!("generator successfully resumed"), Err(_) => {} } diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs index 8693964665d3..7395c8484c16 100644 --- a/src/test/run-pass/generator/smoke.rs +++ b/src/test/run-pass/generator/smoke.rs @@ -24,7 +24,7 @@ fn simple() { } }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -40,7 +40,7 @@ fn return_capture() { a }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -52,11 +52,11 @@ fn simple_yield() { yield; }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -69,11 +69,11 @@ fn yield_capture() { yield b; }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -86,11 +86,11 @@ fn simple_yield_value() { return String::from("foo") }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(ref s) if *s == "bar" => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -104,11 +104,11 @@ fn return_after_yield() { return a }; - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(ref s) if *s == "foo" => {} s => panic!("bad state: {:?}", s), } @@ -156,11 +156,11 @@ fn send_and_sync() { fn send_over_threads() { let mut foo = || { yield }; thread::spawn(move || { - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(()) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } @@ -169,11 +169,11 @@ fn send_over_threads() { let a = String::from("a"); let mut foo = || { yield a }; thread::spawn(move || { - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(ref s) if *s == "a" => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/run-pass/generator/static-generators.rs b/src/test/run-pass/generator/static-generators.rs index 9504414d8b6f..ebc070eee09c 100644 --- a/src/test/run-pass/generator/static-generators.rs +++ b/src/test/run-pass/generator/static-generators.rs @@ -13,14 +13,14 @@ use std::ops::{Generator, GeneratorState}; fn main() { - let mut generator = unsafe { - static || { - let a = true; - let b = &a; - yield; - assert_eq!(b as *const _, &a as *const _); - } + let mut generator = static || { + let a = true; + let b = &a; + yield; + assert_eq!(b as *const _, &a as *const _); }; - assert_eq!(generator.resume(), GeneratorState::Yielded(())); - assert_eq!(generator.resume(), GeneratorState::Complete(())); + unsafe { + assert_eq!(generator.resume(), GeneratorState::Yielded(())); + assert_eq!(generator.resume(), GeneratorState::Complete(())); + } } diff --git a/src/test/run-pass/generator/xcrate-reachable.rs b/src/test/run-pass/generator/xcrate-reachable.rs index dff5e08b9c20..8eeb01331449 100644 --- a/src/test/run-pass/generator/xcrate-reachable.rs +++ b/src/test/run-pass/generator/xcrate-reachable.rs @@ -17,5 +17,5 @@ extern crate xcrate_reachable as foo; use std::ops::Generator; fn main() { - foo::foo().resume(); + unsafe { foo::foo().resume(); } } diff --git a/src/test/run-pass/generator/xcrate.rs b/src/test/run-pass/generator/xcrate.rs index dc7a6fdef9c7..04791d513567 100644 --- a/src/test/run-pass/generator/xcrate.rs +++ b/src/test/run-pass/generator/xcrate.rs @@ -19,18 +19,18 @@ use std::ops::{GeneratorState, Generator}; fn main() { let mut foo = xcrate::foo(); - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } let mut foo = xcrate::bar(3); - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Yielded(3) => {} s => panic!("bad state: {:?}", s), } - match foo.resume() { + match unsafe { foo.resume() } { GeneratorState::Complete(()) => {} s => panic!("bad state: {:?}", s), } diff --git a/src/test/ui/generator/borrowing.rs b/src/test/ui/generator/borrowing.rs index de10bdef4aee..e56927d81823 100644 --- a/src/test/ui/generator/borrowing.rs +++ b/src/test/ui/generator/borrowing.rs @@ -15,7 +15,7 @@ use std::ops::Generator; fn main() { let _b = { let a = 3; - (|| yield &a).resume() + unsafe { (|| yield &a).resume() } //~^ ERROR: `a` does not live long enough }; diff --git a/src/test/ui/generator/borrowing.stderr b/src/test/ui/generator/borrowing.stderr index 2a5de3790ada..45d950b5aef6 100644 --- a/src/test/ui/generator/borrowing.stderr +++ b/src/test/ui/generator/borrowing.stderr @@ -1,10 +1,10 @@ error[E0597]: `a` does not live long enough - --> $DIR/borrowing.rs:18:20 + --> $DIR/borrowing.rs:18:29 | -LL | (|| yield &a).resume() - | -- ^ borrowed value does not live long enough - | | - | capture occurs here +LL | unsafe { (|| yield &a).resume() } + | -- ^ borrowed value does not live long enough + | | + | capture occurs here LL | //~^ ERROR: `a` does not live long enough LL | }; | - borrowed value only lives until here diff --git a/src/test/ui/generator/dropck.rs b/src/test/ui/generator/dropck.rs index 0b143d7f5143..b2240fb225f5 100644 --- a/src/test/ui/generator/dropck.rs +++ b/src/test/ui/generator/dropck.rs @@ -23,6 +23,6 @@ fn main() { let _d = ref_.take(); //~ ERROR `ref_` does not live long enough yield; }; - gen.resume(); + unsafe { gen.resume(); } // drops the RefCell and then the Ref, leading to use-after-free } diff --git a/src/test/ui/generator/sized-yield.rs b/src/test/ui/generator/sized-yield.rs index f38ebf8b9463..a1c8ca77e41e 100644 --- a/src/test/ui/generator/sized-yield.rs +++ b/src/test/ui/generator/sized-yield.rs @@ -17,5 +17,5 @@ fn main() { let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied yield s[..]; }; - gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied + unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied } diff --git a/src/test/ui/generator/sized-yield.stderr b/src/test/ui/generator/sized-yield.stderr index fc99c7e3bd74..957fac172c25 100644 --- a/src/test/ui/generator/sized-yield.stderr +++ b/src/test/ui/generator/sized-yield.stderr @@ -11,10 +11,10 @@ LL | | }; = note: the yield type of a generator must have a statically known size error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied - --> $DIR/sized-yield.rs:20:8 + --> $DIR/sized-yield.rs:20:17 | -LL | gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied - | ^^^^^^ `str` does not have a constant size known at compile-time +LL | unsafe { gen.resume(); } //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied + | ^^^^^^ `str` does not have a constant size known at compile-time | = help: the trait `std::marker::Sized` is not implemented for `str` diff --git a/src/test/ui/generator/unsafe-immovable.rs b/src/test/ui/generator/unsafe-immovable.rs deleted file mode 100644 index 45acbf50931b..000000000000 --- a/src/test/ui/generator/unsafe-immovable.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -#![feature(generators)] - -fn main() { - static || { //~ ERROR: construction of immovable generator requires unsafe - yield; - }; -} diff --git a/src/test/ui/generator/unsafe-immovable.stderr b/src/test/ui/generator/unsafe-immovable.stderr deleted file mode 100644 index b2add55613d5..000000000000 --- a/src/test/ui/generator/unsafe-immovable.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0133]: construction of immovable generator requires unsafe function or block - --> $DIR/unsafe-immovable.rs:14:5 - | -LL | / static || { //~ ERROR: construction of immovable generator requires unsafe -LL | | yield; -LL | | }; - | |_____^ construction of immovable generator - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/generator/yield-while-iterating.rs b/src/test/ui/generator/yield-while-iterating.rs index bc53448cb08e..b8a67a0e7b65 100644 --- a/src/test/ui/generator/yield-while-iterating.rs +++ b/src/test/ui/generator/yield-while-iterating.rs @@ -43,7 +43,7 @@ fn yield_during_iter_borrowed_slice_2() { println!("{:?}", x); } -fn yield_during_iter_borrowed_slice_3() { +unsafe fn yield_during_iter_borrowed_slice_3() { // OK to take a mutable ref to `x` and yield // up pointers from it: let mut x = vec![22_i32]; @@ -55,7 +55,7 @@ fn yield_during_iter_borrowed_slice_3() { b.resume(); } -fn yield_during_iter_borrowed_slice_4() { +unsafe fn yield_during_iter_borrowed_slice_4() { // ...but not OK to do that while reading // from `x` too let mut x = vec![22_i32]; @@ -68,7 +68,7 @@ fn yield_during_iter_borrowed_slice_4() { b.resume(); } -fn yield_during_range_iter() { +unsafe fn yield_during_range_iter() { // Should be OK. let mut b = || { let v = vec![1,2,3]; diff --git a/src/test/ui/generator/yield-while-local-borrowed.rs b/src/test/ui/generator/yield-while-local-borrowed.rs index 11bd4ed05cac..3dc2650a2ecb 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.rs +++ b/src/test/ui/generator/yield-while-local-borrowed.rs @@ -15,7 +15,7 @@ use std::ops::{GeneratorState, Generator}; use std::cell::Cell; -fn borrow_local_inline() { +unsafe fn borrow_local_inline() { // Not OK to yield with a borrow of a temporary. // // (This error occurs because the region shows up in the type of @@ -30,7 +30,7 @@ fn borrow_local_inline() { b.resume(); } -fn borrow_local_inline_done() { +unsafe fn borrow_local_inline_done() { // No error here -- `a` is not in scope at the point of `yield`. let mut b = move || { { @@ -41,7 +41,7 @@ fn borrow_local_inline_done() { b.resume(); } -fn borrow_local() { +unsafe fn borrow_local() { // Not OK to yield with a borrow of a temporary. // // (This error occurs because the region shows up in the type of diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.rs b/src/test/ui/generator/yield-while-ref-reborrowed.rs index b9c963ae7407..573dd4377bb2 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.rs +++ b/src/test/ui/generator/yield-while-ref-reborrowed.rs @@ -13,7 +13,7 @@ use std::ops::{GeneratorState, Generator}; use std::cell::Cell; -fn reborrow_shared_ref(x: &i32) { +unsafe fn reborrow_shared_ref(x: &i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the generator. let mut b = move || { @@ -24,7 +24,7 @@ fn reborrow_shared_ref(x: &i32) { b.resume(); } -fn reborrow_mutable_ref(x: &mut i32) { +unsafe fn reborrow_mutable_ref(x: &mut i32) { // This is OK -- we have a borrow live over the yield, but it's of // data that outlives the generator. let mut b = move || { @@ -35,7 +35,7 @@ fn reborrow_mutable_ref(x: &mut i32) { b.resume(); } -fn reborrow_mutable_ref_2(x: &mut i32) { +unsafe fn reborrow_mutable_ref_2(x: &mut i32) { // ...but not OK to go on using `x`. let mut b = || { let a = &mut *x; From 6956bbf61cd0c4e5f0c39ca397085fa040710f56 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 20 Mar 2018 19:36:30 -0500 Subject: [PATCH 454/830] whitelist every target feature for rustdoc --- src/librustc_trans/attributes.rs | 16 ++++++++++++---- src/librustc_trans/llvm_util.rs | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index d5ec8d1b5526..040d9455334b 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -148,9 +148,17 @@ fn cstr(s: &'static str) -> &CStr { pub fn provide(providers: &mut Providers) { providers.target_features_whitelist = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); - Lrc::new(llvm_util::target_feature_whitelist(tcx.sess) - .iter() - .map(|c| c.to_string()) - .collect()) + if tcx.sess.opts.actually_rustdoc { + // rustdoc needs to be able to document functions that use all the features, so + // whitelist them all + Lrc::new(llvm_util::all_known_features() + .map(|c| c.to_string()) + .collect()) + } else { + Lrc::new(llvm_util::target_feature_whitelist(tcx.sess) + .iter() + .map(|c| c.to_string()) + .collect()) + } }; } diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index dd8b44c96b90..5113b65a5c47 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -107,6 +107,20 @@ const POWERPC_WHITELIST: &'static [&'static str] = &["altivec", const MIPS_WHITELIST: &'static [&'static str] = &["fp64", "msa"]; +/// When rustdoc is running, provide a list of all known features so that all their respective +/// primtives may be documented. +/// +/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this +/// iterator! +pub fn all_known_features() -> impl Iterator { + ARM_WHITELIST.iter().cloned() + .chain(AARCH64_WHITELIST.iter().cloned()) + .chain(X86_WHITELIST.iter().cloned()) + .chain(HEXAGON_WHITELIST.iter().cloned()) + .chain(POWERPC_WHITELIST.iter().cloned()) + .chain(MIPS_WHITELIST.iter().cloned()) +} + pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { let arch = if sess.target.target.arch == "x86_64" { "x86" From 1937661961fa54aa2bce8c301d85536916224a74 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 22:45:35 -0500 Subject: [PATCH 455/830] Revert "Stabilize termination_trait in 1.25, not 1.26" This reverts commit e5a55e74405dedf8bc0744300a8c506eea94bc18. --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e71726bcebdc..781071b7f7f0 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -551,12 +551,12 @@ declare_features! ( (accepted, match_beginning_vert, "1.25.0", Some(44101), None), // Nested groups in `use` (RFC 2128) (accepted, use_nested_groups, "1.25.0", Some(44494), None), - // Termination trait in main (RFC 1937) - (accepted, termination_trait, "1.25.0", Some(43301), None), // a..=b and ..=b (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), // allow `..=` in patterns (RFC 1192) (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + // Termination trait in main (RFC 1937) + (accepted, termination_trait, "1.26.0", Some(43301), None), ); // If you change this, please modify src/doc/unstable-book as well. You must From 66d120cd263ea77a44fcde9409a71ac673a5262c Mon Sep 17 00:00:00 2001 From: Niv Kaminer Date: Wed, 21 Mar 2018 07:25:32 +0200 Subject: [PATCH 456/830] Revert "remove FIXME(#33435) and remove the spurious failures counter measure" This reverts commit be73a1f963e7830de2dbfbea6b362673ab7e6ded. --- src/tools/compiletest/src/main.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index cf87062f6bee..e65c03a6e571 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -452,6 +452,11 @@ pub fn run_tests(config: &Config) { _ => { /* proceed */ } } + // FIXME(#33435) Avoid spurious failures in codegen-units/partitioning tests. + if let Mode::CodegenUnits = config.mode { + let _ = fs::remove_dir_all("tmp/partitioning-tests"); + } + let opts = test_opts(config); let tests = make_tests(config); // sadly osx needs some file descriptor limits raised for running tests in From 94bdeb64f96b266d990ba7b76cd78a1e2ed1977f Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Tue, 20 Mar 2018 23:01:42 -0500 Subject: [PATCH 457/830] termination_trait: Add () example to error message --- src/libstd/process.rs | 2 +- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d5ac2d19e831..a6aa3502f26b 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1443,7 +1443,7 @@ pub fn id() -> u32 { #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] #[rustc_on_unimplemented = - "`main` can only return types that implement {Termination}, not `{Self}`"] + "`main` can only return types like `()` that implement {Termination}, not `{Self}`"] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 67ee39d10d91..ffff33da581b 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types that implement std::process::Termination, not `i32` +// error-pattern:`main` can only return types like `()` that implement std::process::Termination, no fn main() -> i32 { 0 } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index d09aac3ac2f2..24371c27742d 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `char: std::process::Termination` is not satisfied --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types like `()` that implement std::process::Termination, not `char` | = help: the trait `std::process::Termination` is not implemented for `char` From 2cdc7af41366182259a05435e325d7444653a3e8 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 00:24:06 -0500 Subject: [PATCH 458/830] Use NOTE instead of error-pattern directive --- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index ffff33da581b..053d6bbf93a2 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:`main` can only return types like `()` that implement std::process::Termination, no fn main() -> i32 { +//~^ ERROR `i32: std::process::Termination` is not satisfied +//~| NOTE `main` can only return types like `()` that implement std::process::Termination, not `i32` 0 } From 5201e7cf8ac0c78bc8e4f0feb8f97e91b957a19e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 21 Mar 2018 07:31:39 +0100 Subject: [PATCH 459/830] document format_args! behavior wrt. Display and Debug --- src/libcore/fmt/mod.rs | 72 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 3ecd73873c09..0363714c31b5 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -406,6 +406,18 @@ impl<'a> Arguments<'a> { /// macro validates the format string at compile-time so usage of the [`write`] /// and [`format`] functions can be safely performed. /// +/// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug` +/// and `Display` contexts as seen below. The example also shows that `Debug` +/// and `Display` format to the same thing: the interpolated format string +/// in `format_args!`. +/// +/// ```rust +/// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); +/// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2)); +/// assert_eq!("1 foo 2", display); +/// assert_eq!(display, debug); +/// ``` +/// /// [`format_args!`]: ../../std/macro.format_args.html /// [`format`]: ../../std/fmt/fn.format.html /// [`write`]: ../../std/fmt/fn.write.html @@ -1553,10 +1565,12 @@ impl<'a> Formatter<'a> { /// /// ```rust /// use std::fmt; + /// use std::net::Ipv4Addr; /// /// struct Foo { /// bar: i32, /// baz: String, + /// addr: Ipv4Addr, /// } /// /// impl fmt::Debug for Foo { @@ -1564,12 +1578,19 @@ impl<'a> Formatter<'a> { /// fmt.debug_struct("Foo") /// .field("bar", &self.bar) /// .field("baz", &self.baz) + /// .field("addr", &format_args!("{}", self.addr)) /// .finish() /// } /// } /// - /// // prints "Foo { bar: 10, baz: "Hello World" }" - /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() }); + /// assert_eq!( + /// "Foo { bar: 10, baz: \"Hello World\", addr: 127.0.0.1 }", + /// format!("{:?}", Foo { + /// bar: 10, + /// baz: "Hello World".to_string(), + /// addr: Ipv4Addr::new(127, 0, 0, 1), + /// }) + /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> { @@ -1583,20 +1604,24 @@ impl<'a> Formatter<'a> { /// /// ```rust /// use std::fmt; + /// use std::marker::PhantomData; /// - /// struct Foo(i32, String); + /// struct Foo(i32, String, PhantomData); /// - /// impl fmt::Debug for Foo { + /// impl fmt::Debug for Foo { /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { /// fmt.debug_tuple("Foo") /// .field(&self.0) /// .field(&self.1) + /// .field(&format_args!("_")) /// .finish() /// } /// } /// - /// // prints "Foo(10, "Hello World")" - /// println!("{:?}", Foo(10, "Hello World".to_string())); + /// assert_eq!( + /// "Foo(10, \"Hello\", _)", + /// format!("{:?}", Foo(10, "Hello".to_string(), PhantomData::)) + /// ); /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> { @@ -1646,6 +1671,41 @@ impl<'a> Formatter<'a> { /// // prints "{10, 11}" /// println!("{:?}", Foo(vec![10, 11])); /// ``` + /// + /// [`format_args!`]: ../../std/macro.format_args.html + /// + /// In this more complex example, we use [`format_args!`] and `.debug_set()` + /// to build a list of match arms: + /// + /// ```rust + /// use std::fmt; + /// + /// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R)); + /// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V); + /// + /// impl<'a, L, R> fmt::Debug for Arm<'a, L, R> + /// where + /// L: 'a + fmt::Debug, R: 'a + fmt::Debug + /// { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// L::fmt(&(self.0).0, fmt)?; + /// fmt.write_str(" => ")?; + /// R::fmt(&(self.0).1, fmt) + /// } + /// } + /// + /// impl<'a, K, V> fmt::Debug for Table<'a, K, V> + /// where + /// K: 'a + fmt::Debug, V: 'a + fmt::Debug + /// { + /// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + /// fmt.debug_set() + /// .entries(self.0.iter().map(Arm)) + /// .entry(&Arm(&(format_args!("_"), &self.1))) + /// .finish() + /// } + /// } + /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> { builders::debug_set_new(self) From afff64e7a4c88b39402c95f1368c880b17cdf793 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Wed, 21 Mar 2018 07:55:09 +0100 Subject: [PATCH 460/830] document format_args! further wrt. Debug & Display" --- src/libstd/macros.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 000f97136153..47609f17221e 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -335,6 +335,18 @@ pub mod builtin { /// proxied through this one. `format_args!`, unlike its derived macros, avoids /// heap allocations. /// + /// You can use the [`fmt::Arguments`] value that `format_args!` returns + /// in `Debug` and `Display` contexts as seen below. The example also shows + /// that `Debug` and `Display` format to the same thing: the interpolated + /// format string in `format_args!`. + /// + /// ```rust + /// let display = format!("{:?}", format_args!("{} foo {:?}", 1, 2)); + /// let debug = format!("{}", format_args!("{} foo {:?}", 1, 2)); + /// assert_eq!("1 foo 2", display); + /// assert_eq!(display, debug); + /// ``` + /// /// For more information, see the documentation in [`std::fmt`]. /// /// [`Display`]: ../std/fmt/trait.Display.html From 06f81032955e4dd92cb6be3d67f9a56c375c7313 Mon Sep 17 00:00:00 2001 From: Bastien Orivel Date: Wed, 21 Mar 2018 03:04:09 +0100 Subject: [PATCH 461/830] Bump racer and home This removes 10 dependencies from the build :tada: --- src/Cargo.lock | 114 ++++++------------------------------------------- 1 file changed, 12 insertions(+), 102 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 675457905ead..b452e83870a2 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1,20 +1,3 @@ -[[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.4" @@ -199,7 +182,7 @@ dependencies = [ "git2-curl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -567,15 +550,6 @@ dependencies = [ "num-traits 0.1.43 (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.9 (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.5.5" @@ -774,14 +748,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "home" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "advapi32-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)", - "scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1053,14 +1025,6 @@ dependencies = [ "toml-query 0.6.0 (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.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "memchr" version = "2.0.1" @@ -1319,13 +1283,13 @@ dependencies = [ [[package]] name = "racer" -version = "2.0.12" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (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)", @@ -1392,18 +1356,6 @@ version = "0.1.0" name = "reformat_with_range" version = "0.1.0" -[[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.7" @@ -1416,11 +1368,6 @@ 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.5.0" @@ -1461,7 +1408,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1525,7 +1472,7 @@ name = "rls-vfs" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2094,11 +2041,6 @@ name = "scoped-tls" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "scopeguard" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "scopeguard" version = "0.3.3" @@ -2416,23 +2358,6 @@ dependencies = [ "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "thread-id" -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.39 (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]] name = "thread_local" version = "0.3.5" @@ -2583,11 +2508,6 @@ dependencies = [ "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" @@ -2680,8 +2600,6 @@ 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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35c7a5669cb64f085739387e1308b74e6d44022464b7f1b63bbd4ceb6379ec31" @@ -2720,7 +2638,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834" "checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" "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.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" @@ -2741,7 +2658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum globset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e96ab92362c06811385ae9a34d2698e8a1160745e0c78fbb434a44c8de3fabc" "checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc" "checksum hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "459d3cf58137bb02ad4adeef5036377ff59f066dbb82517b7192e3a5462a2abc" -"checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db" +"checksum home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f94f6fbdc000a6eba0c8cf08632b2091bb59141d36ac321a2a96d6365e5e4dc" "checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" @@ -2767,7 +2684,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lzma-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c1b93b78f89e8737dac81837fc8f5521ac162abcba902e1a3db949d55346d1da" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum mdbook 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fef236caad7ba3b5b3944df946f19ab3e190bca53c111dd00fe05fa8d879f2fd" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4" @@ -2796,16 +2712,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" -"checksum racer 2.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "034f1c4528581c40a60e96875467c03315868084e08ff4ceb46a00f7be3b16b4" +"checksum racer 2.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "40d44bc30fc8d403b665286b2c9a83466ddbf69297668fb02b785c3e58eb8e0d" "checksum radix_trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "211c49b6a9995cac0fd1dd9ca60b42cf3a51e151a12eb954b3a9e75513426ee8" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" "checksum regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a62bf8bb734ab90b7f234b681b01af396e5d39b028906c210dc04fa1d5e9e5b3" -"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" "checksum regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48d7391e7e90e06eaf3aefbe4652464153ecfec64806f3bf77ffc59638a63e77" "checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" "checksum rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4b9a3a3f2345854e39768e6425d1c893855da217183d1c0b3ff6f1664b6b6d" @@ -2825,7 +2739,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fbaffce35eb61c5b00846e73128b0cd62717e7c0ec46abbec132370d013975b4" "checksum scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8674d439c964889e2476f474a3bf198cc9e199e77499960893bac5de7e9218a4" -"checksum scopeguard 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59a076157c1e2dc561d8de585151ee6965d910dd4dcb5dabb7ae3e83981a6c57" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" @@ -2854,8 +2767,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" -"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" -"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" @@ -2873,7 +2784,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" "checksum userenv-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d28ea36bbd9192d75bd9fa9b39f96ddb986eaee824adae5d53b6e51919b2f3" -"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 vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" From e0165af94b034dacde7f9a598c5e72b9c1a1898c Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 21 Mar 2018 10:32:53 +0100 Subject: [PATCH 462/830] fix vector fmin/fmax non-fast/fast intrinsics NaN handling --- src/librustc_trans/builder.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 3f5a9a54ff1e..91eabb9998f4 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -1036,7 +1036,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmin(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, true); + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); } @@ -1046,7 +1046,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmax(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmax"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, true); + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); } @@ -1056,7 +1056,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmin_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmin_fast"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, false); + let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0"); } @@ -1067,7 +1067,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn vector_reduce_fmax_fast(&self, src: ValueRef) -> ValueRef { self.count_insn("vector.reduce.fmax_fast"); unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, false); + let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true); if instr.is_null() { bug!("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0"); } From fc3c90cf8af1a2c0e9e6167daed956905b5951a2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 15 Mar 2018 05:10:42 -0400 Subject: [PATCH 463/830] report an error if we see an unexpected lifetime in impl Trait But leave closure substs alone. --- src/librustc/diagnostics.rs | 48 +++++ src/librustc/infer/anon_types/mod.rs | 188 ++++++++++++++---- .../region-escape-via-bound-contravariant.rs | 35 ++++ .../ui/impl-trait/region-escape-via-bound.rs | 34 ++++ .../impl-trait/region-escape-via-bound.stderr | 20 ++ 5 files changed, 291 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs create mode 100644 src/test/ui/impl-trait/region-escape-via-bound.rs create mode 100644 src/test/ui/impl-trait/region-escape-via-bound.stderr diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index b3a904f2f5fe..fad180325928 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2074,6 +2074,54 @@ a (non-transparent) struct containing a single float, while `Grams` is a transparent wrapper around a float. This can make a difference for the ABI. "##, +E0909: r##" +The `impl Trait` return type captures lifetime parameters that do not +appear within the `impl Trait` itself. + +Erroneous code example: + +```compile-fail,E0909 +use std::cell::Cell; + +trait Trait<'a> { } + +impl Trait<'b> for Cell<&'a u32> { } + +fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> +where 'x: 'y +{ + x +} +``` + +Here, the function `foo` returns a value of type `Cell<&'x u32>`, +which references the lifetime `'x`. However, the return type is +declared as `impl Trait<'y>` -- this indicates that `foo` returns +"some type that implements `Trait<'y>`", but it also indicates that +the return type **only captures data referencing the lifetime `'y`**. +In this case, though, we are referencing data with lifetime `'x`, so +this function is in error. + +To fix this, you must reference the lifetime `'x` from the return +type. For example, changing the return type to `impl Trait<'y> + 'x` +would work: + +``` +use std::cell::Cell; + +trait Trait<'a> { } + +impl Trait<'b> for Cell<&'a u32> { } + +fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> + 'x +where 'x: 'y +{ + x +} +``` +"##, + + } diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index 6a4f4072f53d..93e8745af1b5 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -17,7 +17,7 @@ use traits::{self, PredicateObligation}; use ty::{self, Ty, TyCtxt}; use ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder}; use ty::outlives::Component; -use ty::subst::{Kind, UnpackedKind, Substs}; +use ty::subst::{Kind, Substs, UnpackedKind}; use util::nodemap::DefIdMap; pub type AnonTypeMap<'tcx> = DefIdMap>; @@ -113,10 +113,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ) -> InferOk<'tcx, (T, AnonTypeMap<'tcx>)> { debug!( "instantiate_anon_types(value={:?}, parent_def_id={:?}, body_id={:?}, param_env={:?})", - value, - parent_def_id, - body_id, - param_env, + value, parent_def_id, body_id, param_env, ); let mut instantiator = Instantiator { infcx: self, @@ -458,7 +455,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Convert the type from the function into a type valid outside // the function, by replacing invalid regions with 'static, // after producing an error for each of them. - let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper { tcx: self.tcx, map }); + let definition_ty = + instantiated_ty.fold_with(&mut ReverseMapper::new( + self.tcx, + self.is_tainted_by_errors(), + def_id, + map, + instantiated_ty, + )); debug!( "infer_anon_definition_from_instantiation: definition_ty={:?}", definition_ty @@ -475,7 +479,49 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { struct ReverseMapper<'cx, 'gcx: 'tcx, 'tcx: 'cx> { tcx: TyCtxt<'cx, 'gcx, 'tcx>, - map: FxHashMap, Kind<'gcx>> + + /// If errors have already been reported in this fn, we suppress + /// our own errors because they are sometimes derivative. + tainted_by_errors: bool, + + anon_type_def_id: DefId, + map: FxHashMap, Kind<'gcx>>, + map_missing_regions_to_empty: bool, + + /// initially `Some`, set to `None` once error has been reported + hidden_ty: Option>, +} + +impl<'cx, 'gcx, 'tcx> ReverseMapper<'cx, 'gcx, 'tcx> { + fn new( + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + tainted_by_errors: bool, + anon_type_def_id: DefId, + map: FxHashMap, Kind<'gcx>>, + hidden_ty: Ty<'tcx>, + ) -> Self { + Self { + tcx, + tainted_by_errors, + anon_type_def_id, + map, + map_missing_regions_to_empty: false, + hidden_ty: Some(hidden_ty), + } + } + + fn fold_kind_mapping_missing_regions_to_empty(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> { + assert!(!self.map_missing_regions_to_empty); + self.map_missing_regions_to_empty = true; + let kind = kind.fold_with(self); + self.map_missing_regions_to_empty = false; + kind + } + + fn fold_kind_normally(&mut self, kind: Kind<'tcx>) -> Kind<'tcx> { + assert!(!self.map_missing_regions_to_empty); + kind.fold_with(self) + } } impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> { @@ -484,33 +530,105 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ReverseMapper<'cx, 'gcx, 'tcx> } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - // ignore bound regions that appear in the type (e.g., this - // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. - if let ty::ReLateBound(..) = *r { - return r; + match r { + // ignore bound regions that appear in the type (e.g., this + // would ignore `'r` in a type like `for<'r> fn(&'r u32)`. + ty::ReLateBound(..) => return r, + + // ignore `'static`, as that can appear anywhere + ty::ReStatic => return r, + + _ => { } } match self.map.get(&r.into()).map(|k| k.unpack()) { Some(UnpackedKind::Lifetime(r1)) => r1, Some(u) => panic!("region mapped to unexpected kind: {:?}", u), None => { - // No mapping was found. This means that it is either a - // disallowed lifetime, which will be caught by regionck, - // or it is a region in a non-upvar closure generic, which - // is explicitly allowed. If that surprises you, read on. + if !self.map_missing_regions_to_empty && !self.tainted_by_errors { + if let Some(hidden_ty) = self.hidden_ty.take() { + let span = self.tcx.def_span(self.anon_type_def_id); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0909, + "hidden type for `impl Trait` captures lifetime that \ + does not appear in bounds", + ); + + // Assuming regionck succeeded, then we must + // be capturing *some* region from the fn + // header, and hence it must be free, so it's + // ok to invoke this fn (which doesn't accept + // all regions, and would ICE if an + // inappropriate region is given). We check + // `is_tainted_by_errors` by errors above, so + // we don't get in here unless regionck + // succeeded. (Note also that if regionck + // failed, then the regions we are attempting + // to map here may well be giving errors + // *because* the constraints were not + // satisfiable.) + self.tcx.note_and_explain_free_region( + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + r, + "" + ); + + err.emit(); + } + } + self.tcx.types.re_empty + }, + } + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + match ty.sty { + ty::TyClosure(def_id, substs) => { + // I am a horrible monster and I pray for death. When + // we encounter a closure here, it is always a closure + // from within the function that we are currently + // type-checking -- one that is now being encapsulated + // in an existential abstract type. Ideally, we would + // go through the types/lifetimes that it references + // and treat them just like we would any other type, + // which means we would error out if we find any + // reference to a type/region that is not in the + // "reverse map". // - // The case of closure is a somewhat subtle (read: hacky) - // consideration. The problem is that our closure types - // currently include all the lifetime parameters declared - // on the enclosing function, even if they are unused by - // the closure itself. We can't readily filter them out, + // **However,** in the case of closures, there is a + // somewhat subtle (read: hacky) consideration. The + // problem is that our closure types currently include + // all the lifetime parameters declared on the + // enclosing function, even if they are unused by the + // closure itself. We can't readily filter them out, // so here we replace those values with `'empty`. This // can't really make a difference to the rest of the - // compiler; those regions are ignored for the outlives - // relation, and hence don't affect trait selection or - // auto traits, and they are erased during trans. - self.tcx.types.re_empty + // compiler; those regions are ignored for the + // outlives relation, and hence don't affect trait + // selection or auto traits, and they are erased + // during trans. + + let generics = self.tcx.generics_of(def_id); + let parent_len = generics.parent_count(); + let substs = self.tcx.mk_substs(substs.substs.iter().enumerate().map( + |(index, &kind)| { + if index < parent_len { + // Accommodate missing regions in the parent kinds... + self.fold_kind_mapping_missing_regions_to_empty(kind) + } else { + // ...but not elsewhere. + self.fold_kind_normally(kind) + } + }, + )); + + self.tcx.mk_closure(def_id, ty::ClosureSubsts { substs }) } + + _ => ty.super_fold_with(self), } } } @@ -573,12 +691,13 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { return self.fold_anon_ty(ty, def_id, substs); } - debug!("instantiate_anon_types_in_map: \ - encountered anon with wrong parent \ - def_id={:?} \ - anon_parent_def_id={:?}", - def_id, - anon_parent_def_id); + debug!( + "instantiate_anon_types_in_map: \ + encountered anon with wrong parent \ + def_id={:?} \ + anon_parent_def_id={:?}", + def_id, anon_parent_def_id + ); } } @@ -598,8 +717,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { debug!( "instantiate_anon_types: TyAnon(def_id={:?}, substs={:?})", - def_id, - substs + def_id, substs ); // Use the same type variable if the exact same TyAnon appears more @@ -608,8 +726,10 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { return anon_defn.concrete_ty; } let span = tcx.def_span(def_id); - let ty_var = infcx.next_ty_var(ty::UniverseIndex::ROOT, - TypeVariableOrigin::TypeInference(span)); + let ty_var = infcx.next_ty_var( + ty::UniverseIndex::ROOT, + TypeVariableOrigin::TypeInference(span), + ); let predicates_of = tcx.predicates_of(def_id); let bounds = predicates_of.instantiate(tcx, substs); diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs new file mode 100644 index 000000000000..416bdae51784 --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs @@ -0,0 +1,35 @@ +// 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. + +// In contrast to `region-escape-via-bound-invariant`, in this case we +// *can* return a value of type `&'x u32`, even though `'x` does not +// appear in the bounds. This is because `&` is contravariant, and so +// we are *actually* returning a `&'y u32`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +// run-pass + +#![allow(dead_code)] +#![feature(conservative_impl_trait)] +#![feature(in_band_lifetimes)] +#![feature(nll)] + +trait Trait<'a> { } + +impl Trait<'b> for &'a u32 { } + +fn foo(x: &'x u32) -> impl Trait<'y> +where 'x: 'y +{ + x +} + +fn main() { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs new file mode 100644 index 000000000000..38c18ce61044 --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound.rs @@ -0,0 +1,34 @@ +// 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. + +// Test that we do not allow the region `'x` to escape in the impl +// trait **even though** `'y` escapes, which outlives `'x`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +#![allow(dead_code)] +#![feature(conservative_impl_trait)] +#![feature(in_band_lifetimes)] +#![feature(nll)] + +use std::cell::Cell; + +trait Trait<'a> { } + +impl Trait<'b> for Cell<&'a u32> { } + +fn foo(x: Cell<&'x u32>) -> impl Trait<'y> + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909] +where 'x: 'y +{ + x +} + +fn main() { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr new file mode 100644 index 000000000000..5659fee9bedc --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -0,0 +1,20 @@ +error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds + --> $DIR/region-escape-via-bound.rs:27:29 + | +LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y> + | ^^^^^^^^^^^^^^ + | +note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 27:1 + --> $DIR/region-escape-via-bound.rs:27:1 + | +LL | / fn foo(x: Cell<&'x u32>) -> impl Trait<'y> +LL | | //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909] +LL | | where 'x: 'y +LL | | { +LL | | x +LL | | } + | |_^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0909`. From f71de45b230954c25f2337272852be1146d26136 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 15 Mar 2018 10:49:05 -0400 Subject: [PATCH 464/830] use subtyping when we create a closure instead of for upvar types We used to make the upvar types in the closure `==` but that was stronger than we needed. Subtyping suffices, since we are copying the upvar value into the closure field. This in turn allows us to infer smaller lifetimes in captured values in some cases (like the example here), avoiding errors. --- src/librustc_typeck/check/upvar.rs | 2 +- .../ui/generator/auto-trait-regions.stderr | 6 ++-- ...-escape-via-bound-contravariant-closure.rs | 31 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index ab148afafbe0..4fc3344dab2a 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -217,7 +217,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .upvar_tys(closure_def_id, self.tcx) .zip(final_upvar_tys) { - self.demand_eqtype(span, final_upvar_ty, upvar_ty); + self.demand_suptype(span, upvar_ty, final_upvar_ty); } // If we are also inferred the closure kind here, diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index cd83915fe82d..dd78baf92750 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -1,15 +1,15 @@ -error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` +error[E0277]: the trait bound `No: Foo` is not satisfied in `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` --> $DIR/auto-trait-regions.rs:40:5 | LL | assert_foo(gen); //~ ERROR the trait bound `No: Foo` is not satisfied - | ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No` + | ^^^^^^^^^^ within `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]`, the trait `Foo` is not implemented for `No` | = help: the following implementations were found: = note: required because it appears within the type `OnlyFooIfStaticRef` = note: required because it appears within the type `&OnlyFooIfStaticRef` = note: required because it appears within the type `for<'r> {&'r OnlyFooIfStaticRef, ()}` - = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&'static OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` + = note: required because it appears within the type `[generator@$DIR/auto-trait-regions.rs:35:15: 39:6 x:&&OnlyFooIfStaticRef for<'r> {&'r OnlyFooIfStaticRef, ()}]` note: required by `assert_foo` --> $DIR/auto-trait-regions.rs:30:1 | diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs new file mode 100644 index 000000000000..f554efe90361 --- /dev/null +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs @@ -0,0 +1,31 @@ +// 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. + +// In contrast to `region-escape-via-bound-invariant`, in this case we +// *can* return a value of type `&'x u32`, even though `'x` does not +// appear in the bounds. This is because `&` is contravariant, and so +// we are *actually* returning a `&'y u32`. +// +// See https://github.com/rust-lang/rust/issues/46541 for more details. + +// run-pass + +#![allow(dead_code)] +#![feature(conservative_impl_trait)] +#![feature(in_band_lifetimes)] +#![feature(nll)] + +fn foo(x: &'x u32) -> impl Fn() -> &'y u32 +where 'x: 'y +{ + move || x +} + +fn main() { } From 9d5ec9ef1a03d343d01bde68ed6e6affc32ae492 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 15 Mar 2018 16:17:27 -0400 Subject: [PATCH 465/830] work around fallout from these changes in rustc --- src/librustc/infer/canonical.rs | 3 ++- src/librustc/lib.rs | 1 + .../traits/specialize/specialization_graph.rs | 18 ++++++++++------ src/librustc/ty/mod.rs | 21 ++++++++++++------- src/librustc/ty/sty.rs | 11 ++++++---- src/librustc/util/captures.rs | 18 ++++++++++++++++ src/librustc_metadata/decoder.rs | 6 +++++- src/librustc_typeck/collect.rs | 5 +++-- 8 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 src/librustc/util/captures.rs diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs index 4e0cf59e8a7f..22526c7751d5 100644 --- a/src/librustc/infer/canonical.rs +++ b/src/librustc/infer/canonical.rs @@ -40,6 +40,7 @@ use traits::{Obligation, ObligationCause, PredicateObligation}; use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags}; use ty::subst::{Kind, UnpackedKind}; use ty::fold::{TypeFoldable, TypeFolder}; +use util::captures::Captures; use util::common::CellUsizeExt; use rustc_data_structures::indexed_vec::IndexVec; @@ -382,7 +383,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { param_env: ty::ParamEnv<'tcx>, unsubstituted_region_constraints: &'a QueryRegionConstraints<'tcx>, result_subst: &'a CanonicalVarValues<'tcx>, - ) -> impl Iterator> + 'a { + ) -> impl Iterator> + Captures<'gcx> + 'a { let QueryRegionConstraints { region_outlives, ty_outlives, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 77259f156e5e..22b07c8cc044 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -157,6 +157,7 @@ pub mod traits; pub mod ty; pub mod util { + pub mod captures; pub mod common; pub mod ppaux; pub mod nodemap; diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index e0d662657b7d..e56a8662f3eb 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -19,6 +19,7 @@ use ty::{self, TyCtxt, TypeFoldable}; use ty::fast_reject::{self, SimplifiedType}; use rustc_data_structures::sync::Lrc; use syntax::ast::Name; +use util::captures::Captures; use util::nodemap::{DefIdMap, FxHashMap}; /// A per-trait graph of impls in specialization order. At the moment, this @@ -313,9 +314,10 @@ impl<'a, 'gcx, 'tcx> Node { } /// Iterate over the items defined directly by the given (impl or trait) node. - #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait. - pub fn items(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) - -> impl Iterator + 'a { + pub fn items( + &self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> impl Iterator + 'a { tcx.associated_items(self.def_id()) } @@ -367,9 +369,13 @@ 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. - pub fn defs(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_item_name: Name, - trait_item_kind: ty::AssociatedKind, trait_def_id: DefId) - -> impl Iterator> + 'a { + pub fn defs( + self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + trait_item_name: Name, + trait_item_kind: ty::AssociatedKind, + trait_def_id: DefId, + ) -> impl Iterator> + Captures<'gcx> + Captures<'tcx> + 'a { self.flat_map(move |node| { node.items(tcx).filter(move |impl_item| { impl_item.kind == trait_item_kind && diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c91502235192..95c5cd377d71 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -34,6 +34,7 @@ use ty; use ty::subst::{Subst, Substs}; use ty::util::{IntTypeExt, Discr}; use ty::walk::TypeWalker; +use util::captures::Captures; use util::nodemap::{NodeSet, DefIdMap, FxHashMap}; use serialize::{self, Encodable, Encoder}; @@ -1942,8 +1943,10 @@ impl<'a, 'gcx, 'tcx> AdtDef { } #[inline] - pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>) - -> impl Iterator> + 'a { + pub fn discriminants( + &'a self, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> impl Iterator> + Captures<'gcx> + 'a { let repr_type = self.repr.discr_type(); let initial = repr_type.initial_discriminant(tcx.global_tcx()); let mut prev_discr = None::>; @@ -2290,7 +2293,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns an iterator of the def-ids for all body-owners in this /// crate. If you would prefer to iterate over the bodies /// themselves, you can do `self.hir.krate().body_ids.iter()`. - pub fn body_owners(self) -> impl Iterator + 'a { + pub fn body_owners( + self, + ) -> impl Iterator + Captures<'tcx> + Captures<'gcx> + 'a { self.hir.krate() .body_ids .iter() @@ -2394,11 +2399,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait. - pub fn associated_items(self, def_id: DefId) - -> impl Iterator + 'a { + pub fn associated_items( + self, + def_id: DefId, + ) -> impl Iterator + 'a { let def_ids = self.associated_item_def_ids(def_id); - (0..def_ids.len()).map(move |i| self.associated_item(def_ids[i])) + Box::new((0..def_ids.len()).map(move |i| self.associated_item(def_ids[i]))) + as Box + 'a> } /// Returns true if the impls are the same polarity and are implementing diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index bb5c7b5fd2a5..d7ab6e39ac5f 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -18,6 +18,7 @@ use rustc_data_structures::indexed_vec::Idx; use ty::subst::{Substs, Subst, Kind, UnpackedKind}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{Slice, TyS}; +use util::captures::Captures; use std::iter; use std::cmp::Ordering; @@ -384,9 +385,11 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> { /// This returns the types of the MIR locals which had to be stored across suspension points. /// It is calculated in rustc_mir::transform::generator::StateTransform. /// All the types here must be in the tuple in GeneratorInterior. - pub fn state_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> - impl Iterator> + 'a - { + pub fn state_tys( + self, + def_id: DefId, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> impl Iterator> + Captures<'gcx> + 'a { let state = tcx.generator_layout(def_id).fields.iter(); state.map(move |d| d.ty.subst(tcx, self.substs)) } @@ -403,7 +406,7 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> { /// This is the types of all the fields stored in a generator. /// It includes the upvars, state types and the state discriminant which is u32. pub fn field_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> - impl Iterator> + 'a + impl Iterator> + Captures<'gcx> + 'a { self.pre_transforms_tys(def_id, tcx).chain(self.state_tys(def_id, tcx)) } diff --git a/src/librustc/util/captures.rs b/src/librustc/util/captures.rs new file mode 100644 index 000000000000..b68cfd278fa9 --- /dev/null +++ b/src/librustc/util/captures.rs @@ -0,0 +1,18 @@ +// Copyright 2012-2014 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. + +/// "Signaling" trait used in impl trait to tag lifetimes that you may +/// need to capture but don't really need for other reasons. +/// Basically a workaround; see [this comment] for details. +/// +/// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 +pub trait Captures<'a> { } + +impl<'a, T: ?Sized> Captures<'a> for T { } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index e1c17e8260a7..b0c945fbf2a0 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -29,6 +29,7 @@ use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::codec::TyDecoder; use rustc::mir::Mir; +use rustc::util::captures::Captures; use rustc::util::nodemap::FxHashMap; use std::collections::BTreeMap; @@ -146,7 +147,10 @@ impl<'a, 'tcx: 'a, T: Decodable> Lazy { } impl<'a, 'tcx: 'a, T: Decodable> LazySeq { - pub fn decode>(self, meta: M) -> impl Iterator + 'a { + pub fn decode>( + self, + meta: M, + ) -> impl Iterator + Captures<'tcx> + 'a { let mut dcx = meta.decoder(self.position); dcx.lazy_state = LazyState::NodeStart(self.position); (0..self.len).map(move |_| T::decode(&mut dcx).unwrap()) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a17b35dec42d..6f24d06844bb 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -35,8 +35,9 @@ use rustc::ty::{ToPredicate, ReprOptions}; use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::maps::Providers; use rustc::ty::util::IntTypeExt; -use rustc::util::nodemap::{FxHashSet, FxHashMap}; use rustc::ty::util::Discr; +use rustc::util::captures::Captures; +use rustc::util::nodemap::{FxHashSet, FxHashMap}; use syntax::{abi, ast}; use syntax::ast::MetaItemKind; @@ -1281,7 +1282,7 @@ fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>, fn early_bound_lifetimes_from_generics<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, ast_generics: &'a hir::Generics) - -> impl Iterator + -> impl Iterator + Captures<'tcx> { ast_generics .lifetimes() From 94eebaa32505919a17c0848ad0663d49bcddfa80 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 09:24:32 -0400 Subject: [PATCH 466/830] WIP fix mir-opt-end-region-8 --- src/test/mir-opt/end_region_8.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs index 405864aba943..d621cdb4d58f 100644 --- a/src/test/mir-opt/end_region_8.rs +++ b/src/test/mir-opt/end_region_8.rs @@ -36,7 +36,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _2: &'21_1rs D; // ... // let mut _3: (); -// let mut _4: [closure@NodeId(22) r:&'21_1rs D]; +// let mut _4: [closure@NodeId(22) r:&'19s D]; // let mut _5: &'21_1rs D; // bb0: { // StorageLive(_1); @@ -54,6 +54,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // resume; // } // bb2: { +// EndRegion('19s); // StorageDead(_4); // _0 = (); // EndRegion('21_1rs); @@ -61,6 +62,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // drop(_1) -> [return: bb4, unwind: bb1]; // } // bb3: { +// EndRegion('19s); // EndRegion('21_1rs); // drop(_1) -> bb1; // } @@ -72,7 +74,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'21_1rs D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'19s D]) -> i32 { // let mut _0: i32; // let mut _2: i32; // From 5aa29c4c823cbe02a2d84080eefe3eb1aecf0a06 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 21 Mar 2018 14:34:46 +0100 Subject: [PATCH 467/830] Fix test error --- src/librustc_mir/interpret/const_eval.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 82eb28287b03..47f6f61072e1 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -339,6 +339,14 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator { ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>, cid: GlobalId<'tcx>, ) -> EvalResult<'tcx, AllocId> { + let alloc = ecx + .tcx + .interpret_interner + .get_cached(cid.instance.def_id()); + // Don't evaluate when already cached to prevent cycles + if let Some(alloc) = alloc { + return Ok(alloc) + } // ensure the static is computed ecx.const_eval(cid)?; Ok(ecx From c7bdd371a64ff5b9b86680fd77dd56d1eeabb76c Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 21 Mar 2018 22:03:24 +0800 Subject: [PATCH 468/830] Revert "Apply a fix to travis-ci/dpl#788 manually until dpl 1.9.5 is released." This reverts commit 20e65f11f3bb0538c5676425e74b593676bd0f12. --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index b2aba305aedc..41ea0c9afa87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -318,8 +318,6 @@ before_deploy: deploy: - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -336,8 +334,6 @@ deploy: # this is the same as the above deployment provider except that it uploads to # a slightly different directory and has a different trigger - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -355,8 +351,6 @@ deploy: # try branch. Travis does not appear to provide a way to use "or" in these # conditions. - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy @@ -371,8 +365,6 @@ deploy: condition: $DEPLOY = 1 - provider: s3 - edge: - branch: s3-eager-autoload bucket: rust-lang-ci2 skip_cleanup: true local_dir: deploy From 75dcc61d3c1cce7b4428dd85bb588e99d9faf7a9 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Wed, 21 Mar 2018 23:12:24 +0900 Subject: [PATCH 469/830] Cargo fmt libtest --- src/libtest/formatters/json.rs | 49 ++--- src/libtest/formatters/pretty.rs | 9 +- src/libtest/formatters/terse.rs | 9 +- src/libtest/lib.rs | 325 ++++++++++++++----------------- src/libtest/stats.rs | 23 ++- 5 files changed, 182 insertions(+), 233 deletions(-) diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs index d323d50f702b..89235d897bde 100644 --- a/src/libtest/formatters/json.rs +++ b/src/libtest/formatters/json.rs @@ -36,17 +36,12 @@ impl JsonFormatter { if let Some(extras) = extra { self.write_message(&*format!( r#"{{ "type": "{}", "name": "{}", "event": "{}", {} }}"#, - ty, - name, - evt, - extras + ty, name, evt, extras )) } else { self.write_message(&*format!( r#"{{ "type": "{}", "name": "{}", "event": "{}" }}"#, - ty, - name, - evt + ty, name, evt )) } } @@ -89,14 +84,12 @@ impl OutputFormatter for JsonFormatter { self.write_event("test", desc.name.as_slice(), "failed", extra_data) } - TrFailedMsg(ref m) => { - self.write_event( - "test", - desc.name.as_slice(), - "failed", - Some(format!(r#""message": "{}""#, EscapedString(m))), - ) - } + TrFailedMsg(ref m) => self.write_event( + "test", + desc.name.as_slice(), + "failed", + Some(format!(r#""message": "{}""#, EscapedString(m))), + ), TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", None), @@ -116,13 +109,10 @@ impl OutputFormatter for JsonFormatter { let line = format!( "{{ \"type\": \"bench\", \ - \"name\": \"{}\", \ - \"median\": {}, \ - \"deviation\": {}{} }}", - desc.name, - median, - deviation, - mbps + \"name\": \"{}\", \ + \"median\": {}, \ + \"deviation\": {}{} }}", + desc.name, median, deviation, mbps ); self.write_message(&*line) @@ -138,16 +128,15 @@ impl OutputFormatter for JsonFormatter { } fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result { - self.write_message(&*format!( "{{ \"type\": \"suite\", \ - \"event\": \"{}\", \ - \"passed\": {}, \ - \"failed\": {}, \ - \"allowed_fail\": {}, \ - \"ignored\": {}, \ - \"measured\": {}, \ - \"filtered_out\": \"{}\" }}", + \"event\": \"{}\", \ + \"passed\": {}, \ + \"failed\": {}, \ + \"allowed_fail\": {}, \ + \"ignored\": {}, \ + \"measured\": {}, \ + \"filtered_out\": \"{}\" }}", if state.failed == 0 { "ok" } else { "failed" }, state.passed, state.failed + state.allowed_fail, diff --git a/src/libtest/formatters/pretty.rs b/src/libtest/formatters/pretty.rs index f2064deefce6..8e5fa00b5f27 100644 --- a/src/libtest/formatters/pretty.rs +++ b/src/libtest/formatters/pretty.rs @@ -196,8 +196,7 @@ impl OutputFormatter for PrettyFormatter { self.write_plain(&format!( "test {} has been running for over {} seconds\n", - desc.name, - TEST_WARN_TIMEOUT_S + desc.name, TEST_WARN_TIMEOUT_S )) } @@ -232,11 +231,7 @@ impl OutputFormatter for PrettyFormatter { } else { format!( ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n", - state.passed, - state.failed, - state.ignored, - state.measured, - state.filtered_out + state.passed, state.failed, state.ignored, state.measured, state.filtered_out ) }; diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs index 88689485144c..85286027d692 100644 --- a/src/libtest/formatters/terse.rs +++ b/src/libtest/formatters/terse.rs @@ -195,8 +195,7 @@ impl OutputFormatter for TerseFormatter { fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> { self.write_plain(&format!( "test {} has been running for over {} seconds\n", - desc.name, - TEST_WARN_TIMEOUT_S + desc.name, TEST_WARN_TIMEOUT_S )) } @@ -231,11 +230,7 @@ impl OutputFormatter for TerseFormatter { } else { format!( ". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n", - state.passed, - state.failed, - state.ignored, - state.measured, - state.filtered_out + state.passed, state.failed, state.ignored, state.measured, state.filtered_out ) }; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 59d701dd0fbc..b8be1aeff174 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -30,10 +30,8 @@ #![unstable(feature = "test", issue = "27812")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/", - test(attr(deny(warnings))))] + html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))] #![deny(warnings)] - #![feature(asm)] #![feature(fnbox)] #![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))] @@ -43,10 +41,10 @@ #![feature(termination_trait_lib)] extern crate getopts; -extern crate term; #[cfg(any(unix, target_os = "cloudabi"))] extern crate libc; extern crate panic_unwind; +extern crate term; pub use self::TestFn::*; pub use self::ColorConfig::*; @@ -72,7 +70,7 @@ use std::process::Termination; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::thread; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; use std::borrow::Cow; use std::process; @@ -81,16 +79,16 @@ const QUIET_MODE_MAX_COLUMN: usize = 100; // insert a '\n' after 100 tests in qu // to be used by rustc to compile tests in libtest pub mod test { - pub use {Bencher, TestName, TestResult, TestDesc, TestDescAndFn, TestOpts, TrFailed, - TrFailedMsg, TrIgnored, TrOk, Metric, MetricMap, StaticTestFn, StaticTestName, - DynTestName, DynTestFn, assert_test_result, run_test, test_main, test_main_static, - filter_tests, parse_opts, StaticBenchFn, ShouldPanic, Options}; + pub use {assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, + Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, ShouldPanic, + StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, + TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk}; } pub mod stats; mod formatters; -use formatters::{OutputFormatter, PrettyFormatter, TerseFormatter, JsonFormatter}; +use formatters::{JsonFormatter, OutputFormatter, PrettyFormatter, TerseFormatter}; // The name of a test. By convention this follows the rules for rust // paths; i.e. it should be a series of identifiers separated by double @@ -255,7 +253,9 @@ pub struct Options { impl Options { pub fn new() -> Options { - Options { display_output: false } + Options { + display_output: false, + } } pub fn display_output(mut self, display_output: bool) -> Options { @@ -272,7 +272,7 @@ pub fn test_main(args: &[String], tests: Vec, options: Options) { Some(Err(msg)) => { eprintln!("error: {}", msg); process::exit(101); - }, + } None => return, }; @@ -289,7 +289,7 @@ pub fn test_main(args: &[String], tests: Vec, options: Options) { Err(e) => { eprintln!("error: io error when listing tests: {:?}", e); process::exit(101); - }, + } } } } @@ -306,18 +306,14 @@ pub fn test_main_static(tests: &[TestDescAndFn]) { let owned_tests = tests .iter() .map(|t| match t.testfn { - StaticTestFn(f) => { - TestDescAndFn { - testfn: StaticTestFn(f), - desc: t.desc.clone(), - } - } - StaticBenchFn(f) => { - TestDescAndFn { - testfn: StaticBenchFn(f), - desc: t.desc.clone(), - } - } + StaticTestFn(f) => TestDescAndFn { + testfn: StaticTestFn(f), + desc: t.desc.clone(), + }, + StaticBenchFn(f) => TestDescAndFn { + testfn: StaticBenchFn(f), + desc: t.desc.clone(), + }, _ => panic!("non-static tests passed to test::test_main_static"), }) .collect(); @@ -397,34 +393,34 @@ fn optgroups() -> getopts::Options { "", "logfile", "Write logs to the specified file instead \ - of stdout", + of stdout", "PATH", ) .optflag( "", "nocapture", "don't capture stdout/stderr of each \ - task, allow printing directly", + task, allow printing directly", ) .optopt( "", "test-threads", "Number of threads used for running tests \ - in parallel", + in parallel", "n_threads", ) .optmulti( "", "skip", "Skip tests whose names contain FILTER (this flag can \ - be used multiple times)", + be used multiple times)", "FILTER", ) .optflag( "q", "quiet", "Display one character per test instead of one line. \ - Alias to --format=terse", + Alias to --format=terse", ) .optflag( "", @@ -516,8 +512,7 @@ pub fn parse_opts(args: &[String]) -> Option { if let Some(opt) = matches.opt_str("Z") { if !is_nightly() { return Some(Err( - "the option `Z` is only accepted on the nightly compiler" - .into(), + "the option `Z` is only accepted on the nightly compiler".into(), )); } @@ -562,19 +557,17 @@ pub fn parse_opts(args: &[String]) -> Option { } let test_threads = match matches.opt_str("test-threads") { - Some(n_str) => { - match n_str.parse::() { - Ok(0) => return Some(Err(format!("argument for --test-threads must not be 0"))), - Ok(n) => Some(n), - Err(e) => { - return Some(Err(format!( - "argument for --test-threads must be a number > 0 \ - (error: {})", - e - ))) - } + Some(n_str) => match n_str.parse::() { + Ok(0) => return Some(Err(format!("argument for --test-threads must not be 0"))), + Ok(n) => Some(n), + Err(e) => { + return Some(Err(format!( + "argument for --test-threads must be a number > 0 \ + (error: {})", + e + ))) } - } + }, None => None, }; @@ -586,7 +579,7 @@ pub fn parse_opts(args: &[String]) -> Option { Some(v) => { return Some(Err(format!( "argument for --color must be auto, always, or never (was \ - {})", + {})", v ))) } @@ -599,8 +592,7 @@ pub fn parse_opts(args: &[String]) -> Option { Some("json") => { if !allow_unstable { return Some(Err( - "The \"json\" format is only accepted on the nightly compiler" - .into(), + "The \"json\" format is only accepted on the nightly compiler".into(), )); } OutputFormat::Json @@ -609,7 +601,7 @@ pub fn parse_opts(args: &[String]) -> Option { Some(v) => { return Some(Err(format!( "argument for --format must be pretty, terse, or json (was \ - {})", + {})", v ))) } @@ -811,8 +803,7 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec) -> io::Res ntest += 1; "test" } - StaticBenchFn(..) | - DynBenchFn(..) => { + StaticBenchFn(..) | DynBenchFn(..) => { nbench += 1; "benchmark" } @@ -834,7 +825,8 @@ pub fn list_tests_console(opts: &TestOpts, tests: Vec) -> io::Res writeln!(output, "")?; } - writeln!(output, + writeln!( + output, "{}, {}", plural(ntest, "test"), plural(nbench, "benchmark") @@ -851,7 +843,6 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec) -> io::Resu st: &mut ConsoleTestState, out: &mut OutputFormatter, ) -> io::Result<()> { - match (*event).clone() { TeFiltered(ref filtered_tests) => { st.total = filtered_tests.len(); @@ -989,8 +980,7 @@ fn use_color(opts: &TestOpts) -> bool { } } -#[cfg(any(target_os = "cloudabi", - target_os = "redox", +#[cfg(any(target_os = "cloudabi", target_os = "redox", all(target_arch = "wasm32", not(target_os = "emscripten"))))] fn stdout_isatty() -> bool { // FIXME: Implement isatty on Redox @@ -1089,10 +1079,12 @@ where let now = Instant::now(); let timed_out = running_tests .iter() - .filter_map(|(desc, timeout)| if &now >= timeout { - Some(desc.clone()) - } else { - None + .filter_map(|(desc, timeout)| { + if &now >= timeout { + Some(desc.clone()) + } else { + None + } }) .collect(); for test in &timed_out { @@ -1174,12 +1166,10 @@ fn get_concurrency() -> usize { let opt_n: Option = s.parse().ok(); match opt_n { Some(n) if n > 0 => n, - _ => { - panic!( - "RUST_TEST_THREADS is `{}`, should be a positive integer.", - s - ) - } + _ => panic!( + "RUST_TEST_THREADS is `{}`, should be a positive integer.", + s + ), } } Err(..) => num_cpus(), @@ -1223,20 +1213,15 @@ fn get_concurrency() -> usize { 1 } - #[cfg(any(target_os = "android", - target_os = "cloudabi", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "solaris"))] + #[cfg(any(target_os = "android", target_os = "cloudabi", target_os = "emscripten", + target_os = "fuchsia", target_os = "ios", target_os = "linux", + target_os = "macos", target_os = "solaris"))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } } #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "bitrig", - target_os = "netbsd"))] + target_os = "netbsd"))] fn num_cpus() -> usize { use std::ptr; @@ -1308,26 +1293,28 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec filtered, - Some(ref filter) => { - filtered - .into_iter() - .filter(|test| if opts.filter_exact { + Some(ref filter) => filtered + .into_iter() + .filter(|test| { + if opts.filter_exact { test.desc.name.as_slice() == &filter[..] } else { test.desc.name.as_slice().contains(&filter[..]) - }) - .collect() - } + } + }) + .collect(), }; // Skip tests that match any of the skip filters filtered = filtered .into_iter() .filter(|t| { - !opts.skip.iter().any(|sf| if opts.filter_exact { - t.desc.name.as_slice() == &sf[..] - } else { - t.desc.name.as_slice().contains(&sf[..]) + !opts.skip.iter().any(|sf| { + if opts.filter_exact { + t.desc.name.as_slice() == &sf[..] + } else { + t.desc.name.as_slice().contains(&sf[..]) + } }) }) .collect(); @@ -1354,31 +1341,23 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec) -> Vec { // convert benchmarks to tests, if we're not benchmarking them - tests.into_iter().map(|x| { - let testfn = match x.testfn { - DynBenchFn(bench) => { - DynTestFn(Box::new(move || { - bench::run_once(|b| { - __rust_begin_short_backtrace(|| bench.run(b)) - }) - })) - } - StaticBenchFn(benchfn) => { - DynTestFn(Box::new(move || { - bench::run_once(|b| { - __rust_begin_short_backtrace(|| benchfn(b)) - }) - })) - } + tests + .into_iter() + .map(|x| { + let testfn = match x.testfn { + DynBenchFn(bench) => DynTestFn(Box::new(move || { + bench::run_once(|b| __rust_begin_short_backtrace(|| bench.run(b))) + })), + StaticBenchFn(benchfn) => DynTestFn(Box::new(move || { + bench::run_once(|b| __rust_begin_short_backtrace(|| benchfn(b))) + })), f => f, }; TestDescAndFn { @@ -1395,22 +1374,22 @@ pub fn run_test( test: TestDescAndFn, monitor_ch: Sender, ) { - let TestDescAndFn { desc, testfn } = test; - let ignore_because_panic_abort = cfg!(target_arch = "wasm32") && - !cfg!(target_os = "emscripten") && - desc.should_panic != ShouldPanic::No; + let ignore_because_panic_abort = cfg!(target_arch = "wasm32") && !cfg!(target_os = "emscripten") + && desc.should_panic != ShouldPanic::No; if force_ignore || desc.ignore || ignore_because_panic_abort { monitor_ch.send((desc, TrIgnored, Vec::new())).unwrap(); return; } - fn run_test_inner(desc: TestDesc, - monitor_ch: Sender, - nocapture: bool, - testfn: Box) { + fn run_test_inner( + desc: TestDesc, + monitor_ch: Sender, + nocapture: bool, + testfn: Box, + ) { // Buffer for capturing standard I/O let data = Arc::new(Mutex::new(Vec::new())); let data2 = data.clone(); @@ -1440,7 +1419,6 @@ pub fn run_test( .unwrap(); }; - // If the platform is single-threaded we're just going to run // the test synchronously, regardless of the concurrency // level. @@ -1455,27 +1433,25 @@ pub fn run_test( match testfn { DynBenchFn(bencher) => { - ::bench::benchmark(desc, - monitor_ch, - opts.nocapture, - |harness| bencher.run(harness)); + ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { + bencher.run(harness) + }); } StaticBenchFn(benchfn) => { - ::bench::benchmark(desc, - monitor_ch, - opts.nocapture, - |harness| (benchfn.clone())(harness)); + ::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { + (benchfn.clone())(harness) + }); } DynTestFn(f) => { - let cb = move || { - __rust_begin_short_backtrace(f) - }; + let cb = move || __rust_begin_short_backtrace(f); run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb)) } - StaticTestFn(f) => { - run_test_inner(desc, monitor_ch, opts.nocapture, - Box::new(move || __rust_begin_short_backtrace(f))) - } + StaticTestFn(f) => run_test_inner( + desc, + monitor_ch, + opts.nocapture, + Box::new(move || __rust_begin_short_backtrace(f)), + ), } } @@ -1487,8 +1463,7 @@ fn __rust_begin_short_backtrace(f: F) { fn calc_result(desc: &TestDesc, task_result: Result<(), Box>) -> TestResult { match (&desc.should_panic, task_result) { - (&ShouldPanic::No, Ok(())) | - (&ShouldPanic::Yes, Err(_)) => TrOk, + (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TrOk, (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => { if err.downcast_ref::() .map(|e| &**e) @@ -1545,7 +1520,6 @@ impl MetricMap { } } - // Benchmarking /// A function that is opaque to the optimizer, to allow benchmarks to @@ -1566,7 +1540,6 @@ pub fn black_box(dummy: T) -> T { dummy } - impl Bencher { /// Callback for benchmark functions to run in their body. pub fn iter(&mut self, mut inner: F) @@ -1605,7 +1578,6 @@ where return ns_from_dur(start.elapsed()); } - pub fn iter(inner: &mut F) -> stats::Summary where F: FnMut() -> T, @@ -1649,8 +1621,8 @@ where // If we've run for 100ms and seem to have converged to a // stable median. - if loop_run > Duration::from_millis(100) && summ.median_abs_dev_pct < 1.0 && - summ.median - summ5.median < summ5.median_abs_dev + if loop_run > Duration::from_millis(100) && summ.median_abs_dev_pct < 1.0 + && summ.median - summ5.median < summ5.median_abs_dev { return summ5; } @@ -1680,7 +1652,7 @@ pub mod bench { use std::io; use std::sync::{Arc, Mutex}; use stats; - use super::{Bencher, BenchSamples, BenchMode, Sink, MonitorMsg, TestDesc, Sender, TestResult}; + use super::{BenchMode, BenchSamples, Bencher, MonitorMsg, Sender, Sink, TestDesc, TestResult}; pub fn benchmark(desc: TestDesc, monitor_ch: Sender, nocapture: bool, f: F) where @@ -1711,7 +1683,8 @@ pub mod bench { io::set_panic(panicio); }; - let test_result = match result { //bs.bench(f) { + let test_result = match result { + //bs.bench(f) { Ok(Some(ns_iter_summ)) => { let ns_iter = cmp::max(ns_iter_summ.median as u64, 1); let mb_s = bs.bytes * 1000 / ns_iter; @@ -1732,9 +1705,7 @@ pub mod bench { }; TestResult::TrBench(bs) } - Err(_) => { - TestResult::TrFailed - } + Err(_) => TestResult::TrFailed, }; let stdout = data.lock().unwrap().to_vec(); @@ -1756,9 +1727,9 @@ pub mod bench { #[cfg(test)] mod tests { - use test::{TrFailed, TrFailedMsg, TrIgnored, TrOk, filter_tests, parse_opts, TestDesc, - TestDescAndFn, TestOpts, run_test, MetricMap, StaticTestName, DynTestName, - DynTestFn, ShouldPanic}; + use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, ShouldPanic, + StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg, + TrIgnored, TrOk}; use std::sync::mpsc::channel; use bench; use Bencher; @@ -1904,25 +1875,26 @@ mod tests { opts.run_tests = true; opts.run_ignored = true; - let tests = - vec![TestDescAndFn { - desc: TestDesc { - name: StaticTestName("1"), - ignore: true, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})), - }, - TestDescAndFn { - desc: TestDesc { - name: StaticTestName("2"), - ignore: false, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})), - }]; + let tests = vec![ + TestDescAndFn { + desc: TestDesc { + name: StaticTestName("1"), + ignore: true, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }, + TestDescAndFn { + desc: TestDesc { + name: StaticTestName("2"), + ignore: false, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }, + ]; let filtered = filter_tests(&opts, tests); assert_eq!(filtered.len(), 1); @@ -1935,17 +1907,16 @@ mod tests { fn tests() -> Vec { vec!["base", "base::test", "base::test1", "base::test2"] .into_iter() - .map(|name| { - TestDescAndFn { - desc: TestDesc { - name: StaticTestName(name), - ignore: false, - should_panic: ShouldPanic::No, - allow_fail: false, - }, - testfn: DynTestFn(Box::new(move || {})) - } - }).collect() + .map(|name| TestDescAndFn { + desc: TestDesc { + name: StaticTestName(name), + ignore: false, + should_panic: ShouldPanic::No, + allow_fail: false, + }, + testfn: DynTestFn(Box::new(move || {})), + }) + .collect() } let substr = filter_tests( @@ -2127,10 +2098,7 @@ mod tests { allow_fail: false, }; - ::bench::benchmark(desc, - tx, - true, - f); + ::bench::benchmark(desc, tx, true, f); rx.recv().unwrap(); } @@ -2149,10 +2117,7 @@ mod tests { allow_fail: false, }; - ::bench::benchmark(desc, - tx, - true, - f); + ::bench::benchmark(desc, tx, true, f); rx.recv().unwrap(); } } diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index e22fdf77fc17..ddb5dcf2a1cd 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -279,7 +279,6 @@ impl Stats for [f64] { } } - // Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using // linear interpolation. If samples are not sorted, return nonsensical value. fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 { @@ -304,7 +303,6 @@ fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 { lo + (hi - lo) * d } - /// Winsorize a set of samples, replacing values above the `100-pct` percentile /// and below the `pct` percentile with those percentiles themselves. This is a /// way of minimizing the effect of outliers, at the cost of biasing the sample. @@ -338,15 +336,18 @@ mod tests { use std::io; macro_rules! assert_approx_eq { - ($a:expr, $b:expr) => ({ + ($a: expr, $b: expr) => {{ let (a, b) = (&$a, &$b); - assert!((*a - *b).abs() < 1.0e-6, - "{} is not approximately equal to {}", *a, *b); - }) + assert!( + (*a - *b).abs() < 1.0e-6, + "{} is not approximately equal to {}", + *a, + *b + ); + }}; } fn check(samples: &[f64], summ: &Summary) { - let summ2 = Summary::new(samples); let mut w = io::sink(); @@ -911,14 +912,18 @@ mod bench { #[bench] pub fn sum_three_items(b: &mut Bencher) { - b.iter(|| { [1e20f64, 1.5f64, -1e20f64].sum(); }) + b.iter(|| { + [1e20f64, 1.5f64, -1e20f64].sum(); + }) } #[bench] pub fn sum_many_f64(b: &mut Bencher) { let nums = [-1e30f64, 1e60, 1e30, 1.0, -1e60]; let v = (0..500).map(|i| nums[i % 5]).collect::>(); - b.iter(|| { v.sum(); }) + b.iter(|| { + v.sum(); + }) } #[bench] From b996f9d60fdb1db6bd870fc7f600be4c7660f3a2 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 21 Mar 2018 09:52:18 -0500 Subject: [PATCH 470/830] review comments --- src/doc/rustdoc/src/unstable-features.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index ac69cc1007d8..16356c20c706 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -33,7 +33,7 @@ extern { fn some_func(x: T); } This is used by the error index to ensure that the samples that correspond to a given error number properly emit that error code. However, these error codes aren't guaranteed to be the only thing -that a piece of code emits from version to version, so this in unlikely to be stabilized in the +that a piece of code emits from version to version, so this is unlikely to be stabilized in the future. Attempting to use these error numbers on stable will result in the code sample being interpreted as @@ -134,9 +134,9 @@ pub struct UnixToken; In this sample, the tokens will only appear on their respective platforms, but they will both appear in documentation. -`#[doc(cfg(...))]` was introduced to be used by the standard library and is currently controlled by -a feature gate. For more information, see [its chapter in the Unstable Book][unstable-doc-cfg] and -[its tracking issue][issue-doc-cfg]. +`#[doc(cfg(...))]` was introduced to be used by the standard library and currently requires the +`#![feature(doc_cfg)]` feature gate. For more information, see [its chapter in the Unstable +Book][unstable-doc-cfg] and [its tracking issue][issue-doc-cfg]. [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781 @@ -155,8 +155,9 @@ In the standard library, the traits that qualify for inclusion are `Iterator`, ` special marker attribute on them: `#[doc(spotlight)]`. This means that you could apply this attribute to your own trait to include it in the "Important Traits" dialog in documentation. -The `#[doc(spotlight)]` attribute is controlled by a feature gate. For more information, see [its -chapter in the Unstable Book][unstable-spotlight] and [its tracking issue][issue-spotlight]. +The `#[doc(spotlight)]` attribute currently requires the `#![feature(doc_spotlight)]` feature gate. +For more information, see [its chapter in the Unstable Book][unstable-spotlight] and [its tracking +issue][issue-spotlight]. [unstable-spotlight]: ../unstable-book/language-features/doc-spotlight.html [issue-spotlight]: https://github.com/rust-lang/rust/issues/45040 @@ -174,9 +175,9 @@ To prevent internal types from being included in documentation, the standard lib attribute to their `extern crate` declarations: `#[doc(masked)]`. This causes Rustdoc to "mask out" types from these crates when building lists of trait implementations. -The `#[doc(masked)]` attribute is intended to be used internally, and is controlled by a feature -gate. For more information, see [its chapter in the Unstable Book][unstable-masked] and [its -tracking issue][issue-masked]. +The `#[doc(masked)]` attribute is intended to be used internally, and requires the +`#![feature(doc_masked)]` feature gate. For more information, see [its chapter in the Unstable +Book][unstable-masked] and [its tracking issue][issue-masked]. [unstable-masked]: ../unstable-book/language-features/doc-masked.html [issue-masked]: https://github.com/rust-lang/rust/issues/44027 @@ -191,8 +192,9 @@ as if it were written inline. [RFC 1990]: https://github.com/rust-lang/rfcs/pull/1990 -`#[doc(include = "...")]` is currently controlled by a feature gate. For more information, see [its -chapter in the Unstable Book][unstable-include] and [its tracking issue][issue-include]. +`#[doc(include = "...")]` currently requires the `#![feature(external_doc)]` feature gate. For more +information, see [its chapter in the Unstable Book][unstable-include] and [its tracking +issue][issue-include]. [unstable-include]: ../unstable-book/language-features/external-doc.html [issue-include]: https://github.com/rust-lang/rust/issues/44732 From c09b9f937250db0f51b705a3110f8cffdad083bb Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sat, 17 Mar 2018 12:15:24 +0100 Subject: [PATCH 471/830] Deprecate the AsciiExt trait in favor of inherent methods The trait and some of its methods are stable and will remain. Some of the newer methods are unstable and can be removed later. Fixes https://github.com/rust-lang/rust/issues/39658 --- src/libcore/tests/ascii.rs | 3 --- src/libstd/ascii.rs | 17 +++++++++++++++++ src/libstd/sys/windows/process.rs | 1 - src/libstd/sys_common/wtf8.rs | 17 +++++++---------- src/test/run-pass/issue-10683.rs | 2 -- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs index 4d43067ad2cf..950222dbcfa3 100644 --- a/src/libcore/tests/ascii.rs +++ b/src/libcore/tests/ascii.rs @@ -9,7 +9,6 @@ // except according to those terms. use core::char::from_u32; -use std::ascii::AsciiExt; #[test] fn test_is_ascii() { @@ -143,8 +142,6 @@ macro_rules! assert_all { stringify!($what), b); } } - assert!($str.$what()); - assert!($str.as_bytes().$what()); )+ }}; ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+)) diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 0837ff91c142..6472edb0aa7d 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -52,6 +52,7 @@ pub use core::ascii::{EscapeDefault, escape_default}; /// /// [combining character]: https://en.wikipedia.org/wiki/Combining_character #[stable(feature = "rust1", since = "1.0.0")] +#[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] pub trait AsciiExt { /// Container type for copied ASCII characters. #[stable(feature = "rust1", since = "1.0.0")] @@ -84,6 +85,7 @@ pub trait AsciiExt { /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase /// [`str::to_uppercase`]: ../primitive.str.html#method.to_uppercase #[stable(feature = "rust1", since = "1.0.0")] + #[allow(deprecated)] fn to_ascii_uppercase(&self) -> Self::Owned; /// Makes a copy of the value in its ASCII lower case equivalent. @@ -104,6 +106,7 @@ pub trait AsciiExt { /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase /// [`str::to_lowercase`]: ../primitive.str.html#method.to_lowercase #[stable(feature = "rust1", since = "1.0.0")] + #[allow(deprecated)] fn to_ascii_lowercase(&self) -> Self::Owned; /// Checks that two values are an ASCII case-insensitive match. @@ -162,6 +165,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_alphabetic(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII uppercase character: @@ -174,6 +178,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_uppercase(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII lowercase character: @@ -186,6 +191,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_lowercase(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII alphanumeric character: @@ -199,6 +205,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_alphanumeric(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII decimal digit: @@ -211,6 +218,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_digit(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII hexadecimal digit: @@ -224,6 +232,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_hexdigit(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII punctuation character: @@ -241,6 +250,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_punctuation(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII graphic character: @@ -253,6 +263,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_graphic(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII whitespace character: @@ -282,6 +293,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_whitespace(&self) -> bool { unimplemented!(); } /// Checks if the value is an ASCII control character: @@ -294,6 +306,7 @@ pub trait AsciiExt { /// This method will be deprecated in favor of the identically-named /// inherent methods on `u8`, `char`, `[u8]` and `str`. #[unstable(feature = "ascii_ctype", issue = "39658")] + #[rustc_deprecated(since = "1.26.0", reason = "use inherent methods instead")] fn is_ascii_control(&self) -> bool { unimplemented!(); } } @@ -354,6 +367,7 @@ macro_rules! delegating_ascii_ctype_methods { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for u8 { type Owned = u8; @@ -362,6 +376,7 @@ impl AsciiExt for u8 { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for char { type Owned = char; @@ -370,6 +385,7 @@ impl AsciiExt for char { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for [u8] { type Owned = Vec; @@ -427,6 +443,7 @@ impl AsciiExt for [u8] { } #[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated)] impl AsciiExt for str { type Owned = String; diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index f1ab9c476096..afa8e3e13693 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -10,7 +10,6 @@ #![unstable(feature = "process_internals", issue = "0")] -use ascii::AsciiExt; use collections::BTreeMap; use env::split_paths; use env; diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 9fff8b91f96f..78b2bb5fe6e2 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -27,7 +27,6 @@ use core::str::next_code_point; -use ascii::*; use borrow::Cow; use char; use fmt; @@ -871,24 +870,22 @@ impl Hash for Wtf8 { } } -impl AsciiExt for Wtf8 { - type Owned = Wtf8Buf; - - fn is_ascii(&self) -> bool { +impl Wtf8 { + pub fn is_ascii(&self) -> bool { self.bytes.is_ascii() } - fn to_ascii_uppercase(&self) -> Wtf8Buf { + pub fn to_ascii_uppercase(&self) -> Wtf8Buf { Wtf8Buf { bytes: self.bytes.to_ascii_uppercase() } } - fn to_ascii_lowercase(&self) -> Wtf8Buf { + pub fn to_ascii_lowercase(&self) -> Wtf8Buf { Wtf8Buf { bytes: self.bytes.to_ascii_lowercase() } } - fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool { + pub fn eq_ignore_ascii_case(&self, other: &Wtf8) -> bool { self.bytes.eq_ignore_ascii_case(&other.bytes) } - fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() } - fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() } + pub fn make_ascii_uppercase(&mut self) { self.bytes.make_ascii_uppercase() } + pub fn make_ascii_lowercase(&mut self) { self.bytes.make_ascii_lowercase() } } #[cfg(test)] diff --git a/src/test/run-pass/issue-10683.rs b/src/test/run-pass/issue-10683.rs index eb2177202a22..d3ba477fa573 100644 --- a/src/test/run-pass/issue-10683.rs +++ b/src/test/run-pass/issue-10683.rs @@ -10,8 +10,6 @@ // pretty-expanded FIXME #23616 -use std::ascii::AsciiExt; - static NAME: &'static str = "hello world"; fn main() { From 4b673249f86604ad33d51ad9d8c7744dc5ad341b Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 21 Mar 2018 18:01:51 +0000 Subject: [PATCH 472/830] Fix type_dependent_defs ICE on method calls --- src/librustc_passes/rvalue_promotion.rs | 12 ++++++++---- .../type-dependent-def-issue-49241.rs | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/test/compile-fail/type-dependent-def-issue-49241.rs diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 356ad9ec11bb..76cbc6709698 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -373,10 +373,14 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } hir::ExprMethodCall(..) => { - let def_id = v.tables.type_dependent_defs()[e.hir_id].def_id(); - match v.tcx.associated_item(def_id).container { - ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty), - ty::TraitContainer(_) => v.promotable = false + if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) { + let def_id = def.def_id(); + match v.tcx.associated_item(def_id).container { + ty::ImplContainer(_) => v.handle_const_fn_call(def_id, node_ty), + ty::TraitContainer(_) => v.promotable = false + } + } else { + v.tcx.sess.delay_span_bug(e.span, "no type-dependent def for method call"); } } hir::ExprStruct(..) => { diff --git a/src/test/compile-fail/type-dependent-def-issue-49241.rs b/src/test/compile-fail/type-dependent-def-issue-49241.rs new file mode 100644 index 000000000000..64264999fd2f --- /dev/null +++ b/src/test/compile-fail/type-dependent-def-issue-49241.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let v = vec![0]; + const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item + let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error +} From b6934c91b23517c4e17d8016b6c46ffd0703eded Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 13:32:46 -0500 Subject: [PATCH 473/830] termination_trait: Put examples in error help, not label --- src/librustc/traits/error_reporting.rs | 23 +++++++++++-------- src/libstd/process.rs | 2 +- .../termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 4 ++-- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7e5dc02798df..8572c4077142 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -585,20 +585,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref.to_predicate(), post_message) })); + let explanation = match obligation.cause.code { + ObligationCauseCode::MainFunctionType => { + "consider using `()`, or a `Result`".to_owned() + } + _ => { + format!("{}the trait `{}` is not implemented for `{}`", + pre_message, + trait_ref, + trait_ref.self_ty()) + } + }; + if let Some(ref s) = label { // If it has a custom "#[rustc_on_unimplemented]" // error message, let's display it as the label! err.span_label(span, s.as_str()); - err.help(&format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty())); + err.help(&explanation); } else { - err.span_label(span, - &*format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty())); + err.span_label(span, explanation); } if let Some(ref s) = note { // If it has a custom "#[rustc_on_unimplemented]" note, let's display it diff --git a/src/libstd/process.rs b/src/libstd/process.rs index a6aa3502f26b..d5ac2d19e831 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1443,7 +1443,7 @@ pub fn id() -> u32 { #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] #[rustc_on_unimplemented = - "`main` can only return types like `()` that implement {Termination}, not `{Self}`"] + "`main` can only return types that implement {Termination}, not `{Self}`"] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 053d6bbf93a2..2cf9fdcfb4db 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -10,6 +10,6 @@ fn main() -> i32 { //~^ ERROR `i32: std::process::Termination` is not satisfied -//~| NOTE `main` can only return types like `()` that implement std::process::Termination, not `i32` +//~| NOTE `main` can only return types that implement std::process::Termination, not `i32` 0 } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index 24371c27742d..211247757cbc 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -2,9 +2,9 @@ error[E0277]: the trait bound `char: std::process::Termination` is not satisfied --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types like `()` that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types that implement std::process::Termination, not `char` | - = help: the trait `std::process::Termination` is not implemented for `char` + = help: consider using `()`, or a `Result` error: aborting due to previous error From 178652a2988d9ecd478a4116237e1d7ea6b777f7 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Mar 2018 02:06:38 +0000 Subject: [PATCH 474/830] Add support to rustbuild for a 'rustc docs' component tarball --- src/bootstrap/builder.rs | 12 ++-- src/bootstrap/dist.rs | 69 ++++++++++++++++++-- src/bootstrap/doc.rs | 137 ++++++++++++++++++++++++++++++--------- src/bootstrap/lib.rs | 5 ++ 4 files changed, 180 insertions(+), 43 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 675d3dd437ee..9f779da6f65b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -316,11 +316,13 @@ impl<'a> Builder<'a> { test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, - doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, - doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook), - Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts, - dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo, - dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign), + doc::Standalone, doc::Std, doc::Test, doc::WhitelistedRustc, doc::Rustc, + doc::ErrorIndex, doc::Nomicon, doc::Reference, doc::Rustdoc, doc::RustByExample, + doc::CargoBook), + Kind::Dist => describe!(dist::Docs, dist::RustcDocs, dist::Mingw, dist::Rustc, + dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src, + dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Rustfmt, dist::Extended, + dist::HashSign), Kind::Install => describe!(install::Docs, install::Std, install::Cargo, install::Rls, install::Rustfmt, install::Analysis, install::Src, install::Rustc), } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index dcb572416594..e25a7e185258 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -102,7 +102,7 @@ impl Step for Docs { let dst = image.join("share/doc/rust/html"); t!(fs::create_dir_all(&dst)); - let src = build.out.join(host).join("doc"); + let src = build.doc_out(host); cp_r(&src, &dst); let mut cmd = rust_installer(builder); @@ -120,14 +120,69 @@ impl Step for Docs { build.run(&mut cmd); t!(fs::remove_dir_all(&image)); - // As part of this step, *also* copy the docs directory to a directory which - // buildbot typically uploads. - if host == build.build { - let dst = distdir(build).join("doc").join(build.rust_package_vers()); - t!(fs::create_dir_all(&dst)); - cp_r(&src, &dst); + distdir(build).join(format!("{}-{}.tar.gz", name, host)) + } +} + +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RustcDocs { + pub stage: u32, + pub host: Interned, +} + +impl Step for RustcDocs { + type Output = PathBuf; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.path("src/librustc") + } + + fn make_run(run: RunConfig) { + run.builder.ensure(RustcDocs { + stage: run.builder.top_stage, + host: run.target, + }); + } + + /// Builds the `rustc-docs` installer component. + fn run(self, builder: &Builder) -> PathBuf { + let build = builder.build; + let host = self.host; + + let name = pkgname(build, "rustc-docs"); + + println!("Dist compiler docs ({})", host); + if !build.config.compiler_docs { + println!("\tskipping - compiler docs disabled"); + return distdir(build).join(format!("{}-{}.tar.gz", name, host)); } + builder.default_doc(None); + + let image = tmpdir(build).join(format!("{}-{}-image", name, host)); + let _ = fs::remove_dir_all(&image); + + let dst = image.join("share/doc/rustc/html"); + t!(fs::create_dir_all(&dst)); + let src = build.compiler_doc_out(host); + cp_r(&src, &dst); + + let mut cmd = rust_installer(builder); + cmd.arg("generate") + .arg("--product-name=Rustc-Documentation") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=Rustc-documentation-is-installed.") + .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=rustc-docs") + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--bulk-dirs=share/doc/rustc/html"); + build.run(&mut cmd); + t!(fs::remove_dir_all(&image)); + distdir(build).join(format!("{}-{}.tar.gz", name, host)) } } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 5bc582b3507b..ca45adb4649a 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -483,21 +483,17 @@ impl Step for Std { let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "doc"); compile::std_cargo(builder, &compiler, target, &mut cargo); - // We don't want to build docs for internal std dependencies unless - // in compiler-docs mode. When not in that mode, we whitelist the crates - // for which docs must be built. - if !build.config.compiler_docs { - cargo.arg("--no-deps"); - for krate in &["alloc", "core", "std", "std_unicode"] { - cargo.arg("-p").arg(krate); - // Create all crate output directories first to make sure rustdoc uses - // relative links. - // FIXME: Cargo should probably do this itself. - t!(fs::create_dir_all(out_dir.join(krate))); - } + // Keep a whitelist so we do not build internal stdlib crates, these will be + // build by the rustc step later if enabled. + cargo.arg("--no-deps"); + for krate in &["alloc", "core", "std", "std_unicode"] { + cargo.arg("-p").arg(krate); + // Create all crate output directories first to make sure rustdoc uses + // relative links. + // FIXME: Cargo should probably do this itself. + t!(fs::create_dir_all(out_dir.join(krate))); } - build.run(&mut cargo); cp_r(&my_out, &out); } @@ -564,12 +560,12 @@ impl Step for Test { } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Rustc { +pub struct WhitelistedRustc { stage: u32, target: Interned, } -impl Step for Rustc { +impl Step for WhitelistedRustc { type Output = (); const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; @@ -580,21 +576,26 @@ impl Step for Rustc { } fn make_run(run: RunConfig) { - run.builder.ensure(Rustc { + run.builder.ensure(WhitelistedRustc { stage: run.builder.top_stage, target: run.target, }); } - /// Generate all compiler documentation. + /// Generate whitelisted compiler crate documentation. /// - /// This will generate all documentation for the compiler libraries and their - /// dependencies. This is largely just a wrapper around `cargo doc`. + /// This will generate all documentation for crates that are whitelisted + /// to be included in the standard documentation. This documentation is + /// included in the standard Rust documentation, so we should always + /// document it and symlink to merge with the rest of the std and test + /// documentation. We don't build other compiler documentation + /// here as we want to be able to keep it separate from the standard + /// documentation. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder) { let build = builder.build; let stage = self.stage; let target = self.target; - println!("Documenting stage{} compiler ({})", stage, target); + println!("Documenting stage{} whitelisted compiler ({})", stage, target); let out = build.doc_out(target); t!(fs::create_dir_all(&out)); let compiler = builder.compiler(stage, build.build); @@ -620,17 +621,12 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); - if build.config.compiler_docs { - // src/rustc/Cargo.toml contains a bin crate called rustc which - // would otherwise overwrite the docs for the real rustc lib crate. - cargo.arg("-p").arg("rustc_driver"); - } else { - // Like with libstd above if compiler docs aren't enabled then we're not - // documenting internal dependencies, so we have a whitelist. - cargo.arg("--no-deps"); - for krate in &["proc_macro"] { - cargo.arg("-p").arg(krate); - } + // We don't want to build docs for internal compiler dependencies in this + // step (there is another step for that). Therefore, we whitelist the crates + // for which docs must be built. + cargo.arg("--no-deps"); + for krate in &["proc_macro"] { + cargo.arg("-p").arg(krate); } build.run(&mut cargo); @@ -638,6 +634,85 @@ impl Step for Rustc { } } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Rustc { + stage: u32, + target: Interned, +} + +impl Step for Rustc { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + let builder = run.builder; + run.krate("rustc-main").default_condition(builder.build.config.docs) + } + + fn make_run(run: RunConfig) { + run.builder.ensure(Rustc { + stage: run.builder.top_stage, + target: run.target, + }); + } + + /// Generate compiler documentation. + /// + /// This will generate all documentation for compiler and dependencies. + /// Compiler documentation is distributed separately, so we make sure + /// we do not merge it with the other documentation from std, test and + /// proc_macros. This is largely just a wrapper around `cargo doc`. + fn run(self, builder: &Builder) { + let build = builder.build; + let stage = self.stage; + let target = self.target; + println!("Documenting stage{} compiler ({})", stage, target); + let out = build.compiler_doc_out(target); + t!(fs::create_dir_all(&out)); + let compiler = builder.compiler(stage, build.build); + let rustdoc = builder.rustdoc(compiler.host); + let compiler = if build.force_use_stage1(compiler, target) { + builder.compiler(1, compiler.host) + } else { + compiler + }; + + if !build.config.compiler_docs { + println!("\tskipping - compiler docs disabled"); + return; + } + + // Build libstd docs so that we generate relative links + builder.ensure(Std { stage, target }); + + builder.ensure(compile::Rustc { compiler, target }); + let out_dir = build.stage_out(compiler, Mode::Librustc) + .join(target).join("doc"); + + // See docs in std above for why we symlink + // + // This step must happen after other documentation steps. This + // invariant ensures that compiler documentation is not included + // in the standard documentation tarballs but that all the + // documentation from the standard documentation tarballs is included + // in the compiler documentation tarball. + let my_out = build.crate_doc_out(target); + build.clear_if_dirty(&my_out, &rustdoc); + t!(symlink_dir_force(&my_out, &out_dir)); + + let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); + compile::rustc_cargo(build, &mut cargo); + + // src/rustc/Cargo.toml contains a bin crate called rustc which + // would otherwise overwrite the docs for the real rustc lib crate. + cargo.arg("-p").arg("rustc_driver"); + + build.run(&mut cargo); + cp_r(&my_out, &out); + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ErrorIndex { target: Interned, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index b778ba33d89c..b2c8ac24d72d 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -511,6 +511,11 @@ impl Build { self.out.join(&*target).join("doc") } + /// Output directory for all documentation for a target + fn compiler_doc_out(&self, target: Interned) -> PathBuf { + self.out.join(&*target).join("compiler-doc") + } + /// Output directory for some generated md crate documentation for a target (temporary) fn md_doc_out(&self, target: Interned) -> Interned { INTERNER.intern_path(self.out.join(&*target).join("md-doc")) From 1392179cdc9c96e75353771959c246553b918d57 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Mar 2018 02:07:16 +0000 Subject: [PATCH 475/830] Configure the dist-x86_64-linux builder to produce compiler documentation --- src/ci/docker/dist-x86_64-linux/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index 3b98b0aa926b..28c97e8c6dbf 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -84,7 +84,8 @@ ENV HOSTS=x86_64-unknown-linux-gnu ENV RUST_CONFIGURE_ARGS \ --enable-full-tools \ --enable-sanitizers \ - --enable-profiler + --enable-profiler \ + --enable-compiler-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs From 395570857686648f76ba801d3cde24e4cb906934 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 16:31:20 -0400 Subject: [PATCH 476/830] WIP tweak example to include feature gate --- src/librustc/diagnostics.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index fad180325928..4c2dd8c27186 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2081,6 +2081,8 @@ appear within the `impl Trait` itself. Erroneous code example: ```compile-fail,E0909 +#![feature(conservative_impl_trait)] + use std::cell::Cell; trait Trait<'a> { } From 2ba41e9d7943912dafe2f508c97d4083249d97a4 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 21 Mar 2018 15:43:06 -0500 Subject: [PATCH 477/830] update stdsimd --- src/stdsimd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdsimd b/src/stdsimd index ab9356f2af65..bcb720e55861 160000 --- a/src/stdsimd +++ b/src/stdsimd @@ -1 +1 @@ -Subproject commit ab9356f2af650815d339d77306f0d09c44d531ad +Subproject commit bcb720e55861c38db47f2ebdf26b7198338cb39d From 3272b63f3458c9ca7a4680b512cc0dfd79e763e3 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 21 Mar 2018 21:00:38 +0000 Subject: [PATCH 478/830] Moved test to ui --- .../type-dependent-def-issue-49241.rs | 0 .../ui/type-dependent-def-issue-49241.stderr | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+) rename src/test/{compile-fail => ui}/type-dependent-def-issue-49241.rs (100%) create mode 100644 src/test/ui/type-dependent-def-issue-49241.stderr diff --git a/src/test/compile-fail/type-dependent-def-issue-49241.rs b/src/test/ui/type-dependent-def-issue-49241.rs similarity index 100% rename from src/test/compile-fail/type-dependent-def-issue-49241.rs rename to src/test/ui/type-dependent-def-issue-49241.rs diff --git a/src/test/ui/type-dependent-def-issue-49241.stderr b/src/test/ui/type-dependent-def-issue-49241.stderr new file mode 100644 index 000000000000..f00edccae5d5 --- /dev/null +++ b/src/test/ui/type-dependent-def-issue-49241.stderr @@ -0,0 +1,18 @@ +error[E0434]: can't capture dynamic environment in a fn item + --> $DIR/type-dependent-def-issue-49241.rs:13:22 + | +LL | const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item + | ^ + | + = help: use the `|| { ... }` closure form instead + +error[E0080]: constant evaluation error + --> $DIR/type-dependent-def-issue-49241.rs:14:18 + | +LL | let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error + | ^ encountered constants with type errors, stopping evaluation + +error: aborting due to 2 previous errors + +Some errors occurred: E0080, E0434. +For more information about an error, try `rustc --explain E0080`. From 78bcbb0f96e3c65742fe3f6c5fb4c68f28dcf99c Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 02:29:01 +0800 Subject: [PATCH 479/830] Download the GCC artifacts from the HTTP server instead of FTP server. The former seems much more stable, in case the cache becomes invalidated. --- src/ci/docker/dist-i686-linux/build-gcc.sh | 17 +++++++++++++++++ src/ci/docker/dist-x86_64-linux/build-gcc.sh | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/ci/docker/dist-i686-linux/build-gcc.sh b/src/ci/docker/dist-i686-linux/build-gcc.sh index 6b991bb59e4b..08020e533ff1 100755 --- a/src/ci/docker/dist-i686-linux/build-gcc.sh +++ b/src/ci/docker/dist-i686-linux/build-gcc.sh @@ -17,6 +17,23 @@ GCC=4.8.5 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.bz2 | tar xjf - cd gcc-$GCC + +# FIXME(#49246): Remove the `sed` below. +# +# On 2018 March 21st, two Travis builders' cache for Docker are suddenly invalidated. Normally this +# is fine, because we just need to rebuild the Docker image. However, it reveals a network issue: +# downloading from `ftp://gcc.gnu.org/` from Travis (using passive mode) often leads to "Connection +# timed out" error, and even when the download completed, the file is usually corrupted. This causes +# nothing to be landed that day. +# +# We observed that the `gcc-4.8.5.tar.bz2` above can be downloaded successfully, so as a stability +# improvement we try to download from the HTTPS mirror instead. Turns out this uncovered the third +# bug: the host `gcc.gnu.org` and `cygwin.com` share the same IP, and the TLS certificate of the +# latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server +# instead here. +# +sed -i'' 's|ftp://gcc\.gnu\.org/|http://gcc.gnu.org/|g' ./contrib/download_prerequisites + ./contrib/download_prerequisites mkdir ../gcc-build cd ../gcc-build diff --git a/src/ci/docker/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/dist-x86_64-linux/build-gcc.sh index 6b991bb59e4b..08020e533ff1 100755 --- a/src/ci/docker/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/dist-x86_64-linux/build-gcc.sh @@ -17,6 +17,23 @@ GCC=4.8.5 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.bz2 | tar xjf - cd gcc-$GCC + +# FIXME(#49246): Remove the `sed` below. +# +# On 2018 March 21st, two Travis builders' cache for Docker are suddenly invalidated. Normally this +# is fine, because we just need to rebuild the Docker image. However, it reveals a network issue: +# downloading from `ftp://gcc.gnu.org/` from Travis (using passive mode) often leads to "Connection +# timed out" error, and even when the download completed, the file is usually corrupted. This causes +# nothing to be landed that day. +# +# We observed that the `gcc-4.8.5.tar.bz2` above can be downloaded successfully, so as a stability +# improvement we try to download from the HTTPS mirror instead. Turns out this uncovered the third +# bug: the host `gcc.gnu.org` and `cygwin.com` share the same IP, and the TLS certificate of the +# latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server +# instead here. +# +sed -i'' 's|ftp://gcc\.gnu\.org/|http://gcc.gnu.org/|g' ./contrib/download_prerequisites + ./contrib/download_prerequisites mkdir ../gcc-build cd ../gcc-build From 56a19a9eec0ae2cd1b1914cfe9854e1c1028f329 Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 04:07:29 +0800 Subject: [PATCH 480/830] Handle redirects correctly. --- src/ci/docker/dist-i686-linux/build-git.sh | 2 +- src/ci/docker/dist-x86_64-linux/build-git.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/dist-i686-linux/build-git.sh b/src/ci/docker/dist-i686-linux/build-git.sh index ff62a68629a8..aa31f50ba034 100755 --- a/src/ci/docker/dist-i686-linux/build-git.sh +++ b/src/ci/docker/dist-i686-linux/build-git.sh @@ -12,7 +12,7 @@ set -ex source shared.sh -curl https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - +curl -L https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - cd git-2.10.0 make configure diff --git a/src/ci/docker/dist-x86_64-linux/build-git.sh b/src/ci/docker/dist-x86_64-linux/build-git.sh index ff62a68629a8..aa31f50ba034 100755 --- a/src/ci/docker/dist-x86_64-linux/build-git.sh +++ b/src/ci/docker/dist-x86_64-linux/build-git.sh @@ -12,7 +12,7 @@ set -ex source shared.sh -curl https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - +curl -L https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz | tar xzf - cd git-2.10.0 make configure From 99b49b532c8fa2b45179ff346089d9527d05a7a6 Mon Sep 17 00:00:00 2001 From: Mrowqa Date: Wed, 21 Mar 2018 23:11:27 +0100 Subject: [PATCH 481/830] Now it compiles --- src/librustc/hir/lowering.rs | 3 ++- src/librustc/ich/impls_hir.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index a35af56bd97b..f6bdfde15fc5 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -809,7 +809,7 @@ impl<'a> LoweringContext<'a> { } } - fn lower_attrs(&mut self, attrs: &Vec) -> hir::HirVec { + fn lower_attrs(&mut self, attrs: &[Attribute]) -> hir::HirVec { attrs.iter().map(|a| self.lower_attr(a)).collect::>().into() } @@ -1019,6 +1019,7 @@ impl<'a> LoweringContext<'a> { span, pure_wrt_drop: false, synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), + attrs: P::new(), }); hir::TyPath(hir::QPath::Resolved(None, P(hir::Path { diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index e764cedd658b..774b1442b710 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -203,7 +203,8 @@ impl_stable_hash_for!(struct hir::TyParam { default, span, pure_wrt_drop, - synthetic + synthetic, + attrs }); impl_stable_hash_for!(enum hir::GenericParam { From 7c442e5c9b46de225f8903352b7dfc5552b297de Mon Sep 17 00:00:00 2001 From: Murarth Date: Wed, 21 Mar 2018 10:47:03 -0700 Subject: [PATCH 482/830] Stabilize method `String::retain` --- .../src/library-features/string-retain.md | 23 ------------------- src/liballoc/string.rs | 4 +--- 2 files changed, 1 insertion(+), 26 deletions(-) delete mode 100644 src/doc/unstable-book/src/library-features/string-retain.md diff --git a/src/doc/unstable-book/src/library-features/string-retain.md b/src/doc/unstable-book/src/library-features/string-retain.md deleted file mode 100644 index 049444aa49bd..000000000000 --- a/src/doc/unstable-book/src/library-features/string-retain.md +++ /dev/null @@ -1,23 +0,0 @@ -# `string_retain` - -The tracking issue for this feature is: [#43874] - -[#43874]: https://github.com/rust-lang/rust/issues/43874 - ------------------------- - -Retains only the characters specified by the predicate. - -In other words, remove all characters `c` such that `f(c)` returns `false`. -This method operates in place and preserves the order of the retained -characters. - -```rust -#![feature(string_retain)] - -let mut s = String::from("f_o_ob_ar"); - -s.retain(|c| c != '_'); - -assert_eq!(s, "foobar"); -``` diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 9fec90914985..52ff6357c5b7 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1177,8 +1177,6 @@ impl String { /// # Examples /// /// ``` - /// #![feature(string_retain)] - /// /// let mut s = String::from("f_o_ob_ar"); /// /// s.retain(|c| c != '_'); @@ -1186,7 +1184,7 @@ impl String { /// assert_eq!(s, "foobar"); /// ``` #[inline] - #[unstable(feature = "string_retain", issue = "43874")] + #[stable(feature = "string_retain", since = "1.26.0")] pub fn retain(&mut self, mut f: F) where F: FnMut(char) -> bool { From 48c4e352d38479a5adcd664bef3a208640ba5cbc Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 19:22:41 -0400 Subject: [PATCH 483/830] WIP do not use in-band lifetimes --- src/librustc/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 4c2dd8c27186..10156d22501e 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2087,7 +2087,7 @@ use std::cell::Cell; trait Trait<'a> { } -impl Trait<'b> for Cell<&'a u32> { } +impl<'a, 'b> Trait<'b> for Cell<&'a u32> { } fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> where 'x: 'y From 2e8a1abc2df44d8e71e52bf92b658438707564ea Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 19:23:29 -0400 Subject: [PATCH 484/830] also fix the Fixed code --- src/librustc/diagnostics.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 10156d22501e..2fd875c34476 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2109,11 +2109,13 @@ type. For example, changing the return type to `impl Trait<'y> + 'x` would work: ``` +#![feature(conservative_impl_trait)] + use std::cell::Cell; trait Trait<'a> { } -impl Trait<'b> for Cell<&'a u32> { } +impl<'a,'b> Trait<'b> for Cell<&'a u32> { } fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> + 'x where 'x: 'y From b3fb0d10f03fe7d8f2eaa705a972b0f45e1723db Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 21 Mar 2018 19:57:10 -0500 Subject: [PATCH 485/830] add target_feature items to doc_cfg rustdoc test --- src/test/rustdoc/doc-cfg.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/test/rustdoc/doc-cfg.rs b/src/test/rustdoc/doc-cfg.rs index 8499e5c741ee..ea8a13b034be 100644 --- a/src/test/rustdoc/doc-cfg.rs +++ b/src/test/rustdoc/doc-cfg.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(doc_cfg)] +#![feature(target_feature, cfg_target_feature)] // @has doc_cfg/struct.Portable.html // @!has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' '' @@ -45,3 +46,26 @@ pub mod unix_only { fn unix_and_arm_only_function() {} } } + +// tagging a function with `#[target_feature]` creates a doc(cfg(target_feature)) node for that +// item as well + +// the portability header is different on the module view versus the full view +// @has doc_cfg/index.html +// @matches - '//*[@class=" module-item"]//*[@class="stab portability"]' '\Aavx\Z' + +// @has doc_cfg/fn.uses_target_feature.html +// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ +// 'This is supported with target feature avx only.' +#[target_feature(enable = "avx")] +pub unsafe fn uses_target_feature() { + content::should::be::irrelevant(); +} + +// @has doc_cfg/fn.uses_cfg_target_feature.html +// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \ +// 'This is supported with target feature avx only.' +#[doc(cfg(target_feature = "avx"))] +pub fn uses_cfg_target_feature() { + uses_target_feature(); +} From c116b0e8296dc4198408a708fae53f47fc1e51c6 Mon Sep 17 00:00:00 2001 From: Maxwell Borden Date: Wed, 21 Mar 2018 18:11:57 -0700 Subject: [PATCH 486/830] Fixed clockwise/counter-clockwise in atan2 documentation in f32 and f64 and included that it returns radians --- src/libstd/f32.rs | 9 +++++---- src/libstd/f64.rs | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index a760922115ae..ceb019bc95b4 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -780,7 +780,7 @@ impl f32 { unsafe { cmath::atanf(self) } } - /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`). + /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians. /// /// * `x = 0`, `y = 0`: `0` /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` @@ -791,12 +791,13 @@ impl f32 { /// use std::f32; /// /// let pi = f32::consts::PI; - /// // All angles from horizontal right (+x) - /// // 45 deg counter-clockwise + /// // Positive angles measured counter-clockwise + /// // from positive x axis + /// // -pi/4 radians (45 deg clockwise) /// let x1 = 3.0f32; /// let y1 = -3.0f32; /// - /// // 135 deg clockwise + /// // 3pi/4 radians (135 deg counter-clockwise) /// let x2 = -3.0f32; /// let y2 = 3.0f32; /// diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 6f34f176a971..97adf108b73b 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -716,7 +716,7 @@ impl f64 { unsafe { cmath::atan(self) } } - /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`). + /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians. /// /// * `x = 0`, `y = 0`: `0` /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` @@ -727,12 +727,13 @@ impl f64 { /// use std::f64; /// /// let pi = f64::consts::PI; - /// // All angles from horizontal right (+x) - /// // 45 deg counter-clockwise + /// // Positive angles measured counter-clockwise + /// // from positive x axis + /// // -pi/4 radians (45 deg clockwise) /// let x1 = 3.0_f64; /// let y1 = -3.0_f64; /// - /// // 135 deg clockwise + /// // 3pi/4 radians (135 deg counter-clockwise) /// let x2 = -3.0_f64; /// let y2 = 3.0_f64; /// From 9f792e199bc53a75afdad72547a151a0bc86ec5d Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 09:02:51 +0800 Subject: [PATCH 487/830] Temporarily disable dist-ing RLS, Rustfmt and Clippy. Unfortunately we don't have sufficient time to rebuild the cache *and* distribute everything in `dist-x86_64-linux alt`, the debug assertions are really slow. We will re-enable them after the PR has been successfully merged, thus successfully updating the cache (freeing up 40 minutes), giving us enough time to build these tools. --- src/ci/run.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index e3f38e4834a9..afa6d1fa0aea 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -105,7 +105,15 @@ fi travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then - sh -x -c "$SCRIPT" + # FIXME(#49246): Re-enable these tools after #49246 has been merged and thus fixing the cache. + if [ "$DEPLOY_ALT" = 1 ]; then + sh -x -c "$SCRIPT \ + --exclude src/tools/rls \ + --exclude src/tools/rustfmt \ + --exclude src/tools/clippy" + else + sh -x -c "$SCRIPT" + fi else do_make() { travis_fold start "make-$1" From 2b13d95da02d318c12814261dd36edd91ae6879e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 21 Mar 2018 23:28:48 -0500 Subject: [PATCH 488/830] termination_trait: Make error message more helpful --- src/librustc/traits/error_reporting.rs | 16 +++++++--------- src/libstd/process.rs | 5 +++-- .../termination-trait-main-i32.rs | 5 +++-- .../termination-trait-not-satisfied.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8572c4077142..47e6b0feceae 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -585,17 +585,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref.to_predicate(), post_message) })); - let explanation = match obligation.cause.code { - ObligationCauseCode::MainFunctionType => { + let explanation = + if obligation.cause.code == ObligationCauseCode::MainFunctionType { "consider using `()`, or a `Result`".to_owned() - } - _ => { + } else { format!("{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref, - trait_ref.self_ty()) - } - }; + pre_message, + trait_ref, + trait_ref.self_ty()) + }; if let Some(ref s) = label { // If it has a custom "#[rustc_on_unimplemented]" diff --git a/src/libstd/process.rs b/src/libstd/process.rs index d5ac2d19e831..c877bf6aa35c 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1442,8 +1442,9 @@ pub fn id() -> u32 { /// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned. #[cfg_attr(not(test), lang = "termination")] #[unstable(feature = "termination_trait_lib", issue = "43301")] -#[rustc_on_unimplemented = - "`main` can only return types that implement {Termination}, not `{Self}`"] +#[rustc_on_unimplemented( + message="`main` has invalid return type `{Self}`", + label="`main` can only return types that implement {Termination}")] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 2cf9fdcfb4db..0e6ddf7c92f1 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -9,7 +9,8 @@ // except according to those terms. fn main() -> i32 { -//~^ ERROR `i32: std::process::Termination` is not satisfied -//~| NOTE `main` can only return types that implement std::process::Termination, not `i32` +//~^ ERROR `main` has invalid return type `i32` +//~| NOTE `main` can only return types that implement std::process::Termination +//~| HELP consider using `()`, or a `Result` 0 } diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs index bab02fc55970..b5f5472b4929 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-not-satisfied.rs @@ -10,6 +10,6 @@ struct ReturnType {} -fn main() -> ReturnType { //~ ERROR `ReturnType: std::process::Termination` is not satisfied +fn main() -> ReturnType { //~ ERROR `main` has invalid return type `ReturnType` ReturnType {} } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index 211247757cbc..5109d9275c58 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `char: std::process::Termination` is not satisfied +error[E0277]: `main` has invalid return type `char` --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types that implement std::process::Termination, not `char` + | ^^^^ `main` can only return types that implement std::process::Termination | = help: consider using `()`, or a `Result` From b48a26cdd1d086a3ca7ffae35b73b72f9ce85b8f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 09:56:04 +0100 Subject: [PATCH 489/830] Produce nice array lengths on a best effort basis --- src/librustc/traits/error_reporting.rs | 16 ++++++++++--- src/librustc/util/ppaux.rs | 4 ++-- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 2 +- .../ui/unevaluated_fixed_size_array_len.rs | 23 +++++++++++++++++++ .../unevaluated_fixed_size_array_len.stderr | 17 ++++++++++++++ 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/unevaluated_fixed_size_array_len.rs create mode 100644 src/test/ui/unevaluated_fixed_size_array_len.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index ab3c619dcdcd..79d5cf793594 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -443,10 +443,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { 4 }; + + let normalize = |candidate| self.tcx.global_tcx().infer_ctxt().enter(|ref infcx| { + let normalized = infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .normalize(candidate) + .ok(); + match normalized { + Some(normalized) => format!("\n {:?}", normalized.value), + None => format!("\n {:?}", candidate), + } + }); + err.help(&format!("the following implementations were found:{}{}", - &impl_candidates[0..end].iter().map(|candidate| { - format!("\n {:?}", candidate) - }).collect::(), + &impl_candidates[0..end].iter().map(normalize).collect::(), if impl_candidates.len() > 5 { format!("\nand {} others", impl_candidates.len() - 4) } else { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 2c3ee1ec285a..056f1278c47c 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1177,8 +1177,8 @@ define_print! { ConstVal::Value(Value::ByVal(PrimVal::Bytes(sz))) => { write!(f, "{}", sz)?; } - ConstVal::Unevaluated(_def_id, substs) => { - write!(f, "", &substs[..])?; + ConstVal::Unevaluated(_def_id, _substs) => { + write!(f, "_")?; } _ => { write!(f, "{:?}", sz)?; diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 45dce3d8740d..169a12ef92e9 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -46,7 +46,7 @@ error[E0223]: ambiguous associated type LL | type A = [u8; 4]::AssocTy; | ^^^^^^^^^^^^^^^^ ambiguous associated type | - = note: specify the type using the syntax `<[u8; ] as Trait>::AssocTy` + = note: specify the type using the syntax `<[u8; _] as Trait>::AssocTy` error[E0223]: ambiguous associated type --> $DIR/bad-assoc-ty.rs:15:10 diff --git a/src/test/ui/unevaluated_fixed_size_array_len.rs b/src/test/ui/unevaluated_fixed_size_array_len.rs new file mode 100644 index 000000000000..a6ed9f32106f --- /dev/null +++ b/src/test/ui/unevaluated_fixed_size_array_len.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49208 + +trait Foo { + fn foo(); +} + +impl Foo for [(); 1] { + fn foo() {} +} + +fn main() { + <[(); 0] as Foo>::foo() //~ ERROR E0277 +} diff --git a/src/test/ui/unevaluated_fixed_size_array_len.stderr b/src/test/ui/unevaluated_fixed_size_array_len.stderr new file mode 100644 index 000000000000..6e959da99397 --- /dev/null +++ b/src/test/ui/unevaluated_fixed_size_array_len.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied + --> $DIR/unevaluated_fixed_size_array_len.rs:22:5 + | +LL | <[(); 0] as Foo>::foo() //~ ERROR E0277 + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]` + | + = help: the following implementations were found: + <[(); 1] as Foo> +note: required by `Foo::foo` + --> $DIR/unevaluated_fixed_size_array_len.rs:14:5 + | +LL | fn foo(); + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 613fb8bc2c5277b9b9a14bdba3939bb6042d91ec Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 22 Mar 2018 10:06:17 +0100 Subject: [PATCH 490/830] document format_args! - fix trailing whitespace --- src/libcore/fmt/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 0363714c31b5..62994ed15cc6 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1682,7 +1682,7 @@ impl<'a> Formatter<'a> { /// /// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R)); /// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V); - /// + /// /// impl<'a, L, R> fmt::Debug for Arm<'a, L, R> /// where /// L: 'a + fmt::Debug, R: 'a + fmt::Debug From b272749197a8a4c949b43d4661909b189066f4ae Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 12:38:40 +0100 Subject: [PATCH 491/830] Fix the conversion between bit representations and i128 representations --- src/librustc/ty/layout.rs | 8 +++- src/librustc/ty/mod.rs | 23 +++-------- src/librustc/ty/util.rs | 46 ++++++++++++--------- src/test/run-pass/ctfe/signed_enum_discr.rs | 27 ++++++++++++ 4 files changed, 66 insertions(+), 38 deletions(-) create mode 100644 src/test/run-pass/ctfe/signed_enum_discr.rs diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 3a3f10cb87db..029dd6f1fb46 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1544,11 +1544,17 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } let (mut min, mut max) = (i128::max_value(), i128::min_value()); + let discr_type = def.repr.discr_type(); + let bits = Integer::from_attr(tcx, discr_type).size().bits(); for (i, discr) in def.discriminants(tcx).enumerate() { if variants[i].iter().any(|f| f.abi == Abi::Uninhabited) { continue; } - let x = discr.val as i128; + let mut x = discr.val as i128; + if discr_type.is_signed() { + // sign extend the raw representation to be an i128 + x = (x << (128 - bits)) >> (128 - bits); + } if x < min { min = x; } if x > max { max = x; } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c91502235192..9ffdccefae58 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1886,7 +1886,6 @@ impl<'a, 'gcx, 'tcx> AdtDef { ) -> Option> { let param_env = ParamEnv::empty(); let repr_type = self.repr.discr_type(); - let bit_size = layout::Integer::from_attr(tcx, repr_type).size().bits(); let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); let instance = ty::Instance::new(expr_did, substs); let cid = GlobalId { @@ -1896,25 +1895,13 @@ impl<'a, 'gcx, 'tcx> AdtDef { match tcx.const_eval(param_env.and(cid)) { Ok(&ty::Const { val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))), - .. + ty, }) => { trace!("discriminants: {} ({:?})", b, repr_type); - let ty = repr_type.to_ty(tcx); - if repr_type.is_signed() { - let val = b as i128; - // sign extend to i128 - let amt = 128 - bit_size; - let val = (val << amt) >> amt; - Some(Discr { - val: val as u128, - ty, - }) - } else { - Some(Discr { - val: b, - ty, - }) - } + Some(Discr { + val: b, + ty, + }) }, Ok(&ty::Const { val: ConstVal::Value(other), diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 91d460a96f78..afe977d10baa 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -39,16 +39,24 @@ use syntax_pos::{Span, DUMMY_SP}; #[derive(Copy, Clone, Debug)] pub struct Discr<'tcx> { + /// bit representation of the discriminant, so `-128i8` is `0xFF_u128` pub val: u128, pub ty: Ty<'tcx> } impl<'tcx> fmt::Display for Discr<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - if self.ty.is_signed() { - write!(fmt, "{}", self.val as i128) - } else { - write!(fmt, "{}", self.val) + match self.ty.sty { + ty::TyInt(ity) => { + let bits = ty::tls::with(|tcx| { + Integer::from_attr(tcx, SignedInt(ity)).size().bits() + }); + let x = self.val as i128; + // sign extend the raw representation to be an i128 + let x = (x << (128 - bits)) >> (128 - bits); + write!(fmt, "{}", x) + }, + _ => write!(fmt, "{}", self.val), } } } @@ -64,15 +72,18 @@ impl<'tcx> Discr<'tcx> { TyUint(uty) => (Integer::from_attr(tcx, UnsignedInt(uty)), false), _ => bug!("non integer discriminant"), }; + + let bit_size = int.size().bits(); + let amt = 128 - bit_size; if signed { - let (min, max) = match int { - Integer::I8 => (i8::min_value() as i128, i8::max_value() as i128), - Integer::I16 => (i16::min_value() as i128, i16::max_value() as i128), - Integer::I32 => (i32::min_value() as i128, i32::max_value() as i128), - Integer::I64 => (i64::min_value() as i128, i64::max_value() as i128), - Integer::I128 => (i128::min_value(), i128::max_value()), + let sext = |u| { + let i = u as i128; + (i << amt) >> amt }; - let val = self.val as i128; + let min = sext(1_u128 << (bit_size - 1)); + let max = i128::max_value() >> amt; + let val = sext(self.val); + assert!(n < (i128::max_value() as u128)); let n = n as i128; let oflo = val > max - n; let val = if oflo { @@ -80,22 +91,19 @@ impl<'tcx> Discr<'tcx> { } else { val + n }; + // zero the upper bits + let val = val as u128; + let val = (val << amt) >> amt; (Self { val: val as u128, ty: self.ty, }, oflo) } else { - let (min, max) = match int { - Integer::I8 => (u8::min_value() as u128, u8::max_value() as u128), - Integer::I16 => (u16::min_value() as u128, u16::max_value() as u128), - Integer::I32 => (u32::min_value() as u128, u32::max_value() as u128), - Integer::I64 => (u64::min_value() as u128, u64::max_value() as u128), - Integer::I128 => (u128::min_value(), u128::max_value()), - }; + let max = u128::max_value() >> amt; let val = self.val; let oflo = val > max - n; let val = if oflo { - min + (n - (max - val) - 1) + n - (max - val) - 1 } else { val + n }; diff --git a/src/test/run-pass/ctfe/signed_enum_discr.rs b/src/test/run-pass/ctfe/signed_enum_discr.rs new file mode 100644 index 000000000000..7049d28a8708 --- /dev/null +++ b/src/test/run-pass/ctfe/signed_enum_discr.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49181 + +#[derive(Eq, PartialEq)] +#[repr(i8)] +pub enum A { + B = -1, + C = 1, +} + +pub const D: A = A::B; + +fn main() { + match A::C { + D => {}, + _ => {} + } +} From de1c929adaeb5b1e466b6f8485a9f7cf92969185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Thu, 22 Mar 2018 11:27:59 +0100 Subject: [PATCH 492/830] Use GNU version of fgrep/egrep tool if available It is mostly for BSD system. Some tests (run-make/issue-35164 and run-make/cat-and-grep-sanity-check) are failing with BSD fgrep, whereas they pass with gnu version (gfgrep). --- src/etc/cat-and-grep.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/etc/cat-and-grep.sh b/src/etc/cat-and-grep.sh index ef9884d2e980..361e8d8e60ee 100755 --- a/src/etc/cat-and-grep.sh +++ b/src/etc/cat-and-grep.sh @@ -63,6 +63,11 @@ done shift $((OPTIND - 1)) +# use gnu version of tool if available (for bsd) +if command -v "g${GREPPER}"; then + GREPPER="g${GREPPER}" +fi + LOG=$(mktemp -t cgrep.XXXXXX) trap "rm -f $LOG" EXIT From a1a3bf2b31af680ffbbed4270efc0a2cda80ca87 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 22 Mar 2018 14:38:37 +0100 Subject: [PATCH 493/830] Fix DefKey lookup for proc-macro crates. --- src/librustc_metadata/decoder.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b0c945fbf2a0..1ea009a4e911 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -14,7 +14,8 @@ use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; use schema::*; use rustc_data_structures::sync::{Lrc, ReadGuard}; -use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; +use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash, + DisambiguatedDefPathData}; use rustc::hir; use rustc::middle::cstore::{LinkagePreference, ExternConstBody, ExternBodyNestedBodies}; @@ -1115,7 +1116,23 @@ impl<'a, 'tcx> CrateMetadata { #[inline] pub fn def_key(&self, index: DefIndex) -> DefKey { - self.def_path_table.def_key(index) + if !self.is_proc_macro(index) { + self.def_path_table.def_key(index) + } else { + // FIXME(#49271) - It would be better if the DefIds were consistent + // with the DefPathTable, but for proc-macro crates + // they aren't. + let name = self.proc_macros + .as_ref() + .unwrap()[index.to_proc_macro_index()].0; + DefKey { + parent: Some(CRATE_DEF_INDEX), + disambiguated_data: DisambiguatedDefPathData { + data: DefPathData::MacroDef(name.as_str()), + disambiguator: 0, + } + } + } } // Returns the path leading to the thing with this `id`. From 9839e5fa103d117cbdb936e8594ba832e1eeb320 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 15:05:12 +0100 Subject: [PATCH 494/830] Remove slow HashSet during miri stack frame creation --- src/librustc_mir/interpret/eval_context.rs | 40 ++++++---------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index c236ce2abc5f..ee8419404ca4 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::fmt::Write; use rustc::hir::def_id::DefId; @@ -383,40 +382,23 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M ) -> EvalResult<'tcx> { ::log_settings::settings().indentation += 1; - /// Return the set of locals that have a storage annotation anywhere - fn collect_storage_annotations<'mir, 'tcx>(mir: &'mir mir::Mir<'tcx>) -> HashSet { - use rustc::mir::StatementKind::*; - - let mut set = HashSet::new(); - for block in mir.basic_blocks() { - for stmt in block.statements.iter() { - match stmt.kind { - StorageLive(local) | - StorageDead(local) => { - set.insert(local); - } - _ => {} - } - } - } - set - } - // Subtract 1 because `local_decls` includes the ReturnMemoryPointer, but we don't store a local // `Value` for that. let num_locals = mir.local_decls.len() - 1; - let locals = { - let annotated_locals = collect_storage_annotations(mir); - let mut locals = vec![None; num_locals]; - for i in 0..num_locals { - let local = mir::Local::new(i + 1); - if !annotated_locals.contains(&local) { - locals[i] = Some(Value::ByVal(PrimVal::Undef)); + let mut locals = vec![Some(Value::ByVal(PrimVal::Undef)); num_locals]; + trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len()); + for block in mir.basic_blocks() { + for stmt in block.statements.iter() { + use rustc::mir::StatementKind::{StorageDead, StorageLive}; + match stmt.kind { + StorageLive(local) | StorageDead(local) => if local.index() > 0 { + locals[local.index() - 1] = None; + }, + _ => {} } } - locals - }; + } self.stack.push(Frame { mir, From a4bc8590117f313ab2c895ab91f183f368369e2b Mon Sep 17 00:00:00 2001 From: kennytm Date: Thu, 22 Mar 2018 17:52:57 +0800 Subject: [PATCH 495/830] Revert "Temporarily disable dist-ing RLS, Rustfmt and Clippy." This reverts commit 9f792e199bc53a75afdad72547a151a0bc86ec5d. --- src/ci/run.sh | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index afa6d1fa0aea..e3f38e4834a9 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -105,15 +105,7 @@ fi travis_fold end log-system-info if [ ! -z "$SCRIPT" ]; then - # FIXME(#49246): Re-enable these tools after #49246 has been merged and thus fixing the cache. - if [ "$DEPLOY_ALT" = 1 ]; then - sh -x -c "$SCRIPT \ - --exclude src/tools/rls \ - --exclude src/tools/rustfmt \ - --exclude src/tools/clippy" - else - sh -x -c "$SCRIPT" - fi + sh -x -c "$SCRIPT" else do_make() { travis_fold start "make-$1" From bfb94ac5f43ac7fb0736185421f6135fe7043a2e Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Thu, 22 Mar 2018 10:34:51 -0500 Subject: [PATCH 496/830] Clean up raw identifier handling when recovering tokens from AST. --- src/libsyntax/ext/quote.rs | 5 +++-- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/parse/token.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 090b9a354463..540a03ff032f 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -238,8 +238,9 @@ pub mod rt { if i > 0 { inner.push(TokenTree::Token(self.span, token::Colon).into()); } - inner.push(TokenTree::Token(self.span, - token::Ident(segment.identifier, false)).into()); + inner.push(TokenTree::Token( + self.span, token::Token::from_ast_ident(segment.identifier) + ).into()); } inner.push(self.tokens.clone()); diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 0f5855a32259..3f01d5ec6dd8 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -169,7 +169,7 @@ pub fn transcribe(cx: &ExtCtxt, Ident { ctxt: ident.ctxt.apply_mark(cx.current_expansion.mark), ..ident }; sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark)); result.push(TokenTree::Token(sp, token::Dollar).into()); - result.push(TokenTree::Token(sp, token::Ident(ident, false)).into()); + result.push(TokenTree::Token(sp, token::Token::from_ast_ident(ident)).into()); } } quoted::TokenTree::Delimited(mut span, delimited) => { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 4e7a282adc58..7798a7a77ee6 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -236,7 +236,7 @@ impl Token { /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary. pub fn from_ast_ident(ident: ast::Ident) -> Token { - Ident(ident, is_reserved_ident(ident)) + Ident(ident, is_reserved_ident(ident) && !is_path_segment_keyword(ident)) } /// Returns `true` if the token starts with '>'. From 57f9c4d6d9ba7d48b9f64193dd037a54e11ef7b4 Mon Sep 17 00:00:00 2001 From: Lymia Aluysia Date: Thu, 22 Mar 2018 10:35:49 -0500 Subject: [PATCH 497/830] Clarify description of raw_identifiers feature flag. --- src/libsyntax/feature_gate.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 153e42c8214f..c64e0f514de6 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -453,7 +453,7 @@ declare_features! ( // `use path as _;` and `extern crate c as _;` (active, underscore_imports, "1.26.0", Some(48216), None), - // Raw identifiers allowing keyword names to be used + // Allows keywords to be escaped for use as identifiers (active, raw_identifiers, "1.26.0", Some(48589), None), ); From 0d278ca6a887b0adc2b1b852c09f24892b8397b4 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 22 Mar 2018 15:55:57 +0000 Subject: [PATCH 498/830] Use FunctionRetTy::Default rather than an explicit TyKind::Infer for lambda-building This prevents explicit `-> _` return type annotations for closures generated by `lambda`. --- src/librustc_allocator/expand.rs | 2 +- src/libsyntax/ext/build.rs | 10 +++++----- src/libsyntax/test.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs index 02e704b68418..ee38cca7828b 100644 --- a/src/librustc_allocator/expand.rs +++ b/src/librustc_allocator/expand.rs @@ -145,7 +145,7 @@ impl<'a> AllocFnFactory<'a> { let result = self.call_allocator(method.name, args); let (output_ty, output_expr) = self.ret_ty(&method.output, &mut abi_args, mk, result); - let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, output_ty), + let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)), Unsafety::Unsafe, dummy_spanned(Constness::NotConst), Abi::Rust, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 9b53553bf69d..269517e998f5 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -214,7 +214,7 @@ pub trait AstBuilder { fn arg(&self, span: Span, name: Ident, ty: P) -> ast::Arg; // FIXME unused self - fn fn_decl(&self, inputs: Vec , output: P) -> P; + fn fn_decl(&self, inputs: Vec , output: ast::FunctionRetTy) -> P; fn item_fn_poly(&self, span: Span, @@ -924,7 +924,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { -> P { let fn_decl = self.fn_decl( ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(), - self.ty_infer(span)); + ast::FunctionRetTy::Default(span)); // FIXME -- We are using `span` as the span of the `|...|` // part of the lambda, but it probably (maybe?) corresponds to @@ -970,10 +970,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } // FIXME unused self - fn fn_decl(&self, inputs: Vec, output: P) -> P { + fn fn_decl(&self, inputs: Vec, output: ast::FunctionRetTy) -> P { P(ast::FnDecl { inputs, - output: ast::FunctionRetTy::Ty(output), + output, variadic: false }) } @@ -1003,7 +1003,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.item(span, name, Vec::new(), - ast::ItemKind::Fn(self.fn_decl(inputs, output), + ast::ItemKind::Fn(self.fn_decl(inputs, ast::FunctionRetTy::Ty(output)), ast::Unsafety::Normal, dummy_spanned(ast::Constness::NotConst), Abi::Rust, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 9edfa767d319..67d3adc83f2d 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -547,7 +547,7 @@ fn mk_main(cx: &mut TestCtxt) -> P { // pub fn main() { ... } let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![])); let main_body = ecx.block(sp, vec![call_test_main]); - let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], main_ret_ty), + let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)), ast::Unsafety::Normal, dummy_spanned(ast::Constness::NotConst), ::abi::Abi::Rust, ast::Generics::default(), main_body); diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 49c372b751b5..3935f1722b61 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -962,7 +962,7 @@ impl<'a> MethodDef<'a> { let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); let method_ident = cx.ident_of(self.name); - let fn_decl = cx.fn_decl(args, ret_type); + let fn_decl = cx.fn_decl(args, ast::FunctionRetTy::Ty(ret_type)); let body_block = cx.block_expr(body); let unsafety = if self.is_unsafe { From 9fa14e47d4a14fcda4adff658ccfdda3c8b9005f Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 22 Mar 2018 16:59:02 +0100 Subject: [PATCH 499/830] Skip checking for Storage* statements in constants/statics --- src/librustc_mir/interpret/eval_context.rs | 27 ++++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ee8419404ca4..376c7f240583 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1,6 +1,7 @@ use std::fmt::Write; use rustc::hir::def_id::DefId; +use rustc::hir::def::Def; use rustc::hir::map::definitions::DefPathData; use rustc::middle::const_val::{ConstVal, ErrKind}; use rustc::mir; @@ -387,17 +388,23 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let num_locals = mir.local_decls.len() - 1; let mut locals = vec![Some(Value::ByVal(PrimVal::Undef)); num_locals]; - trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len()); - for block in mir.basic_blocks() { - for stmt in block.statements.iter() { - use rustc::mir::StatementKind::{StorageDead, StorageLive}; - match stmt.kind { - StorageLive(local) | StorageDead(local) => if local.index() > 0 { - locals[local.index() - 1] = None; - }, - _ => {} + match self.tcx.describe_def(instance.def_id()) { + // statics and constants don't have `Storage*` statements, no need to look for them + Some(Def::Static(..)) | Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {}, + _ => { + trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len()); + for block in mir.basic_blocks() { + for stmt in block.statements.iter() { + use rustc::mir::StatementKind::{StorageDead, StorageLive}; + match stmt.kind { + StorageLive(local) | StorageDead(local) => if local.index() > 0 { + locals[local.index() - 1] = None; + }, + _ => {} + } + } } - } + }, } self.stack.push(Frame { From ad50f3389a13d74aa0088bcb39c406193b721769 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 22 Mar 2018 16:35:54 +0000 Subject: [PATCH 500/830] Optimise decode return expression for unit structs --- src/libsyntax_ext/deriving/encodable.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index 743f22b6b314..88baa22e7fa1 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -228,13 +228,13 @@ fn encodable_substructure(cx: &mut ExtCtxt, } // unit structs have no fields and need to return Ok() - if stmts.is_empty() { + let blk = if stmts.is_empty() { let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![])); - let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok))); - stmts.push(cx.stmt_expr(ret_ok)); - } + cx.lambda1(trait_span, ok, blkarg) + } else { + cx.lambda_stmts_1(trait_span, stmts, blkarg) + }; - let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg); cx.expr_method_call(trait_span, encoder, cx.ident_of("emit_struct"), From 70559c54ce2a493a15f447436e281e16fc55b291 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 22 Mar 2018 09:49:20 -0700 Subject: [PATCH 501/830] Command::env_saw_path() may be unused on platforms not using posix_spawn() --- src/libstd/sys/unix/process/process_common.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 48255489dd91..b7f30600b8a4 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -184,6 +184,7 @@ impl Command { let maybe_env = self.env.capture_if_changed(); maybe_env.map(|env| construct_envp(env, &mut self.saw_nul)) } + #[allow(dead_code)] pub fn env_saw_path(&self) -> bool { self.env.have_changed_path() } From 1b0e9f5af9283b003f5fce6f19ede145c1776684 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 22 Mar 2018 14:57:28 +0000 Subject: [PATCH 502/830] Only generate documentation for local rustc crates. --- src/bootstrap/doc.rs | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index ca45adb4649a..e525bdb98fc0 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -17,12 +17,13 @@ //! Everything here is basically just a shim around calling either `rustbook` or //! `rustdoc`. +use std::collections::HashSet; use std::fs::{self, File}; use std::io::prelude::*; use std::io; use std::path::{PathBuf, Path}; -use Mode; +use {Build, Mode}; use build_helper::up_to_date; use util::{cp_r, symlink_dir}; @@ -704,15 +705,41 @@ impl Step for Rustc { let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); - // src/rustc/Cargo.toml contains a bin crate called rustc which - // would otherwise overwrite the docs for the real rustc lib crate. - cargo.arg("-p").arg("rustc_driver"); + // Only include compiler crates, no dependencies of those, such as `libc`. + cargo.arg("--no-deps"); + + // Find dependencies for top level crates. + let mut compiler_crates = HashSet::new(); + for root_crate in &["rustc", "rustc_driver"] { + let interned_root_crate = INTERNER.intern_str(root_crate); + find_compiler_crates(&build, &interned_root_crate, &mut compiler_crates); + } + + for krate in &compiler_crates { + cargo.arg("-p").arg(krate); + } build.run(&mut cargo); cp_r(&my_out, &out); } } +fn find_compiler_crates( + build: &Build, + name: &Interned, + crates: &mut HashSet> +) { + // Add current crate. + crates.insert(*name); + + // Look for dependencies. + for dep in build.crates.get(name).unwrap().deps.iter() { + if build.crates.get(dep).unwrap().is_local(build) { + find_compiler_crates(build, dep, crates); + } + } +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ErrorIndex { target: Interned, From 7df6f4161cdc13a19216b5f1087081f490f06cdb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 9 Mar 2018 09:26:15 -0800 Subject: [PATCH 503/830] rustc: Add a `#[wasm_custom_section]` attribute This commit is an implementation of adding custom sections to wasm artifacts in rustc. The intention here is to expose the ability of the wasm binary format to contain custom sections with arbitrary user-defined data. Currently neither our version of LLVM nor LLD supports this so the implementation is currently custom to rustc itself. The implementation here is to attach a `#[wasm_custom_section = "foo"]` attribute to any `const` which has a type like `[u8; N]`. Other types of constants aren't supported yet but may be added one day! This should hopefully be enough to get off the ground with *some* custom section support. The current semantics are that any constant tagged with `#[wasm_custom_section]` section will be *appended* to the corresponding section in the final output wasm artifact (and this affects dependencies linked in as well, not just the final crate). This means that whatever is interpreting the contents must be able to interpret binary-concatenated sections (or each constant needs to be in its own custom section). To test this change the existing `run-make` test suite was moved to a `run-make-fulldeps` folder and a new `run-make` test suite was added which applies to all targets by default. This test suite currently only has one test which only runs for the wasm target (using a node.js script to use `WebAssembly` in JS to parse the wasm output). --- src/bootstrap/builder.rs | 1 + src/bootstrap/compile.rs | 2 +- src/bootstrap/test.rs | 19 ++++-- src/librustc/dep_graph/dep_node.rs | 2 + src/librustc/hir/check_attr.rs | 13 ++++ src/librustc/middle/dead.rs | 5 ++ src/librustc/ty/maps/config.rs | 6 ++ src/librustc/ty/maps/mod.rs | 2 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_metadata/cstore_impl.rs | 2 + src/librustc_metadata/decoder.rs | 10 +++ src/librustc_metadata/encoder.rs | 12 ++++ src/librustc_metadata/schema.rs | 1 + src/librustc_trans/attributes.rs | 32 ++++++++- src/librustc_trans/back/link.rs | 6 ++ src/librustc_trans/back/wasm.rs | 44 +++++++++++++ src/librustc_trans/base.rs | 66 +++++++++++++++++++ src/librustc_trans/lib.rs | 3 + src/librustc_typeck/check/mod.rs | 23 ++++++- src/libsyntax/feature_gate.rs | 8 +++ .../a-b-a-linker-guard/Makefile | 0 .../a-b-a-linker-guard/a.rs | 0 .../a-b-a-linker-guard/b.rs | 0 .../alloc-extern-crates/Makefile | 0 .../alloc-extern-crates/fakealloc.rs | 0 .../allow-non-lint-warnings-cmdline/Makefile | 0 .../allow-non-lint-warnings-cmdline/foo.rs | 0 .../allow-warnings-cmdline-stability/Makefile | 0 .../allow-warnings-cmdline-stability/bar.rs | 0 .../allow-warnings-cmdline-stability/foo.rs | 0 .../archive-duplicate-names/Makefile | 0 .../archive-duplicate-names/bar.c | 0 .../archive-duplicate-names/bar.rs | 0 .../archive-duplicate-names/foo.c | 0 .../archive-duplicate-names/foo.rs | 0 .../atomic-lock-free/Makefile | 0 .../atomic-lock-free/atomic_lock_free.rs | 0 .../bare-outfile/Makefile | 0 .../bare-outfile/foo.rs | 0 .../c-dynamic-dylib/Makefile | 0 .../c-dynamic-dylib/bar.rs | 0 .../c-dynamic-dylib/cfoo.c | 0 .../c-dynamic-dylib/foo.rs | 0 .../c-dynamic-rlib/Makefile | 0 .../c-dynamic-rlib/bar.rs | 0 .../c-dynamic-rlib/cfoo.c | 0 .../c-dynamic-rlib/foo.rs | 0 .../c-link-to-rust-dylib/Makefile | 0 .../c-link-to-rust-dylib/bar.c | 0 .../c-link-to-rust-dylib/foo.rs | 0 .../c-link-to-rust-staticlib/Makefile | 0 .../c-link-to-rust-staticlib/bar.c | 0 .../c-link-to-rust-staticlib/foo.rs | 0 .../c-static-dylib/Makefile | 0 .../c-static-dylib/bar.rs | 0 .../c-static-dylib/cfoo.c | 0 .../c-static-dylib/foo.rs | 0 .../c-static-rlib/Makefile | 0 .../c-static-rlib/bar.rs | 0 .../c-static-rlib/cfoo.c | 0 .../c-static-rlib/foo.rs | 0 .../cat-and-grep-sanity-check/Makefile | 0 .../cdylib-fewer-symbols/Makefile | 0 .../cdylib-fewer-symbols/foo.rs | 0 .../cdylib/Makefile | 0 .../cdylib/bar.rs | 0 .../cdylib/foo.c | 0 .../cdylib/foo.rs | 0 .../codegen-options-parsing/Makefile | 0 .../codegen-options-parsing/dummy.rs | 0 .../compile-stdin/Makefile | 0 .../compiler-lookup-paths-2/Makefile | 0 .../compiler-lookup-paths-2/a.rs | 0 .../compiler-lookup-paths-2/b.rs | 0 .../compiler-lookup-paths-2/c.rs | 0 .../compiler-lookup-paths/Makefile | 0 .../compiler-lookup-paths/a.rs | 0 .../compiler-lookup-paths/b.rs | 0 .../compiler-lookup-paths/c.rs | 0 .../compiler-lookup-paths/d.rs | 0 .../compiler-lookup-paths/e.rs | 0 .../compiler-lookup-paths/e2.rs | 0 .../compiler-lookup-paths/f.rs | 0 .../compiler-lookup-paths/native.c | 0 .../compiler-rt-works-on-mingw/Makefile | 0 .../compiler-rt-works-on-mingw/foo.cpp | 0 .../compiler-rt-works-on-mingw/foo.rs | 0 .../crate-data-smoke/Makefile | 0 .../crate-data-smoke/crate.rs | 0 .../crate-data-smoke/lib.rs | 0 .../crate-data-smoke/rlib.rs | 0 .../crate-name-priority/Makefile | 0 .../crate-name-priority/foo.rs | 0 .../crate-name-priority/foo1.rs | 0 .../debug-assertions/Makefile | 0 .../debug-assertions/debug.rs | 0 .../dep-info-doesnt-run-much/Makefile | 0 .../dep-info-doesnt-run-much/foo.rs | 0 .../dep-info-spaces/Makefile | 0 .../dep-info-spaces/Makefile.foo | 0 .../dep-info-spaces/bar.rs | 0 .../dep-info-spaces/foo foo.rs | 0 .../dep-info-spaces/lib.rs | 0 .../dep-info/Makefile | 0 .../dep-info/Makefile.foo | 0 .../dep-info/bar.rs | 0 .../dep-info/foo.rs | 0 .../dep-info/lib.rs | 0 .../dep-info/lib2.rs | 0 .../duplicate-output-flavors/Makefile | 0 .../duplicate-output-flavors/foo.rs | 0 .../dylib-chain/Makefile | 0 .../dylib-chain/m1.rs | 0 .../dylib-chain/m2.rs | 0 .../dylib-chain/m3.rs | 0 .../dylib-chain/m4.rs | 0 .../emit/Makefile | 0 .../emit/test-24876.rs | 0 .../emit/test-26235.rs | 0 .../Makefile | 0 .../bar.rs | 0 .../foo.rs | 0 .../error-writing-dependencies/Makefile | 0 .../error-writing-dependencies/foo.rs | 0 .../extern-diff-internal-name/Makefile | 0 .../extern-diff-internal-name/lib.rs | 0 .../extern-diff-internal-name/test.rs | 0 .../extern-flag-disambiguates/Makefile | 0 .../extern-flag-disambiguates/a.rs | 0 .../extern-flag-disambiguates/b.rs | 0 .../extern-flag-disambiguates/c.rs | 0 .../extern-flag-disambiguates/d.rs | 0 .../extern-flag-fun/Makefile | 0 .../extern-flag-fun/bar-alt.rs | 0 .../extern-flag-fun/bar.rs | 0 .../extern-flag-fun/foo.rs | 0 .../extern-fn-generic/Makefile | 0 .../extern-fn-generic/test.c | 0 .../extern-fn-generic/test.rs | 0 .../extern-fn-generic/testcrate.rs | 0 .../extern-fn-mangle/Makefile | 0 .../extern-fn-mangle/test.c | 0 .../extern-fn-mangle/test.rs | 0 .../extern-fn-reachable/Makefile | 0 .../extern-fn-reachable/dylib.rs | 0 .../extern-fn-reachable/main.rs | 0 .../extern-fn-struct-passing-abi/Makefile | 0 .../extern-fn-struct-passing-abi/test.c | 0 .../extern-fn-struct-passing-abi/test.rs | 0 .../extern-fn-with-extern-types/Makefile | 0 .../extern-fn-with-extern-types/ctest.c | 0 .../extern-fn-with-extern-types/test.rs | 0 .../extern-fn-with-packed-struct/Makefile | 0 .../extern-fn-with-packed-struct/test.c | 0 .../extern-fn-with-packed-struct/test.rs | 0 .../extern-fn-with-union/Makefile | 0 .../extern-fn-with-union/ctest.c | 0 .../extern-fn-with-union/test.rs | 0 .../extern-fn-with-union/testcrate.rs | 0 .../extern-multiple-copies/Makefile | 0 .../extern-multiple-copies/bar.rs | 0 .../extern-multiple-copies/foo1.rs | 0 .../extern-multiple-copies/foo2.rs | 0 .../extern-multiple-copies2/Makefile | 0 .../extern-multiple-copies2/bar.rs | 0 .../extern-multiple-copies2/foo1.rs | 0 .../extern-multiple-copies2/foo2.rs | 0 .../extern-overrides-distribution/Makefile | 0 .../extern-overrides-distribution/libc.rs | 0 .../extern-overrides-distribution/main.rs | 0 .../extra-filename-with-temp-outputs/Makefile | 0 .../extra-filename-with-temp-outputs/foo.rs | 0 .../fpic/Makefile | 0 .../fpic/hello.rs | 0 .../hir-tree/Makefile | 0 .../hir-tree/input.rs | 0 .../hotplug_codegen_backend/Makefile | 0 .../hotplug_codegen_backend/some_crate.rs | 0 .../hotplug_codegen_backend/the_backend.rs | 0 .../include_bytes_deps/Makefile | 0 .../include_bytes_deps/input.bin | 0 .../include_bytes_deps/input.md | 0 .../include_bytes_deps/input.txt | 0 .../include_bytes_deps/main.rs | 0 .../inline-always-many-cgu/Makefile | 0 .../inline-always-many-cgu/foo.rs | 0 .../interdependent-c-libraries/Makefile | 0 .../interdependent-c-libraries/bar.c | 0 .../interdependent-c-libraries/bar.rs | 0 .../interdependent-c-libraries/foo.c | 0 .../interdependent-c-libraries/foo.rs | 0 .../interdependent-c-libraries/main.rs | 0 .../intrinsic-unreachable/Makefile | 0 .../intrinsic-unreachable/exit-ret.rs | 0 .../intrinsic-unreachable/exit-unreachable.rs | 0 .../invalid-library/Makefile | 0 .../invalid-library/foo.rs | 0 .../invalid-staticlib/Makefile | 0 .../issue-11908/Makefile | 0 .../issue-11908/bar.rs | 0 .../issue-11908/foo.rs | 0 .../issue-14500/Makefile | 0 .../issue-14500/bar.rs | 0 .../issue-14500/foo.c | 0 .../issue-14500/foo.rs | 0 .../issue-14698/Makefile | 0 .../issue-14698/foo.rs | 0 .../issue-15460/Makefile | 0 .../issue-15460/bar.rs | 0 .../issue-15460/foo.c | 0 .../issue-15460/foo.rs | 0 .../issue-18943/Makefile | 0 .../issue-18943/foo.rs | 0 .../issue-19371/Makefile | 0 .../issue-19371/foo.rs | 0 .../issue-20626/Makefile | 0 .../issue-20626/foo.rs | 0 .../issue-22131/Makefile | 0 .../issue-22131/foo.rs | 0 .../issue-24445/Makefile | 0 .../issue-24445/foo.c | 0 .../issue-24445/foo.rs | 0 .../issue-25581/Makefile | 0 .../issue-25581/test.c | 0 .../issue-25581/test.rs | 0 .../issue-26006/Makefile | 0 .../issue-26006/in/libc/lib.rs | 0 .../issue-26006/in/time/lib.rs | 0 .../issue-26092/Makefile | 0 .../issue-26092/blank.rs | 0 .../issue-28595/Makefile | 0 .../issue-28595/a.c | 0 .../issue-28595/a.rs | 0 .../issue-28595/b.c | 0 .../issue-28595/b.rs | 0 .../issue-28766/Makefile | 0 .../issue-28766/foo.rs | 0 .../issue-28766/main.rs | 0 .../issue-30063/Makefile | 0 .../issue-30063/foo.rs | 0 .../issue-33329/Makefile | 0 .../issue-33329/main.rs | 0 .../issue-35164/Makefile | 0 .../issue-35164/main.rs | 0 .../issue-35164/submodule/mod.rs | 0 .../issue-37839/Makefile | 0 .../issue-37839/a.rs | 0 .../issue-37839/b.rs | 0 .../issue-37839/c.rs | 0 .../issue-37893/Makefile | 0 .../issue-37893/a.rs | 0 .../issue-37893/b.rs | 0 .../issue-37893/c.rs | 0 .../issue-38237/Makefile | 0 .../issue-38237/bar.rs | 0 .../issue-38237/baz.rs | 0 .../issue-38237/foo.rs | 0 .../issue-40535/Makefile | 0 .../issue-40535/bar.rs | 0 .../issue-40535/baz.rs | 0 .../issue-40535/foo.rs | 0 .../issue-46239/Makefile | 0 .../issue-46239/main.rs | 0 .../issue-7349/Makefile | 0 .../issue-7349/foo.rs | 0 .../issues-41478-43796/Makefile | 0 .../issues-41478-43796/a.rs | 0 .../libs-and-bins/Makefile | 0 .../libs-and-bins/foo.rs | 0 .../libs-through-symlinks/Makefile | 0 .../libs-through-symlinks/bar.rs | 0 .../libs-through-symlinks/foo.rs | 0 .../libtest-json/Makefile | 0 .../libtest-json/f.rs | 0 .../libtest-json/output.json | 0 .../libtest-json/validate_json.py | 0 .../link-arg/Makefile | 0 .../link-arg/empty.rs | 0 .../link-cfg/Makefile | 0 .../link-cfg/dep-with-staticlib.rs | 0 .../link-cfg/dep.rs | 0 .../link-cfg/no-deps.rs | 0 .../link-cfg/return1.c | 0 .../link-cfg/return2.c | 0 .../link-cfg/return3.c | 0 .../link-cfg/with-deps.rs | 0 .../link-cfg/with-staticlib-deps.rs | 0 .../link-path-order/Makefile | 0 .../link-path-order/correct.c | 0 .../link-path-order/main.rs | 0 .../link-path-order/wrong.c | 0 .../linkage-attr-on-static/Makefile | 0 .../linkage-attr-on-static/bar.rs | 0 .../linkage-attr-on-static/foo.c | 0 .../linker-output-non-utf8/Makefile | 0 .../linker-output-non-utf8/exec.rs | 0 .../linker-output-non-utf8/library.rs | 0 .../llvm-pass/Makefile | 0 .../llvm-pass/llvm-function-pass.so.cc | 0 .../llvm-pass/llvm-module-pass.so.cc | 0 .../llvm-pass/main.rs | 0 .../llvm-pass/plugin.rs | 0 .../Makefile | 0 .../long-linker-command-lines-cmd-exe/foo.bat | 0 .../long-linker-command-lines-cmd-exe/foo.rs | 0 .../long-linker-command-lines/Makefile | 0 .../long-linker-command-lines/foo.rs | 0 .../longjmp-across-rust/Makefile | 0 .../longjmp-across-rust/foo.c | 0 .../longjmp-across-rust/main.rs | 0 .../ls-metadata/Makefile | 0 .../ls-metadata/foo.rs | 0 .../lto-no-link-whole-rlib/Makefile | 0 .../lto-no-link-whole-rlib/bar.c | 0 .../lto-no-link-whole-rlib/foo.c | 0 .../lto-no-link-whole-rlib/lib1.rs | 0 .../lto-no-link-whole-rlib/lib2.rs | 0 .../lto-no-link-whole-rlib/main.rs | 0 .../lto-readonly-lib/Makefile | 0 .../lto-readonly-lib/lib.rs | 0 .../lto-readonly-lib/main.rs | 0 .../lto-smoke-c/Makefile | 0 .../lto-smoke-c/bar.c | 0 .../lto-smoke-c/foo.rs | 0 .../lto-smoke/Makefile | 0 .../lto-smoke/lib.rs | 0 .../lto-smoke/main.rs | 0 .../manual-crate-name/Makefile | 0 .../manual-crate-name/bar.rs | 0 .../manual-link/Makefile | 0 .../manual-link/bar.c | 0 .../manual-link/foo.c | 0 .../manual-link/foo.rs | 0 .../manual-link/main.rs | 0 .../many-crates-but-no-match/Makefile | 0 .../many-crates-but-no-match/crateA1.rs | 0 .../many-crates-but-no-match/crateA2.rs | 0 .../many-crates-but-no-match/crateA3.rs | 0 .../many-crates-but-no-match/crateB.rs | 0 .../many-crates-but-no-match/crateC.rs | 0 .../metadata-flag-frobs-symbols/Makefile | 0 .../metadata-flag-frobs-symbols/bar.rs | 0 .../metadata-flag-frobs-symbols/foo.rs | 0 .../min-global-align/Makefile | 0 .../min-global-align/min_global_align.rs | 0 .../mismatching-target-triples/Makefile | 0 .../mismatching-target-triples/bar.rs | 0 .../mismatching-target-triples/foo.rs | 0 .../missing-crate-dependency/Makefile | 0 .../missing-crate-dependency/crateA.rs | 0 .../missing-crate-dependency/crateB.rs | 0 .../missing-crate-dependency/crateC.rs | 0 .../mixing-deps/Makefile | 0 .../mixing-deps/both.rs | 0 .../mixing-deps/dylib.rs | 0 .../mixing-deps/prog.rs | 0 .../mixing-formats/Makefile | 0 .../mixing-formats/bar1.rs | 0 .../mixing-formats/bar2.rs | 0 .../mixing-formats/baz.rs | 0 .../mixing-formats/baz2.rs | 0 .../mixing-formats/foo.rs | 0 .../mixing-libs/Makefile | 0 .../mixing-libs/dylib.rs | 0 .../mixing-libs/prog.rs | 0 .../mixing-libs/rlib.rs | 0 .../msvc-opt-minsize/Makefile | 0 .../msvc-opt-minsize/foo.rs | 0 .../multiple-emits/Makefile | 0 .../multiple-emits/foo.rs | 0 .../no-builtins-lto/Makefile | 0 .../no-builtins-lto/main.rs | 0 .../no-builtins-lto/no_builtins.rs | 0 .../no-duplicate-libs/Makefile | 0 .../no-duplicate-libs/bar.c | 0 .../no-duplicate-libs/foo.c | 0 .../no-duplicate-libs/main.rs | 0 .../no-integrated-as/Makefile | 0 .../no-integrated-as/hello.rs | 0 .../no-intermediate-extras/Makefile | 0 .../no-intermediate-extras/foo.rs | 0 .../obey-crate-type-flag/Makefile | 0 .../obey-crate-type-flag/test.rs | 0 .../Makefile | 0 .../foo.rs | 0 .../output-filename-overwrites-input/Makefile | 0 .../output-filename-overwrites-input/bar.rs | 0 .../output-filename-overwrites-input/foo.rs | 0 .../output-type-permutations/Makefile | 0 .../output-type-permutations/foo.rs | 0 .../output-with-hyphens/Makefile | 0 .../output-with-hyphens/foo-bar.rs | 0 .../prefer-dylib/Makefile | 0 .../prefer-dylib/bar.rs | 0 .../prefer-dylib/foo.rs | 0 .../prefer-rlib/Makefile | 0 .../prefer-rlib/bar.rs | 0 .../prefer-rlib/foo.rs | 0 .../pretty-expanded-hygiene/Makefile | 0 .../pretty-expanded-hygiene/input.pp.rs | 0 .../pretty-expanded-hygiene/input.rs | 0 .../pretty-expanded/Makefile | 0 .../pretty-expanded/input.rs | 0 .../pretty-print-path-suffix/Makefile | 0 .../pretty-print-path-suffix/foo.pp | 0 .../pretty-print-path-suffix/foo_method.pp | 0 .../pretty-print-path-suffix/input.rs | 0 .../pretty-print-path-suffix/nest_foo.pp | 0 .../pretty-print-to-file/Makefile | 0 .../pretty-print-to-file/input.pp | 0 .../pretty-print-to-file/input.rs | 0 .../print-cfg/Makefile | 0 .../print-target-list/Makefile | 0 .../profile/Makefile | 0 .../profile/test.rs | 0 .../prune-link-args/Makefile | 0 .../prune-link-args/empty.rs | 0 .../relocation-model/Makefile | 0 .../relocation-model/foo.rs | 0 .../relro-levels/Makefile | 0 .../relro-levels/hello.rs | 0 .../reproducible-build/Makefile | 0 .../reproducible-build/linker.rs | 0 .../reproducible-build-aux.rs | 0 .../reproducible-build/reproducible-build.rs | 0 .../rlib-chain/Makefile | 0 .../rlib-chain/m1.rs | 0 .../rlib-chain/m2.rs | 0 .../rlib-chain/m3.rs | 0 .../rlib-chain/m4.rs | 0 .../rustc-macro-dep-files/Makefile | 0 .../rustc-macro-dep-files/bar.rs | 0 .../rustc-macro-dep-files/foo.rs | 0 .../rustdoc-error-lines/Makefile | 0 .../rustdoc-error-lines/input.rs | 0 .../rustdoc-output-path/Makefile | 0 .../rustdoc-output-path/foo.rs | 0 .../sanitizer-address/Makefile | 0 .../sanitizer-address/overflow.rs | 0 .../sanitizer-cdylib-link/Makefile | 0 .../sanitizer-cdylib-link/library.rs | 0 .../sanitizer-cdylib-link/program.rs | 0 .../sanitizer-dylib-link/Makefile | 0 .../sanitizer-dylib-link/library.rs | 0 .../sanitizer-dylib-link/program.rs | 0 .../sanitizer-invalid-cratetype/Makefile | 0 .../sanitizer-invalid-cratetype/hello.rs | 0 .../sanitizer-invalid-target/Makefile | 0 .../sanitizer-invalid-target/hello.rs | 0 .../sanitizer-leak/Makefile | 0 .../sanitizer-leak/leak.rs | 0 .../sanitizer-memory/Makefile | 0 .../sanitizer-memory/uninit.rs | 0 .../sanitizer-staticlib-link/Makefile | 0 .../sanitizer-staticlib-link/library.rs | 0 .../sanitizer-staticlib-link/program.c | 0 .../save-analysis-fail/Makefile | 0 .../save-analysis-fail/SameDir.rs | 0 .../save-analysis-fail/SameDir3.rs | 0 .../save-analysis-fail/SubDir/mod.rs | 0 .../save-analysis-fail/foo.rs | 0 .../save-analysis-fail/krate2.rs | 0 .../save-analysis/Makefile | 0 .../save-analysis/SameDir.rs | 0 .../save-analysis/SameDir3.rs | 0 .../save-analysis/SubDir/mod.rs | 0 .../save-analysis/extra-docs.md | 0 .../save-analysis/foo.rs | 0 .../save-analysis/krate2.rs | 0 .../sepcomp-cci-copies/Makefile | 0 .../sepcomp-cci-copies/cci_lib.rs | 0 .../sepcomp-cci-copies/foo.rs | 0 .../sepcomp-inlining/Makefile | 0 .../sepcomp-inlining/foo.rs | 0 .../sepcomp-separate/Makefile | 0 .../sepcomp-separate/foo.rs | 0 .../simd-ffi/Makefile | 0 .../simd-ffi/simd.rs | 0 .../simple-dylib/Makefile | 0 .../simple-dylib/bar.rs | 0 .../simple-dylib/foo.rs | 0 .../simple-rlib/Makefile | 0 .../simple-rlib/bar.rs | 0 .../simple-rlib/foo.rs | 0 .../stable-symbol-names/Makefile | 0 .../stable-symbol-names1.rs | 0 .../stable-symbol-names2.rs | 0 .../static-dylib-by-default/Makefile | 0 .../static-dylib-by-default/bar.rs | 0 .../static-dylib-by-default/foo.rs | 0 .../static-dylib-by-default/main.c | 0 .../static-nobundle/Makefile | 0 .../static-nobundle/aaa.c | 0 .../static-nobundle/bbb.rs | 0 .../static-nobundle/ccc.rs | 0 .../static-nobundle/ddd.rs | 0 .../static-unwinding/Makefile | 0 .../static-unwinding/lib.rs | 0 .../static-unwinding/main.rs | 0 .../staticlib-blank-lib/Makefile | 0 .../staticlib-blank-lib/foo.rs | 0 .../stdin-non-utf8/Makefile | 0 .../stdin-non-utf8/non-utf8 | 0 .../suspicious-library/Makefile | 0 .../suspicious-library/bar.rs | 0 .../suspicious-library/foo.rs | 0 .../symbol-visibility/Makefile | 0 .../symbol-visibility/a_cdylib.rs | 0 .../symbol-visibility/a_rust_dylib.rs | 0 .../symbol-visibility/an_executable.rs | 0 .../symbol-visibility/an_rlib.rs | 0 .../symbols-are-reasonable/Makefile | 0 .../symbols-are-reasonable/lib.rs | 0 .../symbols-include-type-name/Makefile | 0 .../symbols-include-type-name/lib.rs | 0 .../symlinked-extern/Makefile | 0 .../symlinked-extern/bar.rs | 0 .../symlinked-extern/baz.rs | 0 .../symlinked-extern/foo.rs | 0 .../symlinked-libraries/Makefile | 0 .../symlinked-libraries/bar.rs | 0 .../symlinked-libraries/foo.rs | 0 .../symlinked-rlib/Makefile | 0 .../symlinked-rlib/bar.rs | 0 .../symlinked-rlib/foo.rs | 0 .../sysroot-crates-are-unstable/Makefile | 0 .../sysroot-crates-are-unstable/test.py | 0 .../target-cpu-native/Makefile | 0 .../target-cpu-native/foo.rs | 0 .../target-specs/Makefile | 0 .../target-specs/foo.rs | 0 .../target-specs/my-awesome-platform.json | 0 .../target-specs/my-incomplete-platform.json | 0 .../target-specs/my-invalid-platform.json | 0 .../my-x86_64-unknown-linux-gnu-platform.json | 0 .../target-without-atomics/Makefile | 0 .../test-harness/Makefile | 0 .../test-harness/test-ignore-cfg.rs | 0 .../{run-make => run-make-fulldeps}/tools.mk | 0 .../treat-err-as-bug/Makefile | 0 .../treat-err-as-bug/err.rs | 0 .../type-mismatch-same-crate-name/Makefile | 0 .../type-mismatch-same-crate-name/crateA.rs | 0 .../type-mismatch-same-crate-name/crateB.rs | 0 .../type-mismatch-same-crate-name/crateC.rs | 0 .../use-extern-for-plugins/Makefile | 0 .../use-extern-for-plugins/bar.rs | 0 .../use-extern-for-plugins/baz.rs | 0 .../use-extern-for-plugins/foo.rs | 0 .../used/Makefile | 0 .../used/used.rs | 0 .../version/Makefile | 0 .../volatile-intrinsics/Makefile | 0 .../volatile-intrinsics/main.rs | 0 .../weird-output-filenames/Makefile | 0 .../weird-output-filenames/foo.rs | 0 .../windows-spawn/Makefile | 0 .../windows-spawn/hello.rs | 0 .../windows-spawn/spawn.rs | 0 .../windows-subsystem/Makefile | 0 .../windows-subsystem/console.rs | 0 .../windows-subsystem/windows.rs | 0 .../run-make/wasm-custom-section/Makefile | 10 +++ src/test/run-make/wasm-custom-section/bar.rs | 24 +++++++ src/test/run-make/wasm-custom-section/foo.js | 46 +++++++++++++ src/test/run-make/wasm-custom-section/foo.rs | 19 ++++++ .../ui/feature-gate-wasm_custom_section.rs | 14 ++++ .../feature-gate-wasm_custom_section.stderr | 11 ++++ src/test/ui/wasm-custom-section/malformed.rs | 19 ++++++ .../ui/wasm-custom-section/malformed.stderr | 14 ++++ src/test/ui/wasm-custom-section/not-const.rs | 29 ++++++++ .../ui/wasm-custom-section/not-const.stderr | 38 +++++++++++ src/test/ui/wasm-custom-section/not-slice.rs | 22 +++++++ .../ui/wasm-custom-section/not-slice.stderr | 20 ++++++ src/tools/compiletest/src/runtest.rs | 15 +++-- 575 files changed, 522 insertions(+), 17 deletions(-) create mode 100644 src/librustc_trans/back/wasm.rs rename src/test/{run-make => run-make-fulldeps}/a-b-a-linker-guard/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/a-b-a-linker-guard/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/a-b-a-linker-guard/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/alloc-extern-crates/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/alloc-extern-crates/fakealloc.rs (100%) rename src/test/{run-make => run-make-fulldeps}/allow-non-lint-warnings-cmdline/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/allow-non-lint-warnings-cmdline/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/allow-warnings-cmdline-stability/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/allow-warnings-cmdline-stability/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/allow-warnings-cmdline-stability/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/archive-duplicate-names/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/atomic-lock-free/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/atomic-lock-free/atomic_lock_free.rs (100%) rename src/test/{run-make => run-make-fulldeps}/bare-outfile/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/bare-outfile/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-dynamic-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-dylib/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-staticlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-staticlib/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-link-to-rust-staticlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/cfoo.c (100%) rename src/test/{run-make => run-make-fulldeps}/c-static-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/cat-and-grep-sanity-check/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib-fewer-symbols/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib-fewer-symbols/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/cdylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/codegen-options-parsing/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/codegen-options-parsing/dummy.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compile-stdin/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths-2/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/d.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/e.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/e2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/f.rs (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-lookup-paths/native.c (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-rt-works-on-mingw/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-rt-works-on-mingw/foo.cpp (100%) rename src/test/{run-make => run-make-fulldeps}/compiler-rt-works-on-mingw/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/crate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-data-smoke/rlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-name-priority/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/crate-name-priority/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/crate-name-priority/foo1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/debug-assertions/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/debug-assertions/debug.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-doesnt-run-much/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-doesnt-run-much/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/Makefile.foo (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/foo foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info-spaces/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/Makefile.foo (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dep-info/lib2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/duplicate-output-flavors/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/duplicate-output-flavors/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/dylib-chain/m4.rs (100%) rename src/test/{run-make => run-make-fulldeps}/emit/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/emit/test-24876.rs (100%) rename src/test/{run-make => run-make-fulldeps}/emit/test-26235.rs (100%) rename src/test/{run-make => run-make-fulldeps}/error-found-staticlib-instead-crate/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/error-found-staticlib-instead-crate/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/error-found-staticlib-instead-crate/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/error-writing-dependencies/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/error-writing-dependencies/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-diff-internal-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-diff-internal-name/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-diff-internal-name/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-disambiguates/d.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/bar-alt.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-flag-fun/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-generic/testcrate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-mangle/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-mangle/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-mangle/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-reachable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-reachable/dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-reachable/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-struct-passing-abi/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-struct-passing-abi/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-struct-passing-abi/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-extern-types/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-extern-types/ctest.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-extern-types/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-packed-struct/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-packed-struct/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-packed-struct/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/ctest.c (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-fn-with-union/testcrate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/foo1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies/foo2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/foo1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-multiple-copies2/foo2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-overrides-distribution/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extern-overrides-distribution/libc.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extern-overrides-distribution/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/extra-filename-with-temp-outputs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/extra-filename-with-temp-outputs/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/fpic/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/fpic/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/hir-tree/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/hir-tree/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/hotplug_codegen_backend/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/hotplug_codegen_backend/some_crate.rs (100%) rename src/test/{run-make => run-make-fulldeps}/hotplug_codegen_backend/the_backend.rs (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/input.bin (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/input.md (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/input.txt (100%) rename src/test/{run-make => run-make-fulldeps}/include_bytes_deps/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/inline-always-many-cgu/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/inline-always-many-cgu/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/interdependent-c-libraries/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/intrinsic-unreachable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/intrinsic-unreachable/exit-ret.rs (100%) rename src/test/{run-make => run-make-fulldeps}/intrinsic-unreachable/exit-unreachable.rs (100%) rename src/test/{run-make => run-make-fulldeps}/invalid-library/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/invalid-library/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/invalid-staticlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-11908/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-11908/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-11908/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14500/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14698/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-14698/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-15460/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-18943/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-18943/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-19371/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-19371/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-20626/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-20626/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-22131/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-22131/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-24445/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-24445/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-24445/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-25581/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-25581/test.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-25581/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26006/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26006/in/libc/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26006/in/time/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26092/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-26092/blank.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/a.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/b.c (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28595/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28766/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28766/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-28766/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-30063/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-30063/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-33329/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-33329/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-35164/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-35164/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-35164/submodule/mod.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37839/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/b.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-37893/c.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-38237/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-40535/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-46239/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-46239/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issue-7349/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issue-7349/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/issues-41478-43796/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/issues-41478-43796/a.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libs-and-bins/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/libs-and-bins/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libs-through-symlinks/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/libs-through-symlinks/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libs-through-symlinks/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/f.rs (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/output.json (100%) rename src/test/{run-make => run-make-fulldeps}/libtest-json/validate_json.py (100%) rename src/test/{run-make => run-make-fulldeps}/link-arg/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/link-arg/empty.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/dep-with-staticlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/dep.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/no-deps.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/return1.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/return2.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/return3.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/with-deps.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-cfg/with-staticlib-deps.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/correct.c (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/link-path-order/wrong.c (100%) rename src/test/{run-make => run-make-fulldeps}/linkage-attr-on-static/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/linkage-attr-on-static/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/linkage-attr-on-static/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/linker-output-non-utf8/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/linker-output-non-utf8/exec.rs (100%) rename src/test/{run-make => run-make-fulldeps}/linker-output-non-utf8/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/llvm-function-pass.so.cc (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/llvm-module-pass.so.cc (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/llvm-pass/plugin.rs (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines-cmd-exe/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines-cmd-exe/foo.bat (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines-cmd-exe/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/long-linker-command-lines/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/longjmp-across-rust/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/longjmp-across-rust/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/longjmp-across-rust/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/ls-metadata/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/ls-metadata/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/lib1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/lib2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-no-link-whole-rlib/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-readonly-lib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-readonly-lib/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-readonly-lib/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke-c/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke-c/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke-c/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/lto-smoke/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/manual-crate-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/manual-crate-name/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/manual-link/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateA1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateA2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateA3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateB.rs (100%) rename src/test/{run-make => run-make-fulldeps}/many-crates-but-no-match/crateC.rs (100%) rename src/test/{run-make => run-make-fulldeps}/metadata-flag-frobs-symbols/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/metadata-flag-frobs-symbols/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/metadata-flag-frobs-symbols/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/min-global-align/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/min-global-align/min_global_align.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mismatching-target-triples/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mismatching-target-triples/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mismatching-target-triples/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/crateA.rs (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/crateB.rs (100%) rename src/test/{run-make => run-make-fulldeps}/missing-crate-dependency/crateC.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/both.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-deps/prog.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/bar1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/bar2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/baz2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-formats/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/prog.rs (100%) rename src/test/{run-make => run-make-fulldeps}/mixing-libs/rlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/msvc-opt-minsize/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/msvc-opt-minsize/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/multiple-emits/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/multiple-emits/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-builtins-lto/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-builtins-lto/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-builtins-lto/no_builtins.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/bar.c (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/foo.c (100%) rename src/test/{run-make => run-make-fulldeps}/no-duplicate-libs/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-integrated-as/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-integrated-as/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/no-intermediate-extras/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/no-intermediate-extras/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/obey-crate-type-flag/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/obey-crate-type-flag/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-conflicts-with-directory/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-conflicts-with-directory/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-overwrites-input/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-overwrites-input/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-filename-overwrites-input/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-type-permutations/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-type-permutations/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/output-with-hyphens/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/output-with-hyphens/foo-bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prefer-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded-hygiene/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded-hygiene/input.pp.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded-hygiene/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-expanded/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/foo.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/foo_method.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-path-suffix/nest_foo.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-to-file/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-to-file/input.pp (100%) rename src/test/{run-make => run-make-fulldeps}/pretty-print-to-file/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/print-cfg/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/print-target-list/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/profile/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/profile/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/prune-link-args/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/prune-link-args/empty.rs (100%) rename src/test/{run-make => run-make-fulldeps}/relocation-model/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/relocation-model/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/relro-levels/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/relro-levels/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/linker.rs (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/reproducible-build-aux.rs (100%) rename src/test/{run-make => run-make-fulldeps}/reproducible-build/reproducible-build.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rlib-chain/m4.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustc-macro-dep-files/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rustc-macro-dep-files/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustc-macro-dep-files/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-error-lines/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-error-lines/input.rs (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-output-path/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/rustdoc-output-path/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-address/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-address/overflow.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-cdylib-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-cdylib-link/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-cdylib-link/program.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-dylib-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-dylib-link/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-dylib-link/program.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-cratetype/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-cratetype/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-target/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-invalid-target/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-leak/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-leak/leak.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-memory/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-memory/uninit.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-staticlib-link/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-staticlib-link/library.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sanitizer-staticlib-link/program.c (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/SameDir.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/SameDir3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/SubDir/mod.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis-fail/krate2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/SameDir.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/SameDir3.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/SubDir/mod.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/extra-docs.md (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/save-analysis/krate2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-cci-copies/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-cci-copies/cci_lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-cci-copies/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-inlining/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-inlining/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-separate/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sepcomp-separate/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simd-ffi/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/simd-ffi/simd.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-dylib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/simple-dylib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-dylib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/simple-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/simple-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/stable-symbol-names/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/stable-symbol-names/stable-symbol-names1.rs (100%) rename src/test/{run-make => run-make-fulldeps}/stable-symbol-names/stable-symbol-names2.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-dylib-by-default/main.c (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/aaa.c (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/bbb.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/ccc.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-nobundle/ddd.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-unwinding/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/static-unwinding/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/static-unwinding/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/staticlib-blank-lib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/staticlib-blank-lib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/stdin-non-utf8/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/stdin-non-utf8/non-utf8 (100%) rename src/test/{run-make => run-make-fulldeps}/suspicious-library/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/suspicious-library/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/suspicious-library/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/a_cdylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/a_rust_dylib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/an_executable.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbol-visibility/an_rlib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-are-reasonable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-are-reasonable/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-include-type-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symbols-include-type-name/lib.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-extern/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-libraries/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-libraries/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-libraries/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-rlib/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-rlib/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/symlinked-rlib/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/sysroot-crates-are-unstable/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/sysroot-crates-are-unstable/test.py (100%) rename src/test/{run-make => run-make-fulldeps}/target-cpu-native/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/target-cpu-native/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-awesome-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-incomplete-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-invalid-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-specs/my-x86_64-unknown-linux-gnu-platform.json (100%) rename src/test/{run-make => run-make-fulldeps}/target-without-atomics/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/test-harness/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/test-harness/test-ignore-cfg.rs (100%) rename src/test/{run-make => run-make-fulldeps}/tools.mk (100%) rename src/test/{run-make => run-make-fulldeps}/treat-err-as-bug/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/treat-err-as-bug/err.rs (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/crateA.rs (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/crateB.rs (100%) rename src/test/{run-make => run-make-fulldeps}/type-mismatch-same-crate-name/crateC.rs (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/bar.rs (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/baz.rs (100%) rename src/test/{run-make => run-make-fulldeps}/use-extern-for-plugins/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/used/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/used/used.rs (100%) rename src/test/{run-make => run-make-fulldeps}/version/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/volatile-intrinsics/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/volatile-intrinsics/main.rs (100%) rename src/test/{run-make => run-make-fulldeps}/weird-output-filenames/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/weird-output-filenames/foo.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-spawn/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/windows-spawn/hello.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-spawn/spawn.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-subsystem/Makefile (100%) rename src/test/{run-make => run-make-fulldeps}/windows-subsystem/console.rs (100%) rename src/test/{run-make => run-make-fulldeps}/windows-subsystem/windows.rs (100%) create mode 100644 src/test/run-make/wasm-custom-section/Makefile create mode 100644 src/test/run-make/wasm-custom-section/bar.rs create mode 100644 src/test/run-make/wasm-custom-section/foo.js create mode 100644 src/test/run-make/wasm-custom-section/foo.rs create mode 100644 src/test/ui/feature-gate-wasm_custom_section.rs create mode 100644 src/test/ui/feature-gate-wasm_custom_section.stderr create mode 100644 src/test/ui/wasm-custom-section/malformed.rs create mode 100644 src/test/ui/wasm-custom-section/malformed.stderr create mode 100644 src/test/ui/wasm-custom-section/not-const.rs create mode 100644 src/test/ui/wasm-custom-section/not-const.stderr create mode 100644 src/test/ui/wasm-custom-section/not-slice.rs create mode 100644 src/test/ui/wasm-custom-section/not-slice.stderr diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a398bcc97374..2e094a889820 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -313,6 +313,7 @@ impl<'a> Builder<'a> { test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::Crate, test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::ErrorIndex, test::Distcheck, + test::RunMakeFullDeps, test::Nomicon, test::Reference, test::RustdocBook, test::RustByExample, test::TheBook, test::UnstableBook, test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 86263c8fa073..2640248373c3 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -915,7 +915,7 @@ impl Step for Assemble { } } - let lld_install = if build.config.lld_enabled && target_compiler.stage > 0 { + let lld_install = if build.config.lld_enabled { Some(builder.ensure(native::Lld { target: target_compiler.host, })) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index de938ec8e830..6c19da4648a2 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -759,12 +759,18 @@ test!(RunFailFullDepsPretty { host: true }); -host_test!(RunMake { +default_test!(RunMake { path: "src/test/run-make", mode: "run-make", suite: "run-make" }); +host_test!(RunMakeFullDeps { + path: "src/test/run-make-fulldeps", + mode: "run-make", + suite: "run-make-fulldeps" +}); + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] struct Compiletest { compiler: Compiler, @@ -827,8 +833,7 @@ impl Step for Compiletest { // FIXME: Does pretty need librustc compiled? Note that there are // fulldeps test suites with mode = pretty as well. mode == "pretty" || - mode == "rustdoc" || - mode == "run-make" { + mode == "rustdoc" { builder.ensure(compile::Rustc { compiler, target }); } @@ -849,7 +854,7 @@ impl Step for Compiletest { cmd.arg("--rustc-path").arg(builder.rustc(compiler)); // Avoid depending on rustdoc when we don't need it. - if mode == "rustdoc" || mode == "run-make" { + if mode == "rustdoc" || (mode == "run-make" && suite.ends_with("fulldeps")) { cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host)); } @@ -931,7 +936,7 @@ impl Step for Compiletest { // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. - if suite == "run-make" { + if suite == "run-make-fulldeps" { let llvm_components = output(Command::new(&llvm_config).arg("--components")); let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags")); cmd.arg("--cc").arg(build.cc(target)) @@ -944,12 +949,12 @@ impl Step for Compiletest { } } } - if suite == "run-make" && !build.config.llvm_enabled { + if suite == "run-make-fulldeps" && !build.config.llvm_enabled { println!("Ignoring run-make test suite as they generally don't work without LLVM"); return; } - if suite != "run-make" { + if suite != "run-make-fulldeps" { cmd.arg("--cc").arg("") .arg("--cxx").arg("") .arg("--cflags").arg("") diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 1e2e4e5a69fa..09d7ce599ab0 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -650,6 +650,8 @@ define_dep_nodes!( <'tcx> [] GetSymbolExportLevel(DefId), + [] WasmCustomSections(CrateNum), + [input] Features, [] ProgramClausesFor(DefId), diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index d7194e9c2cab..f141cac16148 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -25,6 +25,7 @@ enum Target { Struct, Union, Enum, + Const, Other, } @@ -35,6 +36,7 @@ impl Target { hir::ItemStruct(..) => Target::Struct, hir::ItemUnion(..) => Target::Union, hir::ItemEnum(..) => Target::Enum, + hir::ItemConst(..) => Target::Const, _ => Target::Other, } } @@ -60,6 +62,17 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { if name == "inline" { self.check_inline(attr, item, target) } + + if name == "wasm_custom_section" { + if target != Target::Const { + self.tcx.sess.span_err(attr.span, "only allowed on consts"); + } + + if attr.value_str().is_none() { + self.tcx.sess.span_err(attr.span, "must be of the form \ + #[wasm_custom_section = \"foo\"]"); + } + } } } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 1ff9c7a86291..abd52624c30d 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -318,6 +318,11 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt, return true; } + // These constants are special for wasm + if attr::contains_name(attrs, "wasm_custom_section") { + return true; + } + tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow } diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 117d92193123..0b41c3ab2fa2 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -678,6 +678,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> } } +impl<'tcx> QueryDescription<'tcx> for queries::wasm_custom_sections<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("custom wasm sections for a crate") + } +} + impl<'tcx> QueryDescription<'tcx> for queries::generics_of<'tcx> { #[inline] fn cache_on_disk(def_id: Self::Key) -> bool { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 6c3b4efb932a..2b4c1992762e 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -424,6 +424,8 @@ define_maps! { <'tcx> [] fn features_query: features_node(CrateNum) -> Lrc, [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc>>, + + [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc>, } ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 4170fa767971..910c00b832ef 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -940,6 +940,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::Features => { force!(features_query, LOCAL_CRATE); } DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); } + DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); } } true diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 2de27f3a1c3e..3c2f984ef8b3 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -271,6 +271,8 @@ provide! { <'tcx> tcx, def_id, other, cdata, Arc::new(cdata.exported_symbols()) } + + wasm_custom_sections => { Lrc::new(cdata.wasm_custom_sections()) } } pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index b0c945fbf2a0..0e5df3142af6 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1067,6 +1067,16 @@ impl<'a, 'tcx> CrateMetadata { .collect() } + pub fn wasm_custom_sections(&self) -> Vec { + let sections = self.root + .wasm_custom_sections + .decode(self) + .map(|def_index| self.local_def_id(def_index)) + .collect::>(); + info!("loaded wasm sections {:?}", sections); + return sections + } + pub fn get_macro(&self, id: DefIndex) -> (InternedString, MacroDef) { let entry = self.entry(id); match entry.kind { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 6b3453f2c99e..56981b8f4a1e 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -435,6 +435,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { &exported_symbols); let exported_symbols_bytes = self.position() - i; + // encode wasm custom sections + let wasm_custom_sections = self.tcx.wasm_custom_sections(LOCAL_CRATE); + let wasm_custom_sections = self.tracked( + IsolatedEncoder::encode_wasm_custom_sections, + &wasm_custom_sections); + // Encode and index the items. i = self.position(); let items = self.encode_info_for_items(); @@ -478,6 +484,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_path_table, impls, exported_symbols, + wasm_custom_sections, index, }); @@ -1444,6 +1451,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { .cloned()) } + fn encode_wasm_custom_sections(&mut self, statics: &[DefId]) -> LazySeq { + info!("encoding custom wasm section constants {:?}", statics); + self.lazy_seq(statics.iter().map(|id| id.index)) + } + fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq> { match self.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) { Some(arr) => { diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 593f08e90bb3..001772623e75 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -204,6 +204,7 @@ pub struct CrateRoot { pub def_path_table: Lazy, pub impls: LazySeq, pub exported_symbols: LazySeq<(ExportedSymbol, SymbolExportLevel)>, + pub wasm_custom_sections: LazySeq, pub index: LazySeq, } diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index 040d9455334b..16253aa92acc 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -11,9 +11,11 @@ use std::ffi::{CStr, CString}; -use rustc::hir::TransFnAttrFlags; +use rustc::hir::{self, TransFnAttrFlags}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::session::config::Sanitizer; +use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc_data_structures::sync::Lrc; @@ -161,4 +163,32 @@ pub fn provide(providers: &mut Providers) { .collect()) } }; + + providers.wasm_custom_sections = |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + let mut finder = WasmSectionFinder { tcx, list: Vec::new() }; + tcx.hir.krate().visit_all_item_likes(&mut finder); + Lrc::new(finder.list) + }; +} + +struct WasmSectionFinder<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + list: Vec, +} + +impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for WasmSectionFinder<'a, 'tcx> { + fn visit_item(&mut self, i: &'tcx hir::Item) { + match i.node { + hir::ItemConst(..) => {} + _ => return, + } + if i.attrs.iter().any(|i| i.check_name("wasm_custom_section")) { + self.list.push(self.tcx.hir.local_def_id(i.id)); + } + } + + fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {} + + fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {} } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index bdda7741221f..8e8ba823b6f8 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use back::wasm; use cc::windows_registry; use super::archive::{ArchiveBuilder, ArchiveConfig}; use super::bytecode::RLIB_BYTECODE_EXTENSION; @@ -810,6 +811,11 @@ fn link_natively(sess: &Session, Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)), } } + + if sess.opts.target_triple == "wasm32-unknown-unknown" { + wasm::add_custom_sections(&out_filename, + &trans.crate_info.wasm_custom_sections); + } } fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path) diff --git a/src/librustc_trans/back/wasm.rs b/src/librustc_trans/back/wasm.rs new file mode 100644 index 000000000000..99f1e4b7e78f --- /dev/null +++ b/src/librustc_trans/back/wasm.rs @@ -0,0 +1,44 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fs; +use std::path::Path; +use std::collections::BTreeMap; + +use serialize::leb128; + +pub fn add_custom_sections(path: &Path, sections: &BTreeMap>) { + let mut wasm = fs::read(path).expect("failed to read wasm output"); + + // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section + for (section, bytes) in sections { + // write the `id` identifier, 0 for a custom section + let len = wasm.len(); + leb128::write_u32_leb128(&mut wasm, len, 0); + + // figure out how long our name descriptor will be + let mut name = Vec::new(); + leb128::write_u32_leb128(&mut name, 0, section.len() as u32); + name.extend_from_slice(section.as_bytes()); + + // write the length of the payload + let len = wasm.len(); + let total_len = bytes.len() + name.len(); + leb128::write_u32_leb128(&mut wasm, len, total_len as u32); + + // write out the name section + wasm.extend(name); + + // and now the payload itself + wasm.extend_from_slice(bytes); + } + + fs::write(path, &wasm).expect("failed to write wasm output"); +} diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 4da082e9d50f..11f952bc5bc7 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -74,6 +74,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; use std::any::Any; +use std::collections::BTreeMap; use std::ffi::CString; use std::str; use std::sync::Arc; @@ -1070,8 +1071,24 @@ impl CrateInfo { used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic), used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic), used_crate_source: FxHashMap(), + wasm_custom_sections: BTreeMap::new(), }; + let load_wasm_sections = tcx.sess.crate_types.borrow() + .iter() + .any(|c| *c != config::CrateTypeRlib) && + tcx.sess.opts.target_triple == "wasm32-unknown-unknown"; + + if load_wasm_sections { + info!("attempting to load all wasm sections"); + for &id in tcx.wasm_custom_sections(LOCAL_CRATE).iter() { + let (name, contents) = fetch_wasm_section(tcx, id); + info.wasm_custom_sections.entry(name) + .or_insert(Vec::new()) + .extend(contents); + } + } + for &cnum in tcx.crates().iter() { info.native_libraries.insert(cnum, tcx.native_libraries(cnum)); info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string()); @@ -1091,6 +1108,14 @@ impl CrateInfo { if tcx.is_no_builtins(cnum) { info.is_no_builtins.insert(cnum); } + if load_wasm_sections { + for &id in tcx.wasm_custom_sections(cnum).iter() { + let (name, contents) = fetch_wasm_section(tcx, id); + info.wasm_custom_sections.entry(name) + .or_insert(Vec::new()) + .extend(contents); + } + } } @@ -1270,3 +1295,44 @@ mod temp_stable_hash_impls { } } } + +fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec) { + use rustc::mir::interpret::{GlobalId, Value, PrimVal}; + use rustc::middle::const_val::ConstVal; + + info!("loading wasm section {:?}", id); + + let section = tcx.get_attrs(id) + .iter() + .find(|a| a.check_name("wasm_custom_section")) + .expect("missing #[wasm_custom_section] attribute") + .value_str() + .expect("malformed #[wasm_custom_section] attribute"); + + let instance = ty::Instance::mono(tcx, id); + let cid = GlobalId { + instance, + promoted: None + }; + let param_env = ty::ParamEnv::reveal_all(); + let val = tcx.const_eval(param_env.and(cid)).unwrap(); + + let val = match val.val { + ConstVal::Value(val) => val, + ConstVal::Unevaluated(..) => bug!("should be evaluated"), + }; + let val = match val { + Value::ByRef(ptr, _align) => ptr.into_inner_primval(), + ref v => bug!("should be ByRef, was {:?}", v), + }; + let mem = match val { + PrimVal::Ptr(mem) => mem, + ref v => bug!("should be Ptr, was {:?}", v), + }; + assert_eq!(mem.offset, 0); + let alloc = tcx + .interpret_interner + .get_alloc(mem.alloc_id) + .expect("miri allocation never successfully created"); + (section.to_string(), alloc.bytes.clone()) +} diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 337f85a38139..bb2aeca37488 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -72,6 +72,7 @@ pub use llvm_util::target_features; use std::any::Any; use std::path::PathBuf; use std::sync::mpsc; +use std::collections::BTreeMap; use rustc_data_structures::sync::Lrc; use rustc::dep_graph::DepGraph; @@ -98,6 +99,7 @@ mod back { pub mod symbol_export; pub mod write; mod rpath; + mod wasm; } mod abi; @@ -400,6 +402,7 @@ struct CrateInfo { used_crate_source: FxHashMap>, used_crates_static: Vec<(CrateNum, LibSource)>, used_crates_dynamic: Vec<(CrateNum, LibSource)>, + wasm_custom_sections: BTreeMap>, } __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 69879bbe85d6..f86fe1fb7564 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1182,9 +1182,15 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item let _indenter = indenter(); match it.node { // Consts can play a role in type-checking, so they are included here. - hir::ItemStatic(..) | + hir::ItemStatic(..) => { + tcx.typeck_tables_of(tcx.hir.local_def_id(it.id)); + } hir::ItemConst(..) => { tcx.typeck_tables_of(tcx.hir.local_def_id(it.id)); + if it.attrs.iter().any(|a| a.check_name("wasm_custom_section")) { + let def_id = tcx.hir.local_def_id(it.id); + check_const_is_u8_array(tcx, def_id, it.span); + } } hir::ItemEnum(ref enum_definition, _) => { check_enum(tcx, @@ -1256,6 +1262,21 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item } } +fn check_const_is_u8_array<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId, + span: Span) { + match tcx.type_of(def_id).sty { + ty::TyArray(t, _) => { + match t.sty { + ty::TyUint(ast::UintTy::U8) => return, + _ => {} + } + } + _ => {} + } + tcx.sess.span_err(span, "must be an array of bytes like `[u8; N]`"); +} + fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_def_id: DefId, item: &hir::Item) { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 915396d29fe2..dbcfee208ca2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -451,6 +451,9 @@ declare_features! ( // `use path as _;` and `extern crate c as _;` (active, underscore_imports, "1.26.0", Some(48216), None), + + // The #[wasm_custom_section] attribute + (active, wasm_custom_section, "1.26.0", None, None), ); declare_features! ( @@ -1004,6 +1007,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "never will be stable", cfg_fn!(rustc_attrs))), + ("wasm_custom_section", Whitelisted, Gated(Stability::Unstable, + "wasm_custom_section", + "attribute is currently unstable", + cfg_fn!(wasm_custom_section))), + // Crate level attributes ("crate_name", CrateLevel, Ungated), ("crate_type", CrateLevel, Ungated), diff --git a/src/test/run-make/a-b-a-linker-guard/Makefile b/src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile similarity index 100% rename from src/test/run-make/a-b-a-linker-guard/Makefile rename to src/test/run-make-fulldeps/a-b-a-linker-guard/Makefile diff --git a/src/test/run-make/a-b-a-linker-guard/a.rs b/src/test/run-make-fulldeps/a-b-a-linker-guard/a.rs similarity index 100% rename from src/test/run-make/a-b-a-linker-guard/a.rs rename to src/test/run-make-fulldeps/a-b-a-linker-guard/a.rs diff --git a/src/test/run-make/a-b-a-linker-guard/b.rs b/src/test/run-make-fulldeps/a-b-a-linker-guard/b.rs similarity index 100% rename from src/test/run-make/a-b-a-linker-guard/b.rs rename to src/test/run-make-fulldeps/a-b-a-linker-guard/b.rs diff --git a/src/test/run-make/alloc-extern-crates/Makefile b/src/test/run-make-fulldeps/alloc-extern-crates/Makefile similarity index 100% rename from src/test/run-make/alloc-extern-crates/Makefile rename to src/test/run-make-fulldeps/alloc-extern-crates/Makefile diff --git a/src/test/run-make/alloc-extern-crates/fakealloc.rs b/src/test/run-make-fulldeps/alloc-extern-crates/fakealloc.rs similarity index 100% rename from src/test/run-make/alloc-extern-crates/fakealloc.rs rename to src/test/run-make-fulldeps/alloc-extern-crates/fakealloc.rs diff --git a/src/test/run-make/allow-non-lint-warnings-cmdline/Makefile b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile similarity index 100% rename from src/test/run-make/allow-non-lint-warnings-cmdline/Makefile rename to src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile diff --git a/src/test/run-make/allow-non-lint-warnings-cmdline/foo.rs b/src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs similarity index 100% rename from src/test/run-make/allow-non-lint-warnings-cmdline/foo.rs rename to src/test/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs diff --git a/src/test/run-make/allow-warnings-cmdline-stability/Makefile b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile similarity index 100% rename from src/test/run-make/allow-warnings-cmdline-stability/Makefile rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile diff --git a/src/test/run-make/allow-warnings-cmdline-stability/bar.rs b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs similarity index 100% rename from src/test/run-make/allow-warnings-cmdline-stability/bar.rs rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs diff --git a/src/test/run-make/allow-warnings-cmdline-stability/foo.rs b/src/test/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs similarity index 100% rename from src/test/run-make/allow-warnings-cmdline-stability/foo.rs rename to src/test/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs diff --git a/src/test/run-make/archive-duplicate-names/Makefile b/src/test/run-make-fulldeps/archive-duplicate-names/Makefile similarity index 100% rename from src/test/run-make/archive-duplicate-names/Makefile rename to src/test/run-make-fulldeps/archive-duplicate-names/Makefile diff --git a/src/test/run-make/archive-duplicate-names/bar.c b/src/test/run-make-fulldeps/archive-duplicate-names/bar.c similarity index 100% rename from src/test/run-make/archive-duplicate-names/bar.c rename to src/test/run-make-fulldeps/archive-duplicate-names/bar.c diff --git a/src/test/run-make/archive-duplicate-names/bar.rs b/src/test/run-make-fulldeps/archive-duplicate-names/bar.rs similarity index 100% rename from src/test/run-make/archive-duplicate-names/bar.rs rename to src/test/run-make-fulldeps/archive-duplicate-names/bar.rs diff --git a/src/test/run-make/archive-duplicate-names/foo.c b/src/test/run-make-fulldeps/archive-duplicate-names/foo.c similarity index 100% rename from src/test/run-make/archive-duplicate-names/foo.c rename to src/test/run-make-fulldeps/archive-duplicate-names/foo.c diff --git a/src/test/run-make/archive-duplicate-names/foo.rs b/src/test/run-make-fulldeps/archive-duplicate-names/foo.rs similarity index 100% rename from src/test/run-make/archive-duplicate-names/foo.rs rename to src/test/run-make-fulldeps/archive-duplicate-names/foo.rs diff --git a/src/test/run-make/atomic-lock-free/Makefile b/src/test/run-make-fulldeps/atomic-lock-free/Makefile similarity index 100% rename from src/test/run-make/atomic-lock-free/Makefile rename to src/test/run-make-fulldeps/atomic-lock-free/Makefile diff --git a/src/test/run-make/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs similarity index 100% rename from src/test/run-make/atomic-lock-free/atomic_lock_free.rs rename to src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs diff --git a/src/test/run-make/bare-outfile/Makefile b/src/test/run-make-fulldeps/bare-outfile/Makefile similarity index 100% rename from src/test/run-make/bare-outfile/Makefile rename to src/test/run-make-fulldeps/bare-outfile/Makefile diff --git a/src/test/run-make/bare-outfile/foo.rs b/src/test/run-make-fulldeps/bare-outfile/foo.rs similarity index 100% rename from src/test/run-make/bare-outfile/foo.rs rename to src/test/run-make-fulldeps/bare-outfile/foo.rs diff --git a/src/test/run-make/c-dynamic-dylib/Makefile b/src/test/run-make-fulldeps/c-dynamic-dylib/Makefile similarity index 100% rename from src/test/run-make/c-dynamic-dylib/Makefile rename to src/test/run-make-fulldeps/c-dynamic-dylib/Makefile diff --git a/src/test/run-make/c-dynamic-dylib/bar.rs b/src/test/run-make-fulldeps/c-dynamic-dylib/bar.rs similarity index 100% rename from src/test/run-make/c-dynamic-dylib/bar.rs rename to src/test/run-make-fulldeps/c-dynamic-dylib/bar.rs diff --git a/src/test/run-make/c-dynamic-dylib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c similarity index 100% rename from src/test/run-make/c-dynamic-dylib/cfoo.c rename to src/test/run-make-fulldeps/c-dynamic-dylib/cfoo.c diff --git a/src/test/run-make/c-dynamic-dylib/foo.rs b/src/test/run-make-fulldeps/c-dynamic-dylib/foo.rs similarity index 100% rename from src/test/run-make/c-dynamic-dylib/foo.rs rename to src/test/run-make-fulldeps/c-dynamic-dylib/foo.rs diff --git a/src/test/run-make/c-dynamic-rlib/Makefile b/src/test/run-make-fulldeps/c-dynamic-rlib/Makefile similarity index 100% rename from src/test/run-make/c-dynamic-rlib/Makefile rename to src/test/run-make-fulldeps/c-dynamic-rlib/Makefile diff --git a/src/test/run-make/c-dynamic-rlib/bar.rs b/src/test/run-make-fulldeps/c-dynamic-rlib/bar.rs similarity index 100% rename from src/test/run-make/c-dynamic-rlib/bar.rs rename to src/test/run-make-fulldeps/c-dynamic-rlib/bar.rs diff --git a/src/test/run-make/c-dynamic-rlib/cfoo.c b/src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c similarity index 100% rename from src/test/run-make/c-dynamic-rlib/cfoo.c rename to src/test/run-make-fulldeps/c-dynamic-rlib/cfoo.c diff --git a/src/test/run-make/c-dynamic-rlib/foo.rs b/src/test/run-make-fulldeps/c-dynamic-rlib/foo.rs similarity index 100% rename from src/test/run-make/c-dynamic-rlib/foo.rs rename to src/test/run-make-fulldeps/c-dynamic-rlib/foo.rs diff --git a/src/test/run-make/c-link-to-rust-dylib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile similarity index 100% rename from src/test/run-make/c-link-to-rust-dylib/Makefile rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/Makefile diff --git a/src/test/run-make/c-link-to-rust-dylib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c similarity index 100% rename from src/test/run-make/c-link-to-rust-dylib/bar.c rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/bar.c diff --git a/src/test/run-make/c-link-to-rust-dylib/foo.rs b/src/test/run-make-fulldeps/c-link-to-rust-dylib/foo.rs similarity index 100% rename from src/test/run-make/c-link-to-rust-dylib/foo.rs rename to src/test/run-make-fulldeps/c-link-to-rust-dylib/foo.rs diff --git a/src/test/run-make/c-link-to-rust-staticlib/Makefile b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile similarity index 100% rename from src/test/run-make/c-link-to-rust-staticlib/Makefile rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/Makefile diff --git a/src/test/run-make/c-link-to-rust-staticlib/bar.c b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c similarity index 100% rename from src/test/run-make/c-link-to-rust-staticlib/bar.c rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/bar.c diff --git a/src/test/run-make/c-link-to-rust-staticlib/foo.rs b/src/test/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs similarity index 100% rename from src/test/run-make/c-link-to-rust-staticlib/foo.rs rename to src/test/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs diff --git a/src/test/run-make/c-static-dylib/Makefile b/src/test/run-make-fulldeps/c-static-dylib/Makefile similarity index 100% rename from src/test/run-make/c-static-dylib/Makefile rename to src/test/run-make-fulldeps/c-static-dylib/Makefile diff --git a/src/test/run-make/c-static-dylib/bar.rs b/src/test/run-make-fulldeps/c-static-dylib/bar.rs similarity index 100% rename from src/test/run-make/c-static-dylib/bar.rs rename to src/test/run-make-fulldeps/c-static-dylib/bar.rs diff --git a/src/test/run-make/c-static-dylib/cfoo.c b/src/test/run-make-fulldeps/c-static-dylib/cfoo.c similarity index 100% rename from src/test/run-make/c-static-dylib/cfoo.c rename to src/test/run-make-fulldeps/c-static-dylib/cfoo.c diff --git a/src/test/run-make/c-static-dylib/foo.rs b/src/test/run-make-fulldeps/c-static-dylib/foo.rs similarity index 100% rename from src/test/run-make/c-static-dylib/foo.rs rename to src/test/run-make-fulldeps/c-static-dylib/foo.rs diff --git a/src/test/run-make/c-static-rlib/Makefile b/src/test/run-make-fulldeps/c-static-rlib/Makefile similarity index 100% rename from src/test/run-make/c-static-rlib/Makefile rename to src/test/run-make-fulldeps/c-static-rlib/Makefile diff --git a/src/test/run-make/c-static-rlib/bar.rs b/src/test/run-make-fulldeps/c-static-rlib/bar.rs similarity index 100% rename from src/test/run-make/c-static-rlib/bar.rs rename to src/test/run-make-fulldeps/c-static-rlib/bar.rs diff --git a/src/test/run-make/c-static-rlib/cfoo.c b/src/test/run-make-fulldeps/c-static-rlib/cfoo.c similarity index 100% rename from src/test/run-make/c-static-rlib/cfoo.c rename to src/test/run-make-fulldeps/c-static-rlib/cfoo.c diff --git a/src/test/run-make/c-static-rlib/foo.rs b/src/test/run-make-fulldeps/c-static-rlib/foo.rs similarity index 100% rename from src/test/run-make/c-static-rlib/foo.rs rename to src/test/run-make-fulldeps/c-static-rlib/foo.rs diff --git a/src/test/run-make/cat-and-grep-sanity-check/Makefile b/src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile similarity index 100% rename from src/test/run-make/cat-and-grep-sanity-check/Makefile rename to src/test/run-make-fulldeps/cat-and-grep-sanity-check/Makefile diff --git a/src/test/run-make/cdylib-fewer-symbols/Makefile b/src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile similarity index 100% rename from src/test/run-make/cdylib-fewer-symbols/Makefile rename to src/test/run-make-fulldeps/cdylib-fewer-symbols/Makefile diff --git a/src/test/run-make/cdylib-fewer-symbols/foo.rs b/src/test/run-make-fulldeps/cdylib-fewer-symbols/foo.rs similarity index 100% rename from src/test/run-make/cdylib-fewer-symbols/foo.rs rename to src/test/run-make-fulldeps/cdylib-fewer-symbols/foo.rs diff --git a/src/test/run-make/cdylib/Makefile b/src/test/run-make-fulldeps/cdylib/Makefile similarity index 100% rename from src/test/run-make/cdylib/Makefile rename to src/test/run-make-fulldeps/cdylib/Makefile diff --git a/src/test/run-make/cdylib/bar.rs b/src/test/run-make-fulldeps/cdylib/bar.rs similarity index 100% rename from src/test/run-make/cdylib/bar.rs rename to src/test/run-make-fulldeps/cdylib/bar.rs diff --git a/src/test/run-make/cdylib/foo.c b/src/test/run-make-fulldeps/cdylib/foo.c similarity index 100% rename from src/test/run-make/cdylib/foo.c rename to src/test/run-make-fulldeps/cdylib/foo.c diff --git a/src/test/run-make/cdylib/foo.rs b/src/test/run-make-fulldeps/cdylib/foo.rs similarity index 100% rename from src/test/run-make/cdylib/foo.rs rename to src/test/run-make-fulldeps/cdylib/foo.rs diff --git a/src/test/run-make/codegen-options-parsing/Makefile b/src/test/run-make-fulldeps/codegen-options-parsing/Makefile similarity index 100% rename from src/test/run-make/codegen-options-parsing/Makefile rename to src/test/run-make-fulldeps/codegen-options-parsing/Makefile diff --git a/src/test/run-make/codegen-options-parsing/dummy.rs b/src/test/run-make-fulldeps/codegen-options-parsing/dummy.rs similarity index 100% rename from src/test/run-make/codegen-options-parsing/dummy.rs rename to src/test/run-make-fulldeps/codegen-options-parsing/dummy.rs diff --git a/src/test/run-make/compile-stdin/Makefile b/src/test/run-make-fulldeps/compile-stdin/Makefile similarity index 100% rename from src/test/run-make/compile-stdin/Makefile rename to src/test/run-make-fulldeps/compile-stdin/Makefile diff --git a/src/test/run-make/compiler-lookup-paths-2/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/Makefile rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/Makefile diff --git a/src/test/run-make/compiler-lookup-paths-2/a.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/a.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/a.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/a.rs diff --git a/src/test/run-make/compiler-lookup-paths-2/b.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/b.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/b.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/b.rs diff --git a/src/test/run-make/compiler-lookup-paths-2/c.rs b/src/test/run-make-fulldeps/compiler-lookup-paths-2/c.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths-2/c.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths-2/c.rs diff --git a/src/test/run-make/compiler-lookup-paths/Makefile b/src/test/run-make-fulldeps/compiler-lookup-paths/Makefile similarity index 100% rename from src/test/run-make/compiler-lookup-paths/Makefile rename to src/test/run-make-fulldeps/compiler-lookup-paths/Makefile diff --git a/src/test/run-make/compiler-lookup-paths/a.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/a.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/a.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/a.rs diff --git a/src/test/run-make/compiler-lookup-paths/b.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/b.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/b.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/b.rs diff --git a/src/test/run-make/compiler-lookup-paths/c.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/c.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/c.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/c.rs diff --git a/src/test/run-make/compiler-lookup-paths/d.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/d.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/d.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/d.rs diff --git a/src/test/run-make/compiler-lookup-paths/e.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/e.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/e.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/e.rs diff --git a/src/test/run-make/compiler-lookup-paths/e2.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/e2.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/e2.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/e2.rs diff --git a/src/test/run-make/compiler-lookup-paths/f.rs b/src/test/run-make-fulldeps/compiler-lookup-paths/f.rs similarity index 100% rename from src/test/run-make/compiler-lookup-paths/f.rs rename to src/test/run-make-fulldeps/compiler-lookup-paths/f.rs diff --git a/src/test/run-make/compiler-lookup-paths/native.c b/src/test/run-make-fulldeps/compiler-lookup-paths/native.c similarity index 100% rename from src/test/run-make/compiler-lookup-paths/native.c rename to src/test/run-make-fulldeps/compiler-lookup-paths/native.c diff --git a/src/test/run-make/compiler-rt-works-on-mingw/Makefile b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile similarity index 100% rename from src/test/run-make/compiler-rt-works-on-mingw/Makefile rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile diff --git a/src/test/run-make/compiler-rt-works-on-mingw/foo.cpp b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp similarity index 100% rename from src/test/run-make/compiler-rt-works-on-mingw/foo.cpp rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp diff --git a/src/test/run-make/compiler-rt-works-on-mingw/foo.rs b/src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs similarity index 100% rename from src/test/run-make/compiler-rt-works-on-mingw/foo.rs rename to src/test/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs diff --git a/src/test/run-make/crate-data-smoke/Makefile b/src/test/run-make-fulldeps/crate-data-smoke/Makefile similarity index 100% rename from src/test/run-make/crate-data-smoke/Makefile rename to src/test/run-make-fulldeps/crate-data-smoke/Makefile diff --git a/src/test/run-make/crate-data-smoke/crate.rs b/src/test/run-make-fulldeps/crate-data-smoke/crate.rs similarity index 100% rename from src/test/run-make/crate-data-smoke/crate.rs rename to src/test/run-make-fulldeps/crate-data-smoke/crate.rs diff --git a/src/test/run-make/crate-data-smoke/lib.rs b/src/test/run-make-fulldeps/crate-data-smoke/lib.rs similarity index 100% rename from src/test/run-make/crate-data-smoke/lib.rs rename to src/test/run-make-fulldeps/crate-data-smoke/lib.rs diff --git a/src/test/run-make/crate-data-smoke/rlib.rs b/src/test/run-make-fulldeps/crate-data-smoke/rlib.rs similarity index 100% rename from src/test/run-make/crate-data-smoke/rlib.rs rename to src/test/run-make-fulldeps/crate-data-smoke/rlib.rs diff --git a/src/test/run-make/crate-name-priority/Makefile b/src/test/run-make-fulldeps/crate-name-priority/Makefile similarity index 100% rename from src/test/run-make/crate-name-priority/Makefile rename to src/test/run-make-fulldeps/crate-name-priority/Makefile diff --git a/src/test/run-make/crate-name-priority/foo.rs b/src/test/run-make-fulldeps/crate-name-priority/foo.rs similarity index 100% rename from src/test/run-make/crate-name-priority/foo.rs rename to src/test/run-make-fulldeps/crate-name-priority/foo.rs diff --git a/src/test/run-make/crate-name-priority/foo1.rs b/src/test/run-make-fulldeps/crate-name-priority/foo1.rs similarity index 100% rename from src/test/run-make/crate-name-priority/foo1.rs rename to src/test/run-make-fulldeps/crate-name-priority/foo1.rs diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make-fulldeps/debug-assertions/Makefile similarity index 100% rename from src/test/run-make/debug-assertions/Makefile rename to src/test/run-make-fulldeps/debug-assertions/Makefile diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make-fulldeps/debug-assertions/debug.rs similarity index 100% rename from src/test/run-make/debug-assertions/debug.rs rename to src/test/run-make-fulldeps/debug-assertions/debug.rs diff --git a/src/test/run-make/dep-info-doesnt-run-much/Makefile b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile similarity index 100% rename from src/test/run-make/dep-info-doesnt-run-much/Makefile rename to src/test/run-make-fulldeps/dep-info-doesnt-run-much/Makefile diff --git a/src/test/run-make/dep-info-doesnt-run-much/foo.rs b/src/test/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs similarity index 100% rename from src/test/run-make/dep-info-doesnt-run-much/foo.rs rename to src/test/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs diff --git a/src/test/run-make/dep-info-spaces/Makefile b/src/test/run-make-fulldeps/dep-info-spaces/Makefile similarity index 100% rename from src/test/run-make/dep-info-spaces/Makefile rename to src/test/run-make-fulldeps/dep-info-spaces/Makefile diff --git a/src/test/run-make/dep-info-spaces/Makefile.foo b/src/test/run-make-fulldeps/dep-info-spaces/Makefile.foo similarity index 100% rename from src/test/run-make/dep-info-spaces/Makefile.foo rename to src/test/run-make-fulldeps/dep-info-spaces/Makefile.foo diff --git a/src/test/run-make/dep-info-spaces/bar.rs b/src/test/run-make-fulldeps/dep-info-spaces/bar.rs similarity index 100% rename from src/test/run-make/dep-info-spaces/bar.rs rename to src/test/run-make-fulldeps/dep-info-spaces/bar.rs diff --git a/src/test/run-make/dep-info-spaces/foo foo.rs b/src/test/run-make-fulldeps/dep-info-spaces/foo foo.rs similarity index 100% rename from src/test/run-make/dep-info-spaces/foo foo.rs rename to src/test/run-make-fulldeps/dep-info-spaces/foo foo.rs diff --git a/src/test/run-make/dep-info-spaces/lib.rs b/src/test/run-make-fulldeps/dep-info-spaces/lib.rs similarity index 100% rename from src/test/run-make/dep-info-spaces/lib.rs rename to src/test/run-make-fulldeps/dep-info-spaces/lib.rs diff --git a/src/test/run-make/dep-info/Makefile b/src/test/run-make-fulldeps/dep-info/Makefile similarity index 100% rename from src/test/run-make/dep-info/Makefile rename to src/test/run-make-fulldeps/dep-info/Makefile diff --git a/src/test/run-make/dep-info/Makefile.foo b/src/test/run-make-fulldeps/dep-info/Makefile.foo similarity index 100% rename from src/test/run-make/dep-info/Makefile.foo rename to src/test/run-make-fulldeps/dep-info/Makefile.foo diff --git a/src/test/run-make/dep-info/bar.rs b/src/test/run-make-fulldeps/dep-info/bar.rs similarity index 100% rename from src/test/run-make/dep-info/bar.rs rename to src/test/run-make-fulldeps/dep-info/bar.rs diff --git a/src/test/run-make/dep-info/foo.rs b/src/test/run-make-fulldeps/dep-info/foo.rs similarity index 100% rename from src/test/run-make/dep-info/foo.rs rename to src/test/run-make-fulldeps/dep-info/foo.rs diff --git a/src/test/run-make/dep-info/lib.rs b/src/test/run-make-fulldeps/dep-info/lib.rs similarity index 100% rename from src/test/run-make/dep-info/lib.rs rename to src/test/run-make-fulldeps/dep-info/lib.rs diff --git a/src/test/run-make/dep-info/lib2.rs b/src/test/run-make-fulldeps/dep-info/lib2.rs similarity index 100% rename from src/test/run-make/dep-info/lib2.rs rename to src/test/run-make-fulldeps/dep-info/lib2.rs diff --git a/src/test/run-make/duplicate-output-flavors/Makefile b/src/test/run-make-fulldeps/duplicate-output-flavors/Makefile similarity index 100% rename from src/test/run-make/duplicate-output-flavors/Makefile rename to src/test/run-make-fulldeps/duplicate-output-flavors/Makefile diff --git a/src/test/run-make/duplicate-output-flavors/foo.rs b/src/test/run-make-fulldeps/duplicate-output-flavors/foo.rs similarity index 100% rename from src/test/run-make/duplicate-output-flavors/foo.rs rename to src/test/run-make-fulldeps/duplicate-output-flavors/foo.rs diff --git a/src/test/run-make/dylib-chain/Makefile b/src/test/run-make-fulldeps/dylib-chain/Makefile similarity index 100% rename from src/test/run-make/dylib-chain/Makefile rename to src/test/run-make-fulldeps/dylib-chain/Makefile diff --git a/src/test/run-make/dylib-chain/m1.rs b/src/test/run-make-fulldeps/dylib-chain/m1.rs similarity index 100% rename from src/test/run-make/dylib-chain/m1.rs rename to src/test/run-make-fulldeps/dylib-chain/m1.rs diff --git a/src/test/run-make/dylib-chain/m2.rs b/src/test/run-make-fulldeps/dylib-chain/m2.rs similarity index 100% rename from src/test/run-make/dylib-chain/m2.rs rename to src/test/run-make-fulldeps/dylib-chain/m2.rs diff --git a/src/test/run-make/dylib-chain/m3.rs b/src/test/run-make-fulldeps/dylib-chain/m3.rs similarity index 100% rename from src/test/run-make/dylib-chain/m3.rs rename to src/test/run-make-fulldeps/dylib-chain/m3.rs diff --git a/src/test/run-make/dylib-chain/m4.rs b/src/test/run-make-fulldeps/dylib-chain/m4.rs similarity index 100% rename from src/test/run-make/dylib-chain/m4.rs rename to src/test/run-make-fulldeps/dylib-chain/m4.rs diff --git a/src/test/run-make/emit/Makefile b/src/test/run-make-fulldeps/emit/Makefile similarity index 100% rename from src/test/run-make/emit/Makefile rename to src/test/run-make-fulldeps/emit/Makefile diff --git a/src/test/run-make/emit/test-24876.rs b/src/test/run-make-fulldeps/emit/test-24876.rs similarity index 100% rename from src/test/run-make/emit/test-24876.rs rename to src/test/run-make-fulldeps/emit/test-24876.rs diff --git a/src/test/run-make/emit/test-26235.rs b/src/test/run-make-fulldeps/emit/test-26235.rs similarity index 100% rename from src/test/run-make/emit/test-26235.rs rename to src/test/run-make-fulldeps/emit/test-26235.rs diff --git a/src/test/run-make/error-found-staticlib-instead-crate/Makefile b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile similarity index 100% rename from src/test/run-make/error-found-staticlib-instead-crate/Makefile rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile diff --git a/src/test/run-make/error-found-staticlib-instead-crate/bar.rs b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs similarity index 100% rename from src/test/run-make/error-found-staticlib-instead-crate/bar.rs rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs diff --git a/src/test/run-make/error-found-staticlib-instead-crate/foo.rs b/src/test/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs similarity index 100% rename from src/test/run-make/error-found-staticlib-instead-crate/foo.rs rename to src/test/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs diff --git a/src/test/run-make/error-writing-dependencies/Makefile b/src/test/run-make-fulldeps/error-writing-dependencies/Makefile similarity index 100% rename from src/test/run-make/error-writing-dependencies/Makefile rename to src/test/run-make-fulldeps/error-writing-dependencies/Makefile diff --git a/src/test/run-make/error-writing-dependencies/foo.rs b/src/test/run-make-fulldeps/error-writing-dependencies/foo.rs similarity index 100% rename from src/test/run-make/error-writing-dependencies/foo.rs rename to src/test/run-make-fulldeps/error-writing-dependencies/foo.rs diff --git a/src/test/run-make/extern-diff-internal-name/Makefile b/src/test/run-make-fulldeps/extern-diff-internal-name/Makefile similarity index 100% rename from src/test/run-make/extern-diff-internal-name/Makefile rename to src/test/run-make-fulldeps/extern-diff-internal-name/Makefile diff --git a/src/test/run-make/extern-diff-internal-name/lib.rs b/src/test/run-make-fulldeps/extern-diff-internal-name/lib.rs similarity index 100% rename from src/test/run-make/extern-diff-internal-name/lib.rs rename to src/test/run-make-fulldeps/extern-diff-internal-name/lib.rs diff --git a/src/test/run-make/extern-diff-internal-name/test.rs b/src/test/run-make-fulldeps/extern-diff-internal-name/test.rs similarity index 100% rename from src/test/run-make/extern-diff-internal-name/test.rs rename to src/test/run-make-fulldeps/extern-diff-internal-name/test.rs diff --git a/src/test/run-make/extern-flag-disambiguates/Makefile b/src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/Makefile rename to src/test/run-make-fulldeps/extern-flag-disambiguates/Makefile diff --git a/src/test/run-make/extern-flag-disambiguates/a.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/a.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/a.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/a.rs diff --git a/src/test/run-make/extern-flag-disambiguates/b.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/b.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/b.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/b.rs diff --git a/src/test/run-make/extern-flag-disambiguates/c.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/c.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/c.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/c.rs diff --git a/src/test/run-make/extern-flag-disambiguates/d.rs b/src/test/run-make-fulldeps/extern-flag-disambiguates/d.rs similarity index 100% rename from src/test/run-make/extern-flag-disambiguates/d.rs rename to src/test/run-make-fulldeps/extern-flag-disambiguates/d.rs diff --git a/src/test/run-make/extern-flag-fun/Makefile b/src/test/run-make-fulldeps/extern-flag-fun/Makefile similarity index 100% rename from src/test/run-make/extern-flag-fun/Makefile rename to src/test/run-make-fulldeps/extern-flag-fun/Makefile diff --git a/src/test/run-make/extern-flag-fun/bar-alt.rs b/src/test/run-make-fulldeps/extern-flag-fun/bar-alt.rs similarity index 100% rename from src/test/run-make/extern-flag-fun/bar-alt.rs rename to src/test/run-make-fulldeps/extern-flag-fun/bar-alt.rs diff --git a/src/test/run-make/extern-flag-fun/bar.rs b/src/test/run-make-fulldeps/extern-flag-fun/bar.rs similarity index 100% rename from src/test/run-make/extern-flag-fun/bar.rs rename to src/test/run-make-fulldeps/extern-flag-fun/bar.rs diff --git a/src/test/run-make/extern-flag-fun/foo.rs b/src/test/run-make-fulldeps/extern-flag-fun/foo.rs similarity index 100% rename from src/test/run-make/extern-flag-fun/foo.rs rename to src/test/run-make-fulldeps/extern-flag-fun/foo.rs diff --git a/src/test/run-make/extern-fn-generic/Makefile b/src/test/run-make-fulldeps/extern-fn-generic/Makefile similarity index 100% rename from src/test/run-make/extern-fn-generic/Makefile rename to src/test/run-make-fulldeps/extern-fn-generic/Makefile diff --git a/src/test/run-make/extern-fn-generic/test.c b/src/test/run-make-fulldeps/extern-fn-generic/test.c similarity index 100% rename from src/test/run-make/extern-fn-generic/test.c rename to src/test/run-make-fulldeps/extern-fn-generic/test.c diff --git a/src/test/run-make/extern-fn-generic/test.rs b/src/test/run-make-fulldeps/extern-fn-generic/test.rs similarity index 100% rename from src/test/run-make/extern-fn-generic/test.rs rename to src/test/run-make-fulldeps/extern-fn-generic/test.rs diff --git a/src/test/run-make/extern-fn-generic/testcrate.rs b/src/test/run-make-fulldeps/extern-fn-generic/testcrate.rs similarity index 100% rename from src/test/run-make/extern-fn-generic/testcrate.rs rename to src/test/run-make-fulldeps/extern-fn-generic/testcrate.rs diff --git a/src/test/run-make/extern-fn-mangle/Makefile b/src/test/run-make-fulldeps/extern-fn-mangle/Makefile similarity index 100% rename from src/test/run-make/extern-fn-mangle/Makefile rename to src/test/run-make-fulldeps/extern-fn-mangle/Makefile diff --git a/src/test/run-make/extern-fn-mangle/test.c b/src/test/run-make-fulldeps/extern-fn-mangle/test.c similarity index 100% rename from src/test/run-make/extern-fn-mangle/test.c rename to src/test/run-make-fulldeps/extern-fn-mangle/test.c diff --git a/src/test/run-make/extern-fn-mangle/test.rs b/src/test/run-make-fulldeps/extern-fn-mangle/test.rs similarity index 100% rename from src/test/run-make/extern-fn-mangle/test.rs rename to src/test/run-make-fulldeps/extern-fn-mangle/test.rs diff --git a/src/test/run-make/extern-fn-reachable/Makefile b/src/test/run-make-fulldeps/extern-fn-reachable/Makefile similarity index 100% rename from src/test/run-make/extern-fn-reachable/Makefile rename to src/test/run-make-fulldeps/extern-fn-reachable/Makefile diff --git a/src/test/run-make/extern-fn-reachable/dylib.rs b/src/test/run-make-fulldeps/extern-fn-reachable/dylib.rs similarity index 100% rename from src/test/run-make/extern-fn-reachable/dylib.rs rename to src/test/run-make-fulldeps/extern-fn-reachable/dylib.rs diff --git a/src/test/run-make/extern-fn-reachable/main.rs b/src/test/run-make-fulldeps/extern-fn-reachable/main.rs similarity index 100% rename from src/test/run-make/extern-fn-reachable/main.rs rename to src/test/run-make-fulldeps/extern-fn-reachable/main.rs diff --git a/src/test/run-make/extern-fn-struct-passing-abi/Makefile b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile similarity index 100% rename from src/test/run-make/extern-fn-struct-passing-abi/Makefile rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.c b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.c similarity index 100% rename from src/test/run-make/extern-fn-struct-passing-abi/test.c rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.c diff --git a/src/test/run-make/extern-fn-struct-passing-abi/test.rs b/src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs similarity index 100% rename from src/test/run-make/extern-fn-struct-passing-abi/test.rs rename to src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs diff --git a/src/test/run-make/extern-fn-with-extern-types/Makefile b/src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile similarity index 100% rename from src/test/run-make/extern-fn-with-extern-types/Makefile rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/Makefile diff --git a/src/test/run-make/extern-fn-with-extern-types/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c similarity index 100% rename from src/test/run-make/extern-fn-with-extern-types/ctest.c rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/ctest.c diff --git a/src/test/run-make/extern-fn-with-extern-types/test.rs b/src/test/run-make-fulldeps/extern-fn-with-extern-types/test.rs similarity index 100% rename from src/test/run-make/extern-fn-with-extern-types/test.rs rename to src/test/run-make-fulldeps/extern-fn-with-extern-types/test.rs diff --git a/src/test/run-make/extern-fn-with-packed-struct/Makefile b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile similarity index 100% rename from src/test/run-make/extern-fn-with-packed-struct/Makefile rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/Makefile diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.c b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c similarity index 100% rename from src/test/run-make/extern-fn-with-packed-struct/test.c rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.c diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.rs b/src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.rs similarity index 100% rename from src/test/run-make/extern-fn-with-packed-struct/test.rs rename to src/test/run-make-fulldeps/extern-fn-with-packed-struct/test.rs diff --git a/src/test/run-make/extern-fn-with-union/Makefile b/src/test/run-make-fulldeps/extern-fn-with-union/Makefile similarity index 100% rename from src/test/run-make/extern-fn-with-union/Makefile rename to src/test/run-make-fulldeps/extern-fn-with-union/Makefile diff --git a/src/test/run-make/extern-fn-with-union/ctest.c b/src/test/run-make-fulldeps/extern-fn-with-union/ctest.c similarity index 100% rename from src/test/run-make/extern-fn-with-union/ctest.c rename to src/test/run-make-fulldeps/extern-fn-with-union/ctest.c diff --git a/src/test/run-make/extern-fn-with-union/test.rs b/src/test/run-make-fulldeps/extern-fn-with-union/test.rs similarity index 100% rename from src/test/run-make/extern-fn-with-union/test.rs rename to src/test/run-make-fulldeps/extern-fn-with-union/test.rs diff --git a/src/test/run-make/extern-fn-with-union/testcrate.rs b/src/test/run-make-fulldeps/extern-fn-with-union/testcrate.rs similarity index 100% rename from src/test/run-make/extern-fn-with-union/testcrate.rs rename to src/test/run-make-fulldeps/extern-fn-with-union/testcrate.rs diff --git a/src/test/run-make/extern-multiple-copies/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies/Makefile similarity index 100% rename from src/test/run-make/extern-multiple-copies/Makefile rename to src/test/run-make-fulldeps/extern-multiple-copies/Makefile diff --git a/src/test/run-make/extern-multiple-copies/bar.rs b/src/test/run-make-fulldeps/extern-multiple-copies/bar.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies/bar.rs rename to src/test/run-make-fulldeps/extern-multiple-copies/bar.rs diff --git a/src/test/run-make/extern-multiple-copies/foo1.rs b/src/test/run-make-fulldeps/extern-multiple-copies/foo1.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies/foo1.rs rename to src/test/run-make-fulldeps/extern-multiple-copies/foo1.rs diff --git a/src/test/run-make/extern-multiple-copies/foo2.rs b/src/test/run-make-fulldeps/extern-multiple-copies/foo2.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies/foo2.rs rename to src/test/run-make-fulldeps/extern-multiple-copies/foo2.rs diff --git a/src/test/run-make/extern-multiple-copies2/Makefile b/src/test/run-make-fulldeps/extern-multiple-copies2/Makefile similarity index 100% rename from src/test/run-make/extern-multiple-copies2/Makefile rename to src/test/run-make-fulldeps/extern-multiple-copies2/Makefile diff --git a/src/test/run-make/extern-multiple-copies2/bar.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/bar.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies2/bar.rs rename to src/test/run-make-fulldeps/extern-multiple-copies2/bar.rs diff --git a/src/test/run-make/extern-multiple-copies2/foo1.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/foo1.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies2/foo1.rs rename to src/test/run-make-fulldeps/extern-multiple-copies2/foo1.rs diff --git a/src/test/run-make/extern-multiple-copies2/foo2.rs b/src/test/run-make-fulldeps/extern-multiple-copies2/foo2.rs similarity index 100% rename from src/test/run-make/extern-multiple-copies2/foo2.rs rename to src/test/run-make-fulldeps/extern-multiple-copies2/foo2.rs diff --git a/src/test/run-make/extern-overrides-distribution/Makefile b/src/test/run-make-fulldeps/extern-overrides-distribution/Makefile similarity index 100% rename from src/test/run-make/extern-overrides-distribution/Makefile rename to src/test/run-make-fulldeps/extern-overrides-distribution/Makefile diff --git a/src/test/run-make/extern-overrides-distribution/libc.rs b/src/test/run-make-fulldeps/extern-overrides-distribution/libc.rs similarity index 100% rename from src/test/run-make/extern-overrides-distribution/libc.rs rename to src/test/run-make-fulldeps/extern-overrides-distribution/libc.rs diff --git a/src/test/run-make/extern-overrides-distribution/main.rs b/src/test/run-make-fulldeps/extern-overrides-distribution/main.rs similarity index 100% rename from src/test/run-make/extern-overrides-distribution/main.rs rename to src/test/run-make-fulldeps/extern-overrides-distribution/main.rs diff --git a/src/test/run-make/extra-filename-with-temp-outputs/Makefile b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile similarity index 100% rename from src/test/run-make/extra-filename-with-temp-outputs/Makefile rename to src/test/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile diff --git a/src/test/run-make/extra-filename-with-temp-outputs/foo.rs b/src/test/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs similarity index 100% rename from src/test/run-make/extra-filename-with-temp-outputs/foo.rs rename to src/test/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs diff --git a/src/test/run-make/fpic/Makefile b/src/test/run-make-fulldeps/fpic/Makefile similarity index 100% rename from src/test/run-make/fpic/Makefile rename to src/test/run-make-fulldeps/fpic/Makefile diff --git a/src/test/run-make/fpic/hello.rs b/src/test/run-make-fulldeps/fpic/hello.rs similarity index 100% rename from src/test/run-make/fpic/hello.rs rename to src/test/run-make-fulldeps/fpic/hello.rs diff --git a/src/test/run-make/hir-tree/Makefile b/src/test/run-make-fulldeps/hir-tree/Makefile similarity index 100% rename from src/test/run-make/hir-tree/Makefile rename to src/test/run-make-fulldeps/hir-tree/Makefile diff --git a/src/test/run-make/hir-tree/input.rs b/src/test/run-make-fulldeps/hir-tree/input.rs similarity index 100% rename from src/test/run-make/hir-tree/input.rs rename to src/test/run-make-fulldeps/hir-tree/input.rs diff --git a/src/test/run-make/hotplug_codegen_backend/Makefile b/src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile similarity index 100% rename from src/test/run-make/hotplug_codegen_backend/Makefile rename to src/test/run-make-fulldeps/hotplug_codegen_backend/Makefile diff --git a/src/test/run-make/hotplug_codegen_backend/some_crate.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs similarity index 100% rename from src/test/run-make/hotplug_codegen_backend/some_crate.rs rename to src/test/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs diff --git a/src/test/run-make/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs similarity index 100% rename from src/test/run-make/hotplug_codegen_backend/the_backend.rs rename to src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs diff --git a/src/test/run-make/include_bytes_deps/Makefile b/src/test/run-make-fulldeps/include_bytes_deps/Makefile similarity index 100% rename from src/test/run-make/include_bytes_deps/Makefile rename to src/test/run-make-fulldeps/include_bytes_deps/Makefile diff --git a/src/test/run-make/include_bytes_deps/input.bin b/src/test/run-make-fulldeps/include_bytes_deps/input.bin similarity index 100% rename from src/test/run-make/include_bytes_deps/input.bin rename to src/test/run-make-fulldeps/include_bytes_deps/input.bin diff --git a/src/test/run-make/include_bytes_deps/input.md b/src/test/run-make-fulldeps/include_bytes_deps/input.md similarity index 100% rename from src/test/run-make/include_bytes_deps/input.md rename to src/test/run-make-fulldeps/include_bytes_deps/input.md diff --git a/src/test/run-make/include_bytes_deps/input.txt b/src/test/run-make-fulldeps/include_bytes_deps/input.txt similarity index 100% rename from src/test/run-make/include_bytes_deps/input.txt rename to src/test/run-make-fulldeps/include_bytes_deps/input.txt diff --git a/src/test/run-make/include_bytes_deps/main.rs b/src/test/run-make-fulldeps/include_bytes_deps/main.rs similarity index 100% rename from src/test/run-make/include_bytes_deps/main.rs rename to src/test/run-make-fulldeps/include_bytes_deps/main.rs diff --git a/src/test/run-make/inline-always-many-cgu/Makefile b/src/test/run-make-fulldeps/inline-always-many-cgu/Makefile similarity index 100% rename from src/test/run-make/inline-always-many-cgu/Makefile rename to src/test/run-make-fulldeps/inline-always-many-cgu/Makefile diff --git a/src/test/run-make/inline-always-many-cgu/foo.rs b/src/test/run-make-fulldeps/inline-always-many-cgu/foo.rs similarity index 100% rename from src/test/run-make/inline-always-many-cgu/foo.rs rename to src/test/run-make-fulldeps/inline-always-many-cgu/foo.rs diff --git a/src/test/run-make/interdependent-c-libraries/Makefile b/src/test/run-make-fulldeps/interdependent-c-libraries/Makefile similarity index 100% rename from src/test/run-make/interdependent-c-libraries/Makefile rename to src/test/run-make-fulldeps/interdependent-c-libraries/Makefile diff --git a/src/test/run-make/interdependent-c-libraries/bar.c b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.c similarity index 100% rename from src/test/run-make/interdependent-c-libraries/bar.c rename to src/test/run-make-fulldeps/interdependent-c-libraries/bar.c diff --git a/src/test/run-make/interdependent-c-libraries/bar.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/bar.rs similarity index 100% rename from src/test/run-make/interdependent-c-libraries/bar.rs rename to src/test/run-make-fulldeps/interdependent-c-libraries/bar.rs diff --git a/src/test/run-make/interdependent-c-libraries/foo.c b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.c similarity index 100% rename from src/test/run-make/interdependent-c-libraries/foo.c rename to src/test/run-make-fulldeps/interdependent-c-libraries/foo.c diff --git a/src/test/run-make/interdependent-c-libraries/foo.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/foo.rs similarity index 100% rename from src/test/run-make/interdependent-c-libraries/foo.rs rename to src/test/run-make-fulldeps/interdependent-c-libraries/foo.rs diff --git a/src/test/run-make/interdependent-c-libraries/main.rs b/src/test/run-make-fulldeps/interdependent-c-libraries/main.rs similarity index 100% rename from src/test/run-make/interdependent-c-libraries/main.rs rename to src/test/run-make-fulldeps/interdependent-c-libraries/main.rs diff --git a/src/test/run-make/intrinsic-unreachable/Makefile b/src/test/run-make-fulldeps/intrinsic-unreachable/Makefile similarity index 100% rename from src/test/run-make/intrinsic-unreachable/Makefile rename to src/test/run-make-fulldeps/intrinsic-unreachable/Makefile diff --git a/src/test/run-make/intrinsic-unreachable/exit-ret.rs b/src/test/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs similarity index 100% rename from src/test/run-make/intrinsic-unreachable/exit-ret.rs rename to src/test/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs diff --git a/src/test/run-make/intrinsic-unreachable/exit-unreachable.rs b/src/test/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs similarity index 100% rename from src/test/run-make/intrinsic-unreachable/exit-unreachable.rs rename to src/test/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs diff --git a/src/test/run-make/invalid-library/Makefile b/src/test/run-make-fulldeps/invalid-library/Makefile similarity index 100% rename from src/test/run-make/invalid-library/Makefile rename to src/test/run-make-fulldeps/invalid-library/Makefile diff --git a/src/test/run-make/invalid-library/foo.rs b/src/test/run-make-fulldeps/invalid-library/foo.rs similarity index 100% rename from src/test/run-make/invalid-library/foo.rs rename to src/test/run-make-fulldeps/invalid-library/foo.rs diff --git a/src/test/run-make/invalid-staticlib/Makefile b/src/test/run-make-fulldeps/invalid-staticlib/Makefile similarity index 100% rename from src/test/run-make/invalid-staticlib/Makefile rename to src/test/run-make-fulldeps/invalid-staticlib/Makefile diff --git a/src/test/run-make/issue-11908/Makefile b/src/test/run-make-fulldeps/issue-11908/Makefile similarity index 100% rename from src/test/run-make/issue-11908/Makefile rename to src/test/run-make-fulldeps/issue-11908/Makefile diff --git a/src/test/run-make/issue-11908/bar.rs b/src/test/run-make-fulldeps/issue-11908/bar.rs similarity index 100% rename from src/test/run-make/issue-11908/bar.rs rename to src/test/run-make-fulldeps/issue-11908/bar.rs diff --git a/src/test/run-make/issue-11908/foo.rs b/src/test/run-make-fulldeps/issue-11908/foo.rs similarity index 100% rename from src/test/run-make/issue-11908/foo.rs rename to src/test/run-make-fulldeps/issue-11908/foo.rs diff --git a/src/test/run-make/issue-14500/Makefile b/src/test/run-make-fulldeps/issue-14500/Makefile similarity index 100% rename from src/test/run-make/issue-14500/Makefile rename to src/test/run-make-fulldeps/issue-14500/Makefile diff --git a/src/test/run-make/issue-14500/bar.rs b/src/test/run-make-fulldeps/issue-14500/bar.rs similarity index 100% rename from src/test/run-make/issue-14500/bar.rs rename to src/test/run-make-fulldeps/issue-14500/bar.rs diff --git a/src/test/run-make/issue-14500/foo.c b/src/test/run-make-fulldeps/issue-14500/foo.c similarity index 100% rename from src/test/run-make/issue-14500/foo.c rename to src/test/run-make-fulldeps/issue-14500/foo.c diff --git a/src/test/run-make/issue-14500/foo.rs b/src/test/run-make-fulldeps/issue-14500/foo.rs similarity index 100% rename from src/test/run-make/issue-14500/foo.rs rename to src/test/run-make-fulldeps/issue-14500/foo.rs diff --git a/src/test/run-make/issue-14698/Makefile b/src/test/run-make-fulldeps/issue-14698/Makefile similarity index 100% rename from src/test/run-make/issue-14698/Makefile rename to src/test/run-make-fulldeps/issue-14698/Makefile diff --git a/src/test/run-make/issue-14698/foo.rs b/src/test/run-make-fulldeps/issue-14698/foo.rs similarity index 100% rename from src/test/run-make/issue-14698/foo.rs rename to src/test/run-make-fulldeps/issue-14698/foo.rs diff --git a/src/test/run-make/issue-15460/Makefile b/src/test/run-make-fulldeps/issue-15460/Makefile similarity index 100% rename from src/test/run-make/issue-15460/Makefile rename to src/test/run-make-fulldeps/issue-15460/Makefile diff --git a/src/test/run-make/issue-15460/bar.rs b/src/test/run-make-fulldeps/issue-15460/bar.rs similarity index 100% rename from src/test/run-make/issue-15460/bar.rs rename to src/test/run-make-fulldeps/issue-15460/bar.rs diff --git a/src/test/run-make/issue-15460/foo.c b/src/test/run-make-fulldeps/issue-15460/foo.c similarity index 100% rename from src/test/run-make/issue-15460/foo.c rename to src/test/run-make-fulldeps/issue-15460/foo.c diff --git a/src/test/run-make/issue-15460/foo.rs b/src/test/run-make-fulldeps/issue-15460/foo.rs similarity index 100% rename from src/test/run-make/issue-15460/foo.rs rename to src/test/run-make-fulldeps/issue-15460/foo.rs diff --git a/src/test/run-make/issue-18943/Makefile b/src/test/run-make-fulldeps/issue-18943/Makefile similarity index 100% rename from src/test/run-make/issue-18943/Makefile rename to src/test/run-make-fulldeps/issue-18943/Makefile diff --git a/src/test/run-make/issue-18943/foo.rs b/src/test/run-make-fulldeps/issue-18943/foo.rs similarity index 100% rename from src/test/run-make/issue-18943/foo.rs rename to src/test/run-make-fulldeps/issue-18943/foo.rs diff --git a/src/test/run-make/issue-19371/Makefile b/src/test/run-make-fulldeps/issue-19371/Makefile similarity index 100% rename from src/test/run-make/issue-19371/Makefile rename to src/test/run-make-fulldeps/issue-19371/Makefile diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs similarity index 100% rename from src/test/run-make/issue-19371/foo.rs rename to src/test/run-make-fulldeps/issue-19371/foo.rs diff --git a/src/test/run-make/issue-20626/Makefile b/src/test/run-make-fulldeps/issue-20626/Makefile similarity index 100% rename from src/test/run-make/issue-20626/Makefile rename to src/test/run-make-fulldeps/issue-20626/Makefile diff --git a/src/test/run-make/issue-20626/foo.rs b/src/test/run-make-fulldeps/issue-20626/foo.rs similarity index 100% rename from src/test/run-make/issue-20626/foo.rs rename to src/test/run-make-fulldeps/issue-20626/foo.rs diff --git a/src/test/run-make/issue-22131/Makefile b/src/test/run-make-fulldeps/issue-22131/Makefile similarity index 100% rename from src/test/run-make/issue-22131/Makefile rename to src/test/run-make-fulldeps/issue-22131/Makefile diff --git a/src/test/run-make/issue-22131/foo.rs b/src/test/run-make-fulldeps/issue-22131/foo.rs similarity index 100% rename from src/test/run-make/issue-22131/foo.rs rename to src/test/run-make-fulldeps/issue-22131/foo.rs diff --git a/src/test/run-make/issue-24445/Makefile b/src/test/run-make-fulldeps/issue-24445/Makefile similarity index 100% rename from src/test/run-make/issue-24445/Makefile rename to src/test/run-make-fulldeps/issue-24445/Makefile diff --git a/src/test/run-make/issue-24445/foo.c b/src/test/run-make-fulldeps/issue-24445/foo.c similarity index 100% rename from src/test/run-make/issue-24445/foo.c rename to src/test/run-make-fulldeps/issue-24445/foo.c diff --git a/src/test/run-make/issue-24445/foo.rs b/src/test/run-make-fulldeps/issue-24445/foo.rs similarity index 100% rename from src/test/run-make/issue-24445/foo.rs rename to src/test/run-make-fulldeps/issue-24445/foo.rs diff --git a/src/test/run-make/issue-25581/Makefile b/src/test/run-make-fulldeps/issue-25581/Makefile similarity index 100% rename from src/test/run-make/issue-25581/Makefile rename to src/test/run-make-fulldeps/issue-25581/Makefile diff --git a/src/test/run-make/issue-25581/test.c b/src/test/run-make-fulldeps/issue-25581/test.c similarity index 100% rename from src/test/run-make/issue-25581/test.c rename to src/test/run-make-fulldeps/issue-25581/test.c diff --git a/src/test/run-make/issue-25581/test.rs b/src/test/run-make-fulldeps/issue-25581/test.rs similarity index 100% rename from src/test/run-make/issue-25581/test.rs rename to src/test/run-make-fulldeps/issue-25581/test.rs diff --git a/src/test/run-make/issue-26006/Makefile b/src/test/run-make-fulldeps/issue-26006/Makefile similarity index 100% rename from src/test/run-make/issue-26006/Makefile rename to src/test/run-make-fulldeps/issue-26006/Makefile diff --git a/src/test/run-make/issue-26006/in/libc/lib.rs b/src/test/run-make-fulldeps/issue-26006/in/libc/lib.rs similarity index 100% rename from src/test/run-make/issue-26006/in/libc/lib.rs rename to src/test/run-make-fulldeps/issue-26006/in/libc/lib.rs diff --git a/src/test/run-make/issue-26006/in/time/lib.rs b/src/test/run-make-fulldeps/issue-26006/in/time/lib.rs similarity index 100% rename from src/test/run-make/issue-26006/in/time/lib.rs rename to src/test/run-make-fulldeps/issue-26006/in/time/lib.rs diff --git a/src/test/run-make/issue-26092/Makefile b/src/test/run-make-fulldeps/issue-26092/Makefile similarity index 100% rename from src/test/run-make/issue-26092/Makefile rename to src/test/run-make-fulldeps/issue-26092/Makefile diff --git a/src/test/run-make/issue-26092/blank.rs b/src/test/run-make-fulldeps/issue-26092/blank.rs similarity index 100% rename from src/test/run-make/issue-26092/blank.rs rename to src/test/run-make-fulldeps/issue-26092/blank.rs diff --git a/src/test/run-make/issue-28595/Makefile b/src/test/run-make-fulldeps/issue-28595/Makefile similarity index 100% rename from src/test/run-make/issue-28595/Makefile rename to src/test/run-make-fulldeps/issue-28595/Makefile diff --git a/src/test/run-make/issue-28595/a.c b/src/test/run-make-fulldeps/issue-28595/a.c similarity index 100% rename from src/test/run-make/issue-28595/a.c rename to src/test/run-make-fulldeps/issue-28595/a.c diff --git a/src/test/run-make/issue-28595/a.rs b/src/test/run-make-fulldeps/issue-28595/a.rs similarity index 100% rename from src/test/run-make/issue-28595/a.rs rename to src/test/run-make-fulldeps/issue-28595/a.rs diff --git a/src/test/run-make/issue-28595/b.c b/src/test/run-make-fulldeps/issue-28595/b.c similarity index 100% rename from src/test/run-make/issue-28595/b.c rename to src/test/run-make-fulldeps/issue-28595/b.c diff --git a/src/test/run-make/issue-28595/b.rs b/src/test/run-make-fulldeps/issue-28595/b.rs similarity index 100% rename from src/test/run-make/issue-28595/b.rs rename to src/test/run-make-fulldeps/issue-28595/b.rs diff --git a/src/test/run-make/issue-28766/Makefile b/src/test/run-make-fulldeps/issue-28766/Makefile similarity index 100% rename from src/test/run-make/issue-28766/Makefile rename to src/test/run-make-fulldeps/issue-28766/Makefile diff --git a/src/test/run-make/issue-28766/foo.rs b/src/test/run-make-fulldeps/issue-28766/foo.rs similarity index 100% rename from src/test/run-make/issue-28766/foo.rs rename to src/test/run-make-fulldeps/issue-28766/foo.rs diff --git a/src/test/run-make/issue-28766/main.rs b/src/test/run-make-fulldeps/issue-28766/main.rs similarity index 100% rename from src/test/run-make/issue-28766/main.rs rename to src/test/run-make-fulldeps/issue-28766/main.rs diff --git a/src/test/run-make/issue-30063/Makefile b/src/test/run-make-fulldeps/issue-30063/Makefile similarity index 100% rename from src/test/run-make/issue-30063/Makefile rename to src/test/run-make-fulldeps/issue-30063/Makefile diff --git a/src/test/run-make/issue-30063/foo.rs b/src/test/run-make-fulldeps/issue-30063/foo.rs similarity index 100% rename from src/test/run-make/issue-30063/foo.rs rename to src/test/run-make-fulldeps/issue-30063/foo.rs diff --git a/src/test/run-make/issue-33329/Makefile b/src/test/run-make-fulldeps/issue-33329/Makefile similarity index 100% rename from src/test/run-make/issue-33329/Makefile rename to src/test/run-make-fulldeps/issue-33329/Makefile diff --git a/src/test/run-make/issue-33329/main.rs b/src/test/run-make-fulldeps/issue-33329/main.rs similarity index 100% rename from src/test/run-make/issue-33329/main.rs rename to src/test/run-make-fulldeps/issue-33329/main.rs diff --git a/src/test/run-make/issue-35164/Makefile b/src/test/run-make-fulldeps/issue-35164/Makefile similarity index 100% rename from src/test/run-make/issue-35164/Makefile rename to src/test/run-make-fulldeps/issue-35164/Makefile diff --git a/src/test/run-make/issue-35164/main.rs b/src/test/run-make-fulldeps/issue-35164/main.rs similarity index 100% rename from src/test/run-make/issue-35164/main.rs rename to src/test/run-make-fulldeps/issue-35164/main.rs diff --git a/src/test/run-make/issue-35164/submodule/mod.rs b/src/test/run-make-fulldeps/issue-35164/submodule/mod.rs similarity index 100% rename from src/test/run-make/issue-35164/submodule/mod.rs rename to src/test/run-make-fulldeps/issue-35164/submodule/mod.rs diff --git a/src/test/run-make/issue-37839/Makefile b/src/test/run-make-fulldeps/issue-37839/Makefile similarity index 100% rename from src/test/run-make/issue-37839/Makefile rename to src/test/run-make-fulldeps/issue-37839/Makefile diff --git a/src/test/run-make/issue-37839/a.rs b/src/test/run-make-fulldeps/issue-37839/a.rs similarity index 100% rename from src/test/run-make/issue-37839/a.rs rename to src/test/run-make-fulldeps/issue-37839/a.rs diff --git a/src/test/run-make/issue-37839/b.rs b/src/test/run-make-fulldeps/issue-37839/b.rs similarity index 100% rename from src/test/run-make/issue-37839/b.rs rename to src/test/run-make-fulldeps/issue-37839/b.rs diff --git a/src/test/run-make/issue-37839/c.rs b/src/test/run-make-fulldeps/issue-37839/c.rs similarity index 100% rename from src/test/run-make/issue-37839/c.rs rename to src/test/run-make-fulldeps/issue-37839/c.rs diff --git a/src/test/run-make/issue-37893/Makefile b/src/test/run-make-fulldeps/issue-37893/Makefile similarity index 100% rename from src/test/run-make/issue-37893/Makefile rename to src/test/run-make-fulldeps/issue-37893/Makefile diff --git a/src/test/run-make/issue-37893/a.rs b/src/test/run-make-fulldeps/issue-37893/a.rs similarity index 100% rename from src/test/run-make/issue-37893/a.rs rename to src/test/run-make-fulldeps/issue-37893/a.rs diff --git a/src/test/run-make/issue-37893/b.rs b/src/test/run-make-fulldeps/issue-37893/b.rs similarity index 100% rename from src/test/run-make/issue-37893/b.rs rename to src/test/run-make-fulldeps/issue-37893/b.rs diff --git a/src/test/run-make/issue-37893/c.rs b/src/test/run-make-fulldeps/issue-37893/c.rs similarity index 100% rename from src/test/run-make/issue-37893/c.rs rename to src/test/run-make-fulldeps/issue-37893/c.rs diff --git a/src/test/run-make/issue-38237/Makefile b/src/test/run-make-fulldeps/issue-38237/Makefile similarity index 100% rename from src/test/run-make/issue-38237/Makefile rename to src/test/run-make-fulldeps/issue-38237/Makefile diff --git a/src/test/run-make/issue-38237/bar.rs b/src/test/run-make-fulldeps/issue-38237/bar.rs similarity index 100% rename from src/test/run-make/issue-38237/bar.rs rename to src/test/run-make-fulldeps/issue-38237/bar.rs diff --git a/src/test/run-make/issue-38237/baz.rs b/src/test/run-make-fulldeps/issue-38237/baz.rs similarity index 100% rename from src/test/run-make/issue-38237/baz.rs rename to src/test/run-make-fulldeps/issue-38237/baz.rs diff --git a/src/test/run-make/issue-38237/foo.rs b/src/test/run-make-fulldeps/issue-38237/foo.rs similarity index 100% rename from src/test/run-make/issue-38237/foo.rs rename to src/test/run-make-fulldeps/issue-38237/foo.rs diff --git a/src/test/run-make/issue-40535/Makefile b/src/test/run-make-fulldeps/issue-40535/Makefile similarity index 100% rename from src/test/run-make/issue-40535/Makefile rename to src/test/run-make-fulldeps/issue-40535/Makefile diff --git a/src/test/run-make/issue-40535/bar.rs b/src/test/run-make-fulldeps/issue-40535/bar.rs similarity index 100% rename from src/test/run-make/issue-40535/bar.rs rename to src/test/run-make-fulldeps/issue-40535/bar.rs diff --git a/src/test/run-make/issue-40535/baz.rs b/src/test/run-make-fulldeps/issue-40535/baz.rs similarity index 100% rename from src/test/run-make/issue-40535/baz.rs rename to src/test/run-make-fulldeps/issue-40535/baz.rs diff --git a/src/test/run-make/issue-40535/foo.rs b/src/test/run-make-fulldeps/issue-40535/foo.rs similarity index 100% rename from src/test/run-make/issue-40535/foo.rs rename to src/test/run-make-fulldeps/issue-40535/foo.rs diff --git a/src/test/run-make/issue-46239/Makefile b/src/test/run-make-fulldeps/issue-46239/Makefile similarity index 100% rename from src/test/run-make/issue-46239/Makefile rename to src/test/run-make-fulldeps/issue-46239/Makefile diff --git a/src/test/run-make/issue-46239/main.rs b/src/test/run-make-fulldeps/issue-46239/main.rs similarity index 100% rename from src/test/run-make/issue-46239/main.rs rename to src/test/run-make-fulldeps/issue-46239/main.rs diff --git a/src/test/run-make/issue-7349/Makefile b/src/test/run-make-fulldeps/issue-7349/Makefile similarity index 100% rename from src/test/run-make/issue-7349/Makefile rename to src/test/run-make-fulldeps/issue-7349/Makefile diff --git a/src/test/run-make/issue-7349/foo.rs b/src/test/run-make-fulldeps/issue-7349/foo.rs similarity index 100% rename from src/test/run-make/issue-7349/foo.rs rename to src/test/run-make-fulldeps/issue-7349/foo.rs diff --git a/src/test/run-make/issues-41478-43796/Makefile b/src/test/run-make-fulldeps/issues-41478-43796/Makefile similarity index 100% rename from src/test/run-make/issues-41478-43796/Makefile rename to src/test/run-make-fulldeps/issues-41478-43796/Makefile diff --git a/src/test/run-make/issues-41478-43796/a.rs b/src/test/run-make-fulldeps/issues-41478-43796/a.rs similarity index 100% rename from src/test/run-make/issues-41478-43796/a.rs rename to src/test/run-make-fulldeps/issues-41478-43796/a.rs diff --git a/src/test/run-make/libs-and-bins/Makefile b/src/test/run-make-fulldeps/libs-and-bins/Makefile similarity index 100% rename from src/test/run-make/libs-and-bins/Makefile rename to src/test/run-make-fulldeps/libs-and-bins/Makefile diff --git a/src/test/run-make/libs-and-bins/foo.rs b/src/test/run-make-fulldeps/libs-and-bins/foo.rs similarity index 100% rename from src/test/run-make/libs-and-bins/foo.rs rename to src/test/run-make-fulldeps/libs-and-bins/foo.rs diff --git a/src/test/run-make/libs-through-symlinks/Makefile b/src/test/run-make-fulldeps/libs-through-symlinks/Makefile similarity index 100% rename from src/test/run-make/libs-through-symlinks/Makefile rename to src/test/run-make-fulldeps/libs-through-symlinks/Makefile diff --git a/src/test/run-make/libs-through-symlinks/bar.rs b/src/test/run-make-fulldeps/libs-through-symlinks/bar.rs similarity index 100% rename from src/test/run-make/libs-through-symlinks/bar.rs rename to src/test/run-make-fulldeps/libs-through-symlinks/bar.rs diff --git a/src/test/run-make/libs-through-symlinks/foo.rs b/src/test/run-make-fulldeps/libs-through-symlinks/foo.rs similarity index 100% rename from src/test/run-make/libs-through-symlinks/foo.rs rename to src/test/run-make-fulldeps/libs-through-symlinks/foo.rs diff --git a/src/test/run-make/libtest-json/Makefile b/src/test/run-make-fulldeps/libtest-json/Makefile similarity index 100% rename from src/test/run-make/libtest-json/Makefile rename to src/test/run-make-fulldeps/libtest-json/Makefile diff --git a/src/test/run-make/libtest-json/f.rs b/src/test/run-make-fulldeps/libtest-json/f.rs similarity index 100% rename from src/test/run-make/libtest-json/f.rs rename to src/test/run-make-fulldeps/libtest-json/f.rs diff --git a/src/test/run-make/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output.json similarity index 100% rename from src/test/run-make/libtest-json/output.json rename to src/test/run-make-fulldeps/libtest-json/output.json diff --git a/src/test/run-make/libtest-json/validate_json.py b/src/test/run-make-fulldeps/libtest-json/validate_json.py similarity index 100% rename from src/test/run-make/libtest-json/validate_json.py rename to src/test/run-make-fulldeps/libtest-json/validate_json.py diff --git a/src/test/run-make/link-arg/Makefile b/src/test/run-make-fulldeps/link-arg/Makefile similarity index 100% rename from src/test/run-make/link-arg/Makefile rename to src/test/run-make-fulldeps/link-arg/Makefile diff --git a/src/test/run-make/link-arg/empty.rs b/src/test/run-make-fulldeps/link-arg/empty.rs similarity index 100% rename from src/test/run-make/link-arg/empty.rs rename to src/test/run-make-fulldeps/link-arg/empty.rs diff --git a/src/test/run-make/link-cfg/Makefile b/src/test/run-make-fulldeps/link-cfg/Makefile similarity index 100% rename from src/test/run-make/link-cfg/Makefile rename to src/test/run-make-fulldeps/link-cfg/Makefile diff --git a/src/test/run-make/link-cfg/dep-with-staticlib.rs b/src/test/run-make-fulldeps/link-cfg/dep-with-staticlib.rs similarity index 100% rename from src/test/run-make/link-cfg/dep-with-staticlib.rs rename to src/test/run-make-fulldeps/link-cfg/dep-with-staticlib.rs diff --git a/src/test/run-make/link-cfg/dep.rs b/src/test/run-make-fulldeps/link-cfg/dep.rs similarity index 100% rename from src/test/run-make/link-cfg/dep.rs rename to src/test/run-make-fulldeps/link-cfg/dep.rs diff --git a/src/test/run-make/link-cfg/no-deps.rs b/src/test/run-make-fulldeps/link-cfg/no-deps.rs similarity index 100% rename from src/test/run-make/link-cfg/no-deps.rs rename to src/test/run-make-fulldeps/link-cfg/no-deps.rs diff --git a/src/test/run-make/link-cfg/return1.c b/src/test/run-make-fulldeps/link-cfg/return1.c similarity index 100% rename from src/test/run-make/link-cfg/return1.c rename to src/test/run-make-fulldeps/link-cfg/return1.c diff --git a/src/test/run-make/link-cfg/return2.c b/src/test/run-make-fulldeps/link-cfg/return2.c similarity index 100% rename from src/test/run-make/link-cfg/return2.c rename to src/test/run-make-fulldeps/link-cfg/return2.c diff --git a/src/test/run-make/link-cfg/return3.c b/src/test/run-make-fulldeps/link-cfg/return3.c similarity index 100% rename from src/test/run-make/link-cfg/return3.c rename to src/test/run-make-fulldeps/link-cfg/return3.c diff --git a/src/test/run-make/link-cfg/with-deps.rs b/src/test/run-make-fulldeps/link-cfg/with-deps.rs similarity index 100% rename from src/test/run-make/link-cfg/with-deps.rs rename to src/test/run-make-fulldeps/link-cfg/with-deps.rs diff --git a/src/test/run-make/link-cfg/with-staticlib-deps.rs b/src/test/run-make-fulldeps/link-cfg/with-staticlib-deps.rs similarity index 100% rename from src/test/run-make/link-cfg/with-staticlib-deps.rs rename to src/test/run-make-fulldeps/link-cfg/with-staticlib-deps.rs diff --git a/src/test/run-make/link-path-order/Makefile b/src/test/run-make-fulldeps/link-path-order/Makefile similarity index 100% rename from src/test/run-make/link-path-order/Makefile rename to src/test/run-make-fulldeps/link-path-order/Makefile diff --git a/src/test/run-make/link-path-order/correct.c b/src/test/run-make-fulldeps/link-path-order/correct.c similarity index 100% rename from src/test/run-make/link-path-order/correct.c rename to src/test/run-make-fulldeps/link-path-order/correct.c diff --git a/src/test/run-make/link-path-order/main.rs b/src/test/run-make-fulldeps/link-path-order/main.rs similarity index 100% rename from src/test/run-make/link-path-order/main.rs rename to src/test/run-make-fulldeps/link-path-order/main.rs diff --git a/src/test/run-make/link-path-order/wrong.c b/src/test/run-make-fulldeps/link-path-order/wrong.c similarity index 100% rename from src/test/run-make/link-path-order/wrong.c rename to src/test/run-make-fulldeps/link-path-order/wrong.c diff --git a/src/test/run-make/linkage-attr-on-static/Makefile b/src/test/run-make-fulldeps/linkage-attr-on-static/Makefile similarity index 100% rename from src/test/run-make/linkage-attr-on-static/Makefile rename to src/test/run-make-fulldeps/linkage-attr-on-static/Makefile diff --git a/src/test/run-make/linkage-attr-on-static/bar.rs b/src/test/run-make-fulldeps/linkage-attr-on-static/bar.rs similarity index 100% rename from src/test/run-make/linkage-attr-on-static/bar.rs rename to src/test/run-make-fulldeps/linkage-attr-on-static/bar.rs diff --git a/src/test/run-make/linkage-attr-on-static/foo.c b/src/test/run-make-fulldeps/linkage-attr-on-static/foo.c similarity index 100% rename from src/test/run-make/linkage-attr-on-static/foo.c rename to src/test/run-make-fulldeps/linkage-attr-on-static/foo.c diff --git a/src/test/run-make/linker-output-non-utf8/Makefile b/src/test/run-make-fulldeps/linker-output-non-utf8/Makefile similarity index 100% rename from src/test/run-make/linker-output-non-utf8/Makefile rename to src/test/run-make-fulldeps/linker-output-non-utf8/Makefile diff --git a/src/test/run-make/linker-output-non-utf8/exec.rs b/src/test/run-make-fulldeps/linker-output-non-utf8/exec.rs similarity index 100% rename from src/test/run-make/linker-output-non-utf8/exec.rs rename to src/test/run-make-fulldeps/linker-output-non-utf8/exec.rs diff --git a/src/test/run-make/linker-output-non-utf8/library.rs b/src/test/run-make-fulldeps/linker-output-non-utf8/library.rs similarity index 100% rename from src/test/run-make/linker-output-non-utf8/library.rs rename to src/test/run-make-fulldeps/linker-output-non-utf8/library.rs diff --git a/src/test/run-make/llvm-pass/Makefile b/src/test/run-make-fulldeps/llvm-pass/Makefile similarity index 100% rename from src/test/run-make/llvm-pass/Makefile rename to src/test/run-make-fulldeps/llvm-pass/Makefile diff --git a/src/test/run-make/llvm-pass/llvm-function-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc similarity index 100% rename from src/test/run-make/llvm-pass/llvm-function-pass.so.cc rename to src/test/run-make-fulldeps/llvm-pass/llvm-function-pass.so.cc diff --git a/src/test/run-make/llvm-pass/llvm-module-pass.so.cc b/src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc similarity index 100% rename from src/test/run-make/llvm-pass/llvm-module-pass.so.cc rename to src/test/run-make-fulldeps/llvm-pass/llvm-module-pass.so.cc diff --git a/src/test/run-make/llvm-pass/main.rs b/src/test/run-make-fulldeps/llvm-pass/main.rs similarity index 100% rename from src/test/run-make/llvm-pass/main.rs rename to src/test/run-make-fulldeps/llvm-pass/main.rs diff --git a/src/test/run-make/llvm-pass/plugin.rs b/src/test/run-make-fulldeps/llvm-pass/plugin.rs similarity index 100% rename from src/test/run-make/llvm-pass/plugin.rs rename to src/test/run-make-fulldeps/llvm-pass/plugin.rs diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile similarity index 100% rename from src/test/run-make/long-linker-command-lines-cmd-exe/Makefile rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat similarity index 100% rename from src/test/run-make/long-linker-command-lines-cmd-exe/foo.bat rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs similarity index 100% rename from src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs rename to src/test/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs diff --git a/src/test/run-make/long-linker-command-lines/Makefile b/src/test/run-make-fulldeps/long-linker-command-lines/Makefile similarity index 100% rename from src/test/run-make/long-linker-command-lines/Makefile rename to src/test/run-make-fulldeps/long-linker-command-lines/Makefile diff --git a/src/test/run-make/long-linker-command-lines/foo.rs b/src/test/run-make-fulldeps/long-linker-command-lines/foo.rs similarity index 100% rename from src/test/run-make/long-linker-command-lines/foo.rs rename to src/test/run-make-fulldeps/long-linker-command-lines/foo.rs diff --git a/src/test/run-make/longjmp-across-rust/Makefile b/src/test/run-make-fulldeps/longjmp-across-rust/Makefile similarity index 100% rename from src/test/run-make/longjmp-across-rust/Makefile rename to src/test/run-make-fulldeps/longjmp-across-rust/Makefile diff --git a/src/test/run-make/longjmp-across-rust/foo.c b/src/test/run-make-fulldeps/longjmp-across-rust/foo.c similarity index 100% rename from src/test/run-make/longjmp-across-rust/foo.c rename to src/test/run-make-fulldeps/longjmp-across-rust/foo.c diff --git a/src/test/run-make/longjmp-across-rust/main.rs b/src/test/run-make-fulldeps/longjmp-across-rust/main.rs similarity index 100% rename from src/test/run-make/longjmp-across-rust/main.rs rename to src/test/run-make-fulldeps/longjmp-across-rust/main.rs diff --git a/src/test/run-make/ls-metadata/Makefile b/src/test/run-make-fulldeps/ls-metadata/Makefile similarity index 100% rename from src/test/run-make/ls-metadata/Makefile rename to src/test/run-make-fulldeps/ls-metadata/Makefile diff --git a/src/test/run-make/ls-metadata/foo.rs b/src/test/run-make-fulldeps/ls-metadata/foo.rs similarity index 100% rename from src/test/run-make/ls-metadata/foo.rs rename to src/test/run-make-fulldeps/ls-metadata/foo.rs diff --git a/src/test/run-make/lto-no-link-whole-rlib/Makefile b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/Makefile rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/Makefile diff --git a/src/test/run-make/lto-no-link-whole-rlib/bar.c b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/bar.c similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/bar.c rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/bar.c diff --git a/src/test/run-make/lto-no-link-whole-rlib/foo.c b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/foo.c similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/foo.c rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/foo.c diff --git a/src/test/run-make/lto-no-link-whole-rlib/lib1.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/lib1.rs rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs diff --git a/src/test/run-make/lto-no-link-whole-rlib/lib2.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/lib2.rs rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs diff --git a/src/test/run-make/lto-no-link-whole-rlib/main.rs b/src/test/run-make-fulldeps/lto-no-link-whole-rlib/main.rs similarity index 100% rename from src/test/run-make/lto-no-link-whole-rlib/main.rs rename to src/test/run-make-fulldeps/lto-no-link-whole-rlib/main.rs diff --git a/src/test/run-make/lto-readonly-lib/Makefile b/src/test/run-make-fulldeps/lto-readonly-lib/Makefile similarity index 100% rename from src/test/run-make/lto-readonly-lib/Makefile rename to src/test/run-make-fulldeps/lto-readonly-lib/Makefile diff --git a/src/test/run-make/lto-readonly-lib/lib.rs b/src/test/run-make-fulldeps/lto-readonly-lib/lib.rs similarity index 100% rename from src/test/run-make/lto-readonly-lib/lib.rs rename to src/test/run-make-fulldeps/lto-readonly-lib/lib.rs diff --git a/src/test/run-make/lto-readonly-lib/main.rs b/src/test/run-make-fulldeps/lto-readonly-lib/main.rs similarity index 100% rename from src/test/run-make/lto-readonly-lib/main.rs rename to src/test/run-make-fulldeps/lto-readonly-lib/main.rs diff --git a/src/test/run-make/lto-smoke-c/Makefile b/src/test/run-make-fulldeps/lto-smoke-c/Makefile similarity index 100% rename from src/test/run-make/lto-smoke-c/Makefile rename to src/test/run-make-fulldeps/lto-smoke-c/Makefile diff --git a/src/test/run-make/lto-smoke-c/bar.c b/src/test/run-make-fulldeps/lto-smoke-c/bar.c similarity index 100% rename from src/test/run-make/lto-smoke-c/bar.c rename to src/test/run-make-fulldeps/lto-smoke-c/bar.c diff --git a/src/test/run-make/lto-smoke-c/foo.rs b/src/test/run-make-fulldeps/lto-smoke-c/foo.rs similarity index 100% rename from src/test/run-make/lto-smoke-c/foo.rs rename to src/test/run-make-fulldeps/lto-smoke-c/foo.rs diff --git a/src/test/run-make/lto-smoke/Makefile b/src/test/run-make-fulldeps/lto-smoke/Makefile similarity index 100% rename from src/test/run-make/lto-smoke/Makefile rename to src/test/run-make-fulldeps/lto-smoke/Makefile diff --git a/src/test/run-make/lto-smoke/lib.rs b/src/test/run-make-fulldeps/lto-smoke/lib.rs similarity index 100% rename from src/test/run-make/lto-smoke/lib.rs rename to src/test/run-make-fulldeps/lto-smoke/lib.rs diff --git a/src/test/run-make/lto-smoke/main.rs b/src/test/run-make-fulldeps/lto-smoke/main.rs similarity index 100% rename from src/test/run-make/lto-smoke/main.rs rename to src/test/run-make-fulldeps/lto-smoke/main.rs diff --git a/src/test/run-make/manual-crate-name/Makefile b/src/test/run-make-fulldeps/manual-crate-name/Makefile similarity index 100% rename from src/test/run-make/manual-crate-name/Makefile rename to src/test/run-make-fulldeps/manual-crate-name/Makefile diff --git a/src/test/run-make/manual-crate-name/bar.rs b/src/test/run-make-fulldeps/manual-crate-name/bar.rs similarity index 100% rename from src/test/run-make/manual-crate-name/bar.rs rename to src/test/run-make-fulldeps/manual-crate-name/bar.rs diff --git a/src/test/run-make/manual-link/Makefile b/src/test/run-make-fulldeps/manual-link/Makefile similarity index 100% rename from src/test/run-make/manual-link/Makefile rename to src/test/run-make-fulldeps/manual-link/Makefile diff --git a/src/test/run-make/manual-link/bar.c b/src/test/run-make-fulldeps/manual-link/bar.c similarity index 100% rename from src/test/run-make/manual-link/bar.c rename to src/test/run-make-fulldeps/manual-link/bar.c diff --git a/src/test/run-make/manual-link/foo.c b/src/test/run-make-fulldeps/manual-link/foo.c similarity index 100% rename from src/test/run-make/manual-link/foo.c rename to src/test/run-make-fulldeps/manual-link/foo.c diff --git a/src/test/run-make/manual-link/foo.rs b/src/test/run-make-fulldeps/manual-link/foo.rs similarity index 100% rename from src/test/run-make/manual-link/foo.rs rename to src/test/run-make-fulldeps/manual-link/foo.rs diff --git a/src/test/run-make/manual-link/main.rs b/src/test/run-make-fulldeps/manual-link/main.rs similarity index 100% rename from src/test/run-make/manual-link/main.rs rename to src/test/run-make-fulldeps/manual-link/main.rs diff --git a/src/test/run-make/many-crates-but-no-match/Makefile b/src/test/run-make-fulldeps/many-crates-but-no-match/Makefile similarity index 100% rename from src/test/run-make/many-crates-but-no-match/Makefile rename to src/test/run-make-fulldeps/many-crates-but-no-match/Makefile diff --git a/src/test/run-make/many-crates-but-no-match/crateA1.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA1.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateA1.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA1.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateA2.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA2.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateA2.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA2.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateA3.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateA3.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateA3.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateA3.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateB.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateB.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateB.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateB.rs diff --git a/src/test/run-make/many-crates-but-no-match/crateC.rs b/src/test/run-make-fulldeps/many-crates-but-no-match/crateC.rs similarity index 100% rename from src/test/run-make/many-crates-but-no-match/crateC.rs rename to src/test/run-make-fulldeps/many-crates-but-no-match/crateC.rs diff --git a/src/test/run-make/metadata-flag-frobs-symbols/Makefile b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile similarity index 100% rename from src/test/run-make/metadata-flag-frobs-symbols/Makefile rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile diff --git a/src/test/run-make/metadata-flag-frobs-symbols/bar.rs b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs similarity index 100% rename from src/test/run-make/metadata-flag-frobs-symbols/bar.rs rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs diff --git a/src/test/run-make/metadata-flag-frobs-symbols/foo.rs b/src/test/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs similarity index 100% rename from src/test/run-make/metadata-flag-frobs-symbols/foo.rs rename to src/test/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs diff --git a/src/test/run-make/min-global-align/Makefile b/src/test/run-make-fulldeps/min-global-align/Makefile similarity index 100% rename from src/test/run-make/min-global-align/Makefile rename to src/test/run-make-fulldeps/min-global-align/Makefile diff --git a/src/test/run-make/min-global-align/min_global_align.rs b/src/test/run-make-fulldeps/min-global-align/min_global_align.rs similarity index 100% rename from src/test/run-make/min-global-align/min_global_align.rs rename to src/test/run-make-fulldeps/min-global-align/min_global_align.rs diff --git a/src/test/run-make/mismatching-target-triples/Makefile b/src/test/run-make-fulldeps/mismatching-target-triples/Makefile similarity index 100% rename from src/test/run-make/mismatching-target-triples/Makefile rename to src/test/run-make-fulldeps/mismatching-target-triples/Makefile diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make-fulldeps/mismatching-target-triples/bar.rs similarity index 100% rename from src/test/run-make/mismatching-target-triples/bar.rs rename to src/test/run-make-fulldeps/mismatching-target-triples/bar.rs diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make-fulldeps/mismatching-target-triples/foo.rs similarity index 100% rename from src/test/run-make/mismatching-target-triples/foo.rs rename to src/test/run-make-fulldeps/mismatching-target-triples/foo.rs diff --git a/src/test/run-make/missing-crate-dependency/Makefile b/src/test/run-make-fulldeps/missing-crate-dependency/Makefile similarity index 100% rename from src/test/run-make/missing-crate-dependency/Makefile rename to src/test/run-make-fulldeps/missing-crate-dependency/Makefile diff --git a/src/test/run-make/missing-crate-dependency/crateA.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateA.rs similarity index 100% rename from src/test/run-make/missing-crate-dependency/crateA.rs rename to src/test/run-make-fulldeps/missing-crate-dependency/crateA.rs diff --git a/src/test/run-make/missing-crate-dependency/crateB.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateB.rs similarity index 100% rename from src/test/run-make/missing-crate-dependency/crateB.rs rename to src/test/run-make-fulldeps/missing-crate-dependency/crateB.rs diff --git a/src/test/run-make/missing-crate-dependency/crateC.rs b/src/test/run-make-fulldeps/missing-crate-dependency/crateC.rs similarity index 100% rename from src/test/run-make/missing-crate-dependency/crateC.rs rename to src/test/run-make-fulldeps/missing-crate-dependency/crateC.rs diff --git a/src/test/run-make/mixing-deps/Makefile b/src/test/run-make-fulldeps/mixing-deps/Makefile similarity index 100% rename from src/test/run-make/mixing-deps/Makefile rename to src/test/run-make-fulldeps/mixing-deps/Makefile diff --git a/src/test/run-make/mixing-deps/both.rs b/src/test/run-make-fulldeps/mixing-deps/both.rs similarity index 100% rename from src/test/run-make/mixing-deps/both.rs rename to src/test/run-make-fulldeps/mixing-deps/both.rs diff --git a/src/test/run-make/mixing-deps/dylib.rs b/src/test/run-make-fulldeps/mixing-deps/dylib.rs similarity index 100% rename from src/test/run-make/mixing-deps/dylib.rs rename to src/test/run-make-fulldeps/mixing-deps/dylib.rs diff --git a/src/test/run-make/mixing-deps/prog.rs b/src/test/run-make-fulldeps/mixing-deps/prog.rs similarity index 100% rename from src/test/run-make/mixing-deps/prog.rs rename to src/test/run-make-fulldeps/mixing-deps/prog.rs diff --git a/src/test/run-make/mixing-formats/Makefile b/src/test/run-make-fulldeps/mixing-formats/Makefile similarity index 100% rename from src/test/run-make/mixing-formats/Makefile rename to src/test/run-make-fulldeps/mixing-formats/Makefile diff --git a/src/test/run-make/mixing-formats/bar1.rs b/src/test/run-make-fulldeps/mixing-formats/bar1.rs similarity index 100% rename from src/test/run-make/mixing-formats/bar1.rs rename to src/test/run-make-fulldeps/mixing-formats/bar1.rs diff --git a/src/test/run-make/mixing-formats/bar2.rs b/src/test/run-make-fulldeps/mixing-formats/bar2.rs similarity index 100% rename from src/test/run-make/mixing-formats/bar2.rs rename to src/test/run-make-fulldeps/mixing-formats/bar2.rs diff --git a/src/test/run-make/mixing-formats/baz.rs b/src/test/run-make-fulldeps/mixing-formats/baz.rs similarity index 100% rename from src/test/run-make/mixing-formats/baz.rs rename to src/test/run-make-fulldeps/mixing-formats/baz.rs diff --git a/src/test/run-make/mixing-formats/baz2.rs b/src/test/run-make-fulldeps/mixing-formats/baz2.rs similarity index 100% rename from src/test/run-make/mixing-formats/baz2.rs rename to src/test/run-make-fulldeps/mixing-formats/baz2.rs diff --git a/src/test/run-make/mixing-formats/foo.rs b/src/test/run-make-fulldeps/mixing-formats/foo.rs similarity index 100% rename from src/test/run-make/mixing-formats/foo.rs rename to src/test/run-make-fulldeps/mixing-formats/foo.rs diff --git a/src/test/run-make/mixing-libs/Makefile b/src/test/run-make-fulldeps/mixing-libs/Makefile similarity index 100% rename from src/test/run-make/mixing-libs/Makefile rename to src/test/run-make-fulldeps/mixing-libs/Makefile diff --git a/src/test/run-make/mixing-libs/dylib.rs b/src/test/run-make-fulldeps/mixing-libs/dylib.rs similarity index 100% rename from src/test/run-make/mixing-libs/dylib.rs rename to src/test/run-make-fulldeps/mixing-libs/dylib.rs diff --git a/src/test/run-make/mixing-libs/prog.rs b/src/test/run-make-fulldeps/mixing-libs/prog.rs similarity index 100% rename from src/test/run-make/mixing-libs/prog.rs rename to src/test/run-make-fulldeps/mixing-libs/prog.rs diff --git a/src/test/run-make/mixing-libs/rlib.rs b/src/test/run-make-fulldeps/mixing-libs/rlib.rs similarity index 100% rename from src/test/run-make/mixing-libs/rlib.rs rename to src/test/run-make-fulldeps/mixing-libs/rlib.rs diff --git a/src/test/run-make/msvc-opt-minsize/Makefile b/src/test/run-make-fulldeps/msvc-opt-minsize/Makefile similarity index 100% rename from src/test/run-make/msvc-opt-minsize/Makefile rename to src/test/run-make-fulldeps/msvc-opt-minsize/Makefile diff --git a/src/test/run-make/msvc-opt-minsize/foo.rs b/src/test/run-make-fulldeps/msvc-opt-minsize/foo.rs similarity index 100% rename from src/test/run-make/msvc-opt-minsize/foo.rs rename to src/test/run-make-fulldeps/msvc-opt-minsize/foo.rs diff --git a/src/test/run-make/multiple-emits/Makefile b/src/test/run-make-fulldeps/multiple-emits/Makefile similarity index 100% rename from src/test/run-make/multiple-emits/Makefile rename to src/test/run-make-fulldeps/multiple-emits/Makefile diff --git a/src/test/run-make/multiple-emits/foo.rs b/src/test/run-make-fulldeps/multiple-emits/foo.rs similarity index 100% rename from src/test/run-make/multiple-emits/foo.rs rename to src/test/run-make-fulldeps/multiple-emits/foo.rs diff --git a/src/test/run-make/no-builtins-lto/Makefile b/src/test/run-make-fulldeps/no-builtins-lto/Makefile similarity index 100% rename from src/test/run-make/no-builtins-lto/Makefile rename to src/test/run-make-fulldeps/no-builtins-lto/Makefile diff --git a/src/test/run-make/no-builtins-lto/main.rs b/src/test/run-make-fulldeps/no-builtins-lto/main.rs similarity index 100% rename from src/test/run-make/no-builtins-lto/main.rs rename to src/test/run-make-fulldeps/no-builtins-lto/main.rs diff --git a/src/test/run-make/no-builtins-lto/no_builtins.rs b/src/test/run-make-fulldeps/no-builtins-lto/no_builtins.rs similarity index 100% rename from src/test/run-make/no-builtins-lto/no_builtins.rs rename to src/test/run-make-fulldeps/no-builtins-lto/no_builtins.rs diff --git a/src/test/run-make/no-duplicate-libs/Makefile b/src/test/run-make-fulldeps/no-duplicate-libs/Makefile similarity index 100% rename from src/test/run-make/no-duplicate-libs/Makefile rename to src/test/run-make-fulldeps/no-duplicate-libs/Makefile diff --git a/src/test/run-make/no-duplicate-libs/bar.c b/src/test/run-make-fulldeps/no-duplicate-libs/bar.c similarity index 100% rename from src/test/run-make/no-duplicate-libs/bar.c rename to src/test/run-make-fulldeps/no-duplicate-libs/bar.c diff --git a/src/test/run-make/no-duplicate-libs/foo.c b/src/test/run-make-fulldeps/no-duplicate-libs/foo.c similarity index 100% rename from src/test/run-make/no-duplicate-libs/foo.c rename to src/test/run-make-fulldeps/no-duplicate-libs/foo.c diff --git a/src/test/run-make/no-duplicate-libs/main.rs b/src/test/run-make-fulldeps/no-duplicate-libs/main.rs similarity index 100% rename from src/test/run-make/no-duplicate-libs/main.rs rename to src/test/run-make-fulldeps/no-duplicate-libs/main.rs diff --git a/src/test/run-make/no-integrated-as/Makefile b/src/test/run-make-fulldeps/no-integrated-as/Makefile similarity index 100% rename from src/test/run-make/no-integrated-as/Makefile rename to src/test/run-make-fulldeps/no-integrated-as/Makefile diff --git a/src/test/run-make/no-integrated-as/hello.rs b/src/test/run-make-fulldeps/no-integrated-as/hello.rs similarity index 100% rename from src/test/run-make/no-integrated-as/hello.rs rename to src/test/run-make-fulldeps/no-integrated-as/hello.rs diff --git a/src/test/run-make/no-intermediate-extras/Makefile b/src/test/run-make-fulldeps/no-intermediate-extras/Makefile similarity index 100% rename from src/test/run-make/no-intermediate-extras/Makefile rename to src/test/run-make-fulldeps/no-intermediate-extras/Makefile diff --git a/src/test/run-make/no-intermediate-extras/foo.rs b/src/test/run-make-fulldeps/no-intermediate-extras/foo.rs similarity index 100% rename from src/test/run-make/no-intermediate-extras/foo.rs rename to src/test/run-make-fulldeps/no-intermediate-extras/foo.rs diff --git a/src/test/run-make/obey-crate-type-flag/Makefile b/src/test/run-make-fulldeps/obey-crate-type-flag/Makefile similarity index 100% rename from src/test/run-make/obey-crate-type-flag/Makefile rename to src/test/run-make-fulldeps/obey-crate-type-flag/Makefile diff --git a/src/test/run-make/obey-crate-type-flag/test.rs b/src/test/run-make-fulldeps/obey-crate-type-flag/test.rs similarity index 100% rename from src/test/run-make/obey-crate-type-flag/test.rs rename to src/test/run-make-fulldeps/obey-crate-type-flag/test.rs diff --git a/src/test/run-make/output-filename-conflicts-with-directory/Makefile b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile similarity index 100% rename from src/test/run-make/output-filename-conflicts-with-directory/Makefile rename to src/test/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile diff --git a/src/test/run-make/output-filename-conflicts-with-directory/foo.rs b/src/test/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs similarity index 100% rename from src/test/run-make/output-filename-conflicts-with-directory/foo.rs rename to src/test/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs diff --git a/src/test/run-make/output-filename-overwrites-input/Makefile b/src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile similarity index 100% rename from src/test/run-make/output-filename-overwrites-input/Makefile rename to src/test/run-make-fulldeps/output-filename-overwrites-input/Makefile diff --git a/src/test/run-make/output-filename-overwrites-input/bar.rs b/src/test/run-make-fulldeps/output-filename-overwrites-input/bar.rs similarity index 100% rename from src/test/run-make/output-filename-overwrites-input/bar.rs rename to src/test/run-make-fulldeps/output-filename-overwrites-input/bar.rs diff --git a/src/test/run-make/output-filename-overwrites-input/foo.rs b/src/test/run-make-fulldeps/output-filename-overwrites-input/foo.rs similarity index 100% rename from src/test/run-make/output-filename-overwrites-input/foo.rs rename to src/test/run-make-fulldeps/output-filename-overwrites-input/foo.rs diff --git a/src/test/run-make/output-type-permutations/Makefile b/src/test/run-make-fulldeps/output-type-permutations/Makefile similarity index 100% rename from src/test/run-make/output-type-permutations/Makefile rename to src/test/run-make-fulldeps/output-type-permutations/Makefile diff --git a/src/test/run-make/output-type-permutations/foo.rs b/src/test/run-make-fulldeps/output-type-permutations/foo.rs similarity index 100% rename from src/test/run-make/output-type-permutations/foo.rs rename to src/test/run-make-fulldeps/output-type-permutations/foo.rs diff --git a/src/test/run-make/output-with-hyphens/Makefile b/src/test/run-make-fulldeps/output-with-hyphens/Makefile similarity index 100% rename from src/test/run-make/output-with-hyphens/Makefile rename to src/test/run-make-fulldeps/output-with-hyphens/Makefile diff --git a/src/test/run-make/output-with-hyphens/foo-bar.rs b/src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs similarity index 100% rename from src/test/run-make/output-with-hyphens/foo-bar.rs rename to src/test/run-make-fulldeps/output-with-hyphens/foo-bar.rs diff --git a/src/test/run-make/prefer-dylib/Makefile b/src/test/run-make-fulldeps/prefer-dylib/Makefile similarity index 100% rename from src/test/run-make/prefer-dylib/Makefile rename to src/test/run-make-fulldeps/prefer-dylib/Makefile diff --git a/src/test/run-make/prefer-dylib/bar.rs b/src/test/run-make-fulldeps/prefer-dylib/bar.rs similarity index 100% rename from src/test/run-make/prefer-dylib/bar.rs rename to src/test/run-make-fulldeps/prefer-dylib/bar.rs diff --git a/src/test/run-make/prefer-dylib/foo.rs b/src/test/run-make-fulldeps/prefer-dylib/foo.rs similarity index 100% rename from src/test/run-make/prefer-dylib/foo.rs rename to src/test/run-make-fulldeps/prefer-dylib/foo.rs diff --git a/src/test/run-make/prefer-rlib/Makefile b/src/test/run-make-fulldeps/prefer-rlib/Makefile similarity index 100% rename from src/test/run-make/prefer-rlib/Makefile rename to src/test/run-make-fulldeps/prefer-rlib/Makefile diff --git a/src/test/run-make/prefer-rlib/bar.rs b/src/test/run-make-fulldeps/prefer-rlib/bar.rs similarity index 100% rename from src/test/run-make/prefer-rlib/bar.rs rename to src/test/run-make-fulldeps/prefer-rlib/bar.rs diff --git a/src/test/run-make/prefer-rlib/foo.rs b/src/test/run-make-fulldeps/prefer-rlib/foo.rs similarity index 100% rename from src/test/run-make/prefer-rlib/foo.rs rename to src/test/run-make-fulldeps/prefer-rlib/foo.rs diff --git a/src/test/run-make/pretty-expanded-hygiene/Makefile b/src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile similarity index 100% rename from src/test/run-make/pretty-expanded-hygiene/Makefile rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs similarity index 100% rename from src/test/run-make/pretty-expanded-hygiene/input.pp.rs rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs similarity index 100% rename from src/test/run-make/pretty-expanded-hygiene/input.rs rename to src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs diff --git a/src/test/run-make/pretty-expanded/Makefile b/src/test/run-make-fulldeps/pretty-expanded/Makefile similarity index 100% rename from src/test/run-make/pretty-expanded/Makefile rename to src/test/run-make-fulldeps/pretty-expanded/Makefile diff --git a/src/test/run-make/pretty-expanded/input.rs b/src/test/run-make-fulldeps/pretty-expanded/input.rs similarity index 100% rename from src/test/run-make/pretty-expanded/input.rs rename to src/test/run-make-fulldeps/pretty-expanded/input.rs diff --git a/src/test/run-make/pretty-print-path-suffix/Makefile b/src/test/run-make-fulldeps/pretty-print-path-suffix/Makefile similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/Makefile rename to src/test/run-make-fulldeps/pretty-print-path-suffix/Makefile diff --git a/src/test/run-make/pretty-print-path-suffix/foo.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/foo.pp similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/foo.pp rename to src/test/run-make-fulldeps/pretty-print-path-suffix/foo.pp diff --git a/src/test/run-make/pretty-print-path-suffix/foo_method.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/foo_method.pp similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/foo_method.pp rename to src/test/run-make-fulldeps/pretty-print-path-suffix/foo_method.pp diff --git a/src/test/run-make/pretty-print-path-suffix/input.rs b/src/test/run-make-fulldeps/pretty-print-path-suffix/input.rs similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/input.rs rename to src/test/run-make-fulldeps/pretty-print-path-suffix/input.rs diff --git a/src/test/run-make/pretty-print-path-suffix/nest_foo.pp b/src/test/run-make-fulldeps/pretty-print-path-suffix/nest_foo.pp similarity index 100% rename from src/test/run-make/pretty-print-path-suffix/nest_foo.pp rename to src/test/run-make-fulldeps/pretty-print-path-suffix/nest_foo.pp diff --git a/src/test/run-make/pretty-print-to-file/Makefile b/src/test/run-make-fulldeps/pretty-print-to-file/Makefile similarity index 100% rename from src/test/run-make/pretty-print-to-file/Makefile rename to src/test/run-make-fulldeps/pretty-print-to-file/Makefile diff --git a/src/test/run-make/pretty-print-to-file/input.pp b/src/test/run-make-fulldeps/pretty-print-to-file/input.pp similarity index 100% rename from src/test/run-make/pretty-print-to-file/input.pp rename to src/test/run-make-fulldeps/pretty-print-to-file/input.pp diff --git a/src/test/run-make/pretty-print-to-file/input.rs b/src/test/run-make-fulldeps/pretty-print-to-file/input.rs similarity index 100% rename from src/test/run-make/pretty-print-to-file/input.rs rename to src/test/run-make-fulldeps/pretty-print-to-file/input.rs diff --git a/src/test/run-make/print-cfg/Makefile b/src/test/run-make-fulldeps/print-cfg/Makefile similarity index 100% rename from src/test/run-make/print-cfg/Makefile rename to src/test/run-make-fulldeps/print-cfg/Makefile diff --git a/src/test/run-make/print-target-list/Makefile b/src/test/run-make-fulldeps/print-target-list/Makefile similarity index 100% rename from src/test/run-make/print-target-list/Makefile rename to src/test/run-make-fulldeps/print-target-list/Makefile diff --git a/src/test/run-make/profile/Makefile b/src/test/run-make-fulldeps/profile/Makefile similarity index 100% rename from src/test/run-make/profile/Makefile rename to src/test/run-make-fulldeps/profile/Makefile diff --git a/src/test/run-make/profile/test.rs b/src/test/run-make-fulldeps/profile/test.rs similarity index 100% rename from src/test/run-make/profile/test.rs rename to src/test/run-make-fulldeps/profile/test.rs diff --git a/src/test/run-make/prune-link-args/Makefile b/src/test/run-make-fulldeps/prune-link-args/Makefile similarity index 100% rename from src/test/run-make/prune-link-args/Makefile rename to src/test/run-make-fulldeps/prune-link-args/Makefile diff --git a/src/test/run-make/prune-link-args/empty.rs b/src/test/run-make-fulldeps/prune-link-args/empty.rs similarity index 100% rename from src/test/run-make/prune-link-args/empty.rs rename to src/test/run-make-fulldeps/prune-link-args/empty.rs diff --git a/src/test/run-make/relocation-model/Makefile b/src/test/run-make-fulldeps/relocation-model/Makefile similarity index 100% rename from src/test/run-make/relocation-model/Makefile rename to src/test/run-make-fulldeps/relocation-model/Makefile diff --git a/src/test/run-make/relocation-model/foo.rs b/src/test/run-make-fulldeps/relocation-model/foo.rs similarity index 100% rename from src/test/run-make/relocation-model/foo.rs rename to src/test/run-make-fulldeps/relocation-model/foo.rs diff --git a/src/test/run-make/relro-levels/Makefile b/src/test/run-make-fulldeps/relro-levels/Makefile similarity index 100% rename from src/test/run-make/relro-levels/Makefile rename to src/test/run-make-fulldeps/relro-levels/Makefile diff --git a/src/test/run-make/relro-levels/hello.rs b/src/test/run-make-fulldeps/relro-levels/hello.rs similarity index 100% rename from src/test/run-make/relro-levels/hello.rs rename to src/test/run-make-fulldeps/relro-levels/hello.rs diff --git a/src/test/run-make/reproducible-build/Makefile b/src/test/run-make-fulldeps/reproducible-build/Makefile similarity index 100% rename from src/test/run-make/reproducible-build/Makefile rename to src/test/run-make-fulldeps/reproducible-build/Makefile diff --git a/src/test/run-make/reproducible-build/linker.rs b/src/test/run-make-fulldeps/reproducible-build/linker.rs similarity index 100% rename from src/test/run-make/reproducible-build/linker.rs rename to src/test/run-make-fulldeps/reproducible-build/linker.rs diff --git a/src/test/run-make/reproducible-build/reproducible-build-aux.rs b/src/test/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs similarity index 100% rename from src/test/run-make/reproducible-build/reproducible-build-aux.rs rename to src/test/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs diff --git a/src/test/run-make/reproducible-build/reproducible-build.rs b/src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs similarity index 100% rename from src/test/run-make/reproducible-build/reproducible-build.rs rename to src/test/run-make-fulldeps/reproducible-build/reproducible-build.rs diff --git a/src/test/run-make/rlib-chain/Makefile b/src/test/run-make-fulldeps/rlib-chain/Makefile similarity index 100% rename from src/test/run-make/rlib-chain/Makefile rename to src/test/run-make-fulldeps/rlib-chain/Makefile diff --git a/src/test/run-make/rlib-chain/m1.rs b/src/test/run-make-fulldeps/rlib-chain/m1.rs similarity index 100% rename from src/test/run-make/rlib-chain/m1.rs rename to src/test/run-make-fulldeps/rlib-chain/m1.rs diff --git a/src/test/run-make/rlib-chain/m2.rs b/src/test/run-make-fulldeps/rlib-chain/m2.rs similarity index 100% rename from src/test/run-make/rlib-chain/m2.rs rename to src/test/run-make-fulldeps/rlib-chain/m2.rs diff --git a/src/test/run-make/rlib-chain/m3.rs b/src/test/run-make-fulldeps/rlib-chain/m3.rs similarity index 100% rename from src/test/run-make/rlib-chain/m3.rs rename to src/test/run-make-fulldeps/rlib-chain/m3.rs diff --git a/src/test/run-make/rlib-chain/m4.rs b/src/test/run-make-fulldeps/rlib-chain/m4.rs similarity index 100% rename from src/test/run-make/rlib-chain/m4.rs rename to src/test/run-make-fulldeps/rlib-chain/m4.rs diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile similarity index 100% rename from src/test/run-make/rustc-macro-dep-files/Makefile rename to src/test/run-make-fulldeps/rustc-macro-dep-files/Makefile diff --git a/src/test/run-make/rustc-macro-dep-files/bar.rs b/src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs similarity index 100% rename from src/test/run-make/rustc-macro-dep-files/bar.rs rename to src/test/run-make-fulldeps/rustc-macro-dep-files/bar.rs diff --git a/src/test/run-make/rustc-macro-dep-files/foo.rs b/src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs similarity index 100% rename from src/test/run-make/rustc-macro-dep-files/foo.rs rename to src/test/run-make-fulldeps/rustc-macro-dep-files/foo.rs diff --git a/src/test/run-make/rustdoc-error-lines/Makefile b/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile similarity index 100% rename from src/test/run-make/rustdoc-error-lines/Makefile rename to src/test/run-make-fulldeps/rustdoc-error-lines/Makefile diff --git a/src/test/run-make/rustdoc-error-lines/input.rs b/src/test/run-make-fulldeps/rustdoc-error-lines/input.rs similarity index 100% rename from src/test/run-make/rustdoc-error-lines/input.rs rename to src/test/run-make-fulldeps/rustdoc-error-lines/input.rs diff --git a/src/test/run-make/rustdoc-output-path/Makefile b/src/test/run-make-fulldeps/rustdoc-output-path/Makefile similarity index 100% rename from src/test/run-make/rustdoc-output-path/Makefile rename to src/test/run-make-fulldeps/rustdoc-output-path/Makefile diff --git a/src/test/run-make/rustdoc-output-path/foo.rs b/src/test/run-make-fulldeps/rustdoc-output-path/foo.rs similarity index 100% rename from src/test/run-make/rustdoc-output-path/foo.rs rename to src/test/run-make-fulldeps/rustdoc-output-path/foo.rs diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile similarity index 100% rename from src/test/run-make/sanitizer-address/Makefile rename to src/test/run-make-fulldeps/sanitizer-address/Makefile diff --git a/src/test/run-make/sanitizer-address/overflow.rs b/src/test/run-make-fulldeps/sanitizer-address/overflow.rs similarity index 100% rename from src/test/run-make/sanitizer-address/overflow.rs rename to src/test/run-make-fulldeps/sanitizer-address/overflow.rs diff --git a/src/test/run-make/sanitizer-cdylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile similarity index 100% rename from src/test/run-make/sanitizer-cdylib-link/Makefile rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile diff --git a/src/test/run-make/sanitizer-cdylib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-cdylib-link/library.rs similarity index 100% rename from src/test/run-make/sanitizer-cdylib-link/library.rs rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/library.rs diff --git a/src/test/run-make/sanitizer-cdylib-link/program.rs b/src/test/run-make-fulldeps/sanitizer-cdylib-link/program.rs similarity index 100% rename from src/test/run-make/sanitizer-cdylib-link/program.rs rename to src/test/run-make-fulldeps/sanitizer-cdylib-link/program.rs diff --git a/src/test/run-make/sanitizer-dylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile similarity index 100% rename from src/test/run-make/sanitizer-dylib-link/Makefile rename to src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile diff --git a/src/test/run-make/sanitizer-dylib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-dylib-link/library.rs similarity index 100% rename from src/test/run-make/sanitizer-dylib-link/library.rs rename to src/test/run-make-fulldeps/sanitizer-dylib-link/library.rs diff --git a/src/test/run-make/sanitizer-dylib-link/program.rs b/src/test/run-make-fulldeps/sanitizer-dylib-link/program.rs similarity index 100% rename from src/test/run-make/sanitizer-dylib-link/program.rs rename to src/test/run-make-fulldeps/sanitizer-dylib-link/program.rs diff --git a/src/test/run-make/sanitizer-invalid-cratetype/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile similarity index 100% rename from src/test/run-make/sanitizer-invalid-cratetype/Makefile rename to src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile diff --git a/src/test/run-make/sanitizer-invalid-cratetype/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs similarity index 100% rename from src/test/run-make/sanitizer-invalid-cratetype/hello.rs rename to src/test/run-make-fulldeps/sanitizer-invalid-cratetype/hello.rs diff --git a/src/test/run-make/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile similarity index 100% rename from src/test/run-make/sanitizer-invalid-target/Makefile rename to src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile diff --git a/src/test/run-make/sanitizer-invalid-target/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs similarity index 100% rename from src/test/run-make/sanitizer-invalid-target/hello.rs rename to src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile similarity index 100% rename from src/test/run-make/sanitizer-leak/Makefile rename to src/test/run-make-fulldeps/sanitizer-leak/Makefile diff --git a/src/test/run-make/sanitizer-leak/leak.rs b/src/test/run-make-fulldeps/sanitizer-leak/leak.rs similarity index 100% rename from src/test/run-make/sanitizer-leak/leak.rs rename to src/test/run-make-fulldeps/sanitizer-leak/leak.rs diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile similarity index 100% rename from src/test/run-make/sanitizer-memory/Makefile rename to src/test/run-make-fulldeps/sanitizer-memory/Makefile diff --git a/src/test/run-make/sanitizer-memory/uninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs similarity index 100% rename from src/test/run-make/sanitizer-memory/uninit.rs rename to src/test/run-make-fulldeps/sanitizer-memory/uninit.rs diff --git a/src/test/run-make/sanitizer-staticlib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile similarity index 100% rename from src/test/run-make/sanitizer-staticlib-link/Makefile rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile diff --git a/src/test/run-make/sanitizer-staticlib-link/library.rs b/src/test/run-make-fulldeps/sanitizer-staticlib-link/library.rs similarity index 100% rename from src/test/run-make/sanitizer-staticlib-link/library.rs rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/library.rs diff --git a/src/test/run-make/sanitizer-staticlib-link/program.c b/src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c similarity index 100% rename from src/test/run-make/sanitizer-staticlib-link/program.c rename to src/test/run-make-fulldeps/sanitizer-staticlib-link/program.c diff --git a/src/test/run-make/save-analysis-fail/Makefile b/src/test/run-make-fulldeps/save-analysis-fail/Makefile similarity index 100% rename from src/test/run-make/save-analysis-fail/Makefile rename to src/test/run-make-fulldeps/save-analysis-fail/Makefile diff --git a/src/test/run-make/save-analysis-fail/SameDir.rs b/src/test/run-make-fulldeps/save-analysis-fail/SameDir.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/SameDir.rs rename to src/test/run-make-fulldeps/save-analysis-fail/SameDir.rs diff --git a/src/test/run-make/save-analysis-fail/SameDir3.rs b/src/test/run-make-fulldeps/save-analysis-fail/SameDir3.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/SameDir3.rs rename to src/test/run-make-fulldeps/save-analysis-fail/SameDir3.rs diff --git a/src/test/run-make/save-analysis-fail/SubDir/mod.rs b/src/test/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/SubDir/mod.rs rename to src/test/run-make-fulldeps/save-analysis-fail/SubDir/mod.rs diff --git a/src/test/run-make/save-analysis-fail/foo.rs b/src/test/run-make-fulldeps/save-analysis-fail/foo.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/foo.rs rename to src/test/run-make-fulldeps/save-analysis-fail/foo.rs diff --git a/src/test/run-make/save-analysis-fail/krate2.rs b/src/test/run-make-fulldeps/save-analysis-fail/krate2.rs similarity index 100% rename from src/test/run-make/save-analysis-fail/krate2.rs rename to src/test/run-make-fulldeps/save-analysis-fail/krate2.rs diff --git a/src/test/run-make/save-analysis/Makefile b/src/test/run-make-fulldeps/save-analysis/Makefile similarity index 100% rename from src/test/run-make/save-analysis/Makefile rename to src/test/run-make-fulldeps/save-analysis/Makefile diff --git a/src/test/run-make/save-analysis/SameDir.rs b/src/test/run-make-fulldeps/save-analysis/SameDir.rs similarity index 100% rename from src/test/run-make/save-analysis/SameDir.rs rename to src/test/run-make-fulldeps/save-analysis/SameDir.rs diff --git a/src/test/run-make/save-analysis/SameDir3.rs b/src/test/run-make-fulldeps/save-analysis/SameDir3.rs similarity index 100% rename from src/test/run-make/save-analysis/SameDir3.rs rename to src/test/run-make-fulldeps/save-analysis/SameDir3.rs diff --git a/src/test/run-make/save-analysis/SubDir/mod.rs b/src/test/run-make-fulldeps/save-analysis/SubDir/mod.rs similarity index 100% rename from src/test/run-make/save-analysis/SubDir/mod.rs rename to src/test/run-make-fulldeps/save-analysis/SubDir/mod.rs diff --git a/src/test/run-make/save-analysis/extra-docs.md b/src/test/run-make-fulldeps/save-analysis/extra-docs.md similarity index 100% rename from src/test/run-make/save-analysis/extra-docs.md rename to src/test/run-make-fulldeps/save-analysis/extra-docs.md diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make-fulldeps/save-analysis/foo.rs similarity index 100% rename from src/test/run-make/save-analysis/foo.rs rename to src/test/run-make-fulldeps/save-analysis/foo.rs diff --git a/src/test/run-make/save-analysis/krate2.rs b/src/test/run-make-fulldeps/save-analysis/krate2.rs similarity index 100% rename from src/test/run-make/save-analysis/krate2.rs rename to src/test/run-make-fulldeps/save-analysis/krate2.rs diff --git a/src/test/run-make/sepcomp-cci-copies/Makefile b/src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile similarity index 100% rename from src/test/run-make/sepcomp-cci-copies/Makefile rename to src/test/run-make-fulldeps/sepcomp-cci-copies/Makefile diff --git a/src/test/run-make/sepcomp-cci-copies/cci_lib.rs b/src/test/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs similarity index 100% rename from src/test/run-make/sepcomp-cci-copies/cci_lib.rs rename to src/test/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs diff --git a/src/test/run-make/sepcomp-cci-copies/foo.rs b/src/test/run-make-fulldeps/sepcomp-cci-copies/foo.rs similarity index 100% rename from src/test/run-make/sepcomp-cci-copies/foo.rs rename to src/test/run-make-fulldeps/sepcomp-cci-copies/foo.rs diff --git a/src/test/run-make/sepcomp-inlining/Makefile b/src/test/run-make-fulldeps/sepcomp-inlining/Makefile similarity index 100% rename from src/test/run-make/sepcomp-inlining/Makefile rename to src/test/run-make-fulldeps/sepcomp-inlining/Makefile diff --git a/src/test/run-make/sepcomp-inlining/foo.rs b/src/test/run-make-fulldeps/sepcomp-inlining/foo.rs similarity index 100% rename from src/test/run-make/sepcomp-inlining/foo.rs rename to src/test/run-make-fulldeps/sepcomp-inlining/foo.rs diff --git a/src/test/run-make/sepcomp-separate/Makefile b/src/test/run-make-fulldeps/sepcomp-separate/Makefile similarity index 100% rename from src/test/run-make/sepcomp-separate/Makefile rename to src/test/run-make-fulldeps/sepcomp-separate/Makefile diff --git a/src/test/run-make/sepcomp-separate/foo.rs b/src/test/run-make-fulldeps/sepcomp-separate/foo.rs similarity index 100% rename from src/test/run-make/sepcomp-separate/foo.rs rename to src/test/run-make-fulldeps/sepcomp-separate/foo.rs diff --git a/src/test/run-make/simd-ffi/Makefile b/src/test/run-make-fulldeps/simd-ffi/Makefile similarity index 100% rename from src/test/run-make/simd-ffi/Makefile rename to src/test/run-make-fulldeps/simd-ffi/Makefile diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make-fulldeps/simd-ffi/simd.rs similarity index 100% rename from src/test/run-make/simd-ffi/simd.rs rename to src/test/run-make-fulldeps/simd-ffi/simd.rs diff --git a/src/test/run-make/simple-dylib/Makefile b/src/test/run-make-fulldeps/simple-dylib/Makefile similarity index 100% rename from src/test/run-make/simple-dylib/Makefile rename to src/test/run-make-fulldeps/simple-dylib/Makefile diff --git a/src/test/run-make/simple-dylib/bar.rs b/src/test/run-make-fulldeps/simple-dylib/bar.rs similarity index 100% rename from src/test/run-make/simple-dylib/bar.rs rename to src/test/run-make-fulldeps/simple-dylib/bar.rs diff --git a/src/test/run-make/simple-dylib/foo.rs b/src/test/run-make-fulldeps/simple-dylib/foo.rs similarity index 100% rename from src/test/run-make/simple-dylib/foo.rs rename to src/test/run-make-fulldeps/simple-dylib/foo.rs diff --git a/src/test/run-make/simple-rlib/Makefile b/src/test/run-make-fulldeps/simple-rlib/Makefile similarity index 100% rename from src/test/run-make/simple-rlib/Makefile rename to src/test/run-make-fulldeps/simple-rlib/Makefile diff --git a/src/test/run-make/simple-rlib/bar.rs b/src/test/run-make-fulldeps/simple-rlib/bar.rs similarity index 100% rename from src/test/run-make/simple-rlib/bar.rs rename to src/test/run-make-fulldeps/simple-rlib/bar.rs diff --git a/src/test/run-make/simple-rlib/foo.rs b/src/test/run-make-fulldeps/simple-rlib/foo.rs similarity index 100% rename from src/test/run-make/simple-rlib/foo.rs rename to src/test/run-make-fulldeps/simple-rlib/foo.rs diff --git a/src/test/run-make/stable-symbol-names/Makefile b/src/test/run-make-fulldeps/stable-symbol-names/Makefile similarity index 100% rename from src/test/run-make/stable-symbol-names/Makefile rename to src/test/run-make-fulldeps/stable-symbol-names/Makefile diff --git a/src/test/run-make/stable-symbol-names/stable-symbol-names1.rs b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs similarity index 100% rename from src/test/run-make/stable-symbol-names/stable-symbol-names1.rs rename to src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs diff --git a/src/test/run-make/stable-symbol-names/stable-symbol-names2.rs b/src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs similarity index 100% rename from src/test/run-make/stable-symbol-names/stable-symbol-names2.rs rename to src/test/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs diff --git a/src/test/run-make/static-dylib-by-default/Makefile b/src/test/run-make-fulldeps/static-dylib-by-default/Makefile similarity index 100% rename from src/test/run-make/static-dylib-by-default/Makefile rename to src/test/run-make-fulldeps/static-dylib-by-default/Makefile diff --git a/src/test/run-make/static-dylib-by-default/bar.rs b/src/test/run-make-fulldeps/static-dylib-by-default/bar.rs similarity index 100% rename from src/test/run-make/static-dylib-by-default/bar.rs rename to src/test/run-make-fulldeps/static-dylib-by-default/bar.rs diff --git a/src/test/run-make/static-dylib-by-default/foo.rs b/src/test/run-make-fulldeps/static-dylib-by-default/foo.rs similarity index 100% rename from src/test/run-make/static-dylib-by-default/foo.rs rename to src/test/run-make-fulldeps/static-dylib-by-default/foo.rs diff --git a/src/test/run-make/static-dylib-by-default/main.c b/src/test/run-make-fulldeps/static-dylib-by-default/main.c similarity index 100% rename from src/test/run-make/static-dylib-by-default/main.c rename to src/test/run-make-fulldeps/static-dylib-by-default/main.c diff --git a/src/test/run-make/static-nobundle/Makefile b/src/test/run-make-fulldeps/static-nobundle/Makefile similarity index 100% rename from src/test/run-make/static-nobundle/Makefile rename to src/test/run-make-fulldeps/static-nobundle/Makefile diff --git a/src/test/run-make/static-nobundle/aaa.c b/src/test/run-make-fulldeps/static-nobundle/aaa.c similarity index 100% rename from src/test/run-make/static-nobundle/aaa.c rename to src/test/run-make-fulldeps/static-nobundle/aaa.c diff --git a/src/test/run-make/static-nobundle/bbb.rs b/src/test/run-make-fulldeps/static-nobundle/bbb.rs similarity index 100% rename from src/test/run-make/static-nobundle/bbb.rs rename to src/test/run-make-fulldeps/static-nobundle/bbb.rs diff --git a/src/test/run-make/static-nobundle/ccc.rs b/src/test/run-make-fulldeps/static-nobundle/ccc.rs similarity index 100% rename from src/test/run-make/static-nobundle/ccc.rs rename to src/test/run-make-fulldeps/static-nobundle/ccc.rs diff --git a/src/test/run-make/static-nobundle/ddd.rs b/src/test/run-make-fulldeps/static-nobundle/ddd.rs similarity index 100% rename from src/test/run-make/static-nobundle/ddd.rs rename to src/test/run-make-fulldeps/static-nobundle/ddd.rs diff --git a/src/test/run-make/static-unwinding/Makefile b/src/test/run-make-fulldeps/static-unwinding/Makefile similarity index 100% rename from src/test/run-make/static-unwinding/Makefile rename to src/test/run-make-fulldeps/static-unwinding/Makefile diff --git a/src/test/run-make/static-unwinding/lib.rs b/src/test/run-make-fulldeps/static-unwinding/lib.rs similarity index 100% rename from src/test/run-make/static-unwinding/lib.rs rename to src/test/run-make-fulldeps/static-unwinding/lib.rs diff --git a/src/test/run-make/static-unwinding/main.rs b/src/test/run-make-fulldeps/static-unwinding/main.rs similarity index 100% rename from src/test/run-make/static-unwinding/main.rs rename to src/test/run-make-fulldeps/static-unwinding/main.rs diff --git a/src/test/run-make/staticlib-blank-lib/Makefile b/src/test/run-make-fulldeps/staticlib-blank-lib/Makefile similarity index 100% rename from src/test/run-make/staticlib-blank-lib/Makefile rename to src/test/run-make-fulldeps/staticlib-blank-lib/Makefile diff --git a/src/test/run-make/staticlib-blank-lib/foo.rs b/src/test/run-make-fulldeps/staticlib-blank-lib/foo.rs similarity index 100% rename from src/test/run-make/staticlib-blank-lib/foo.rs rename to src/test/run-make-fulldeps/staticlib-blank-lib/foo.rs diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make-fulldeps/stdin-non-utf8/Makefile similarity index 100% rename from src/test/run-make/stdin-non-utf8/Makefile rename to src/test/run-make-fulldeps/stdin-non-utf8/Makefile diff --git a/src/test/run-make/stdin-non-utf8/non-utf8 b/src/test/run-make-fulldeps/stdin-non-utf8/non-utf8 similarity index 100% rename from src/test/run-make/stdin-non-utf8/non-utf8 rename to src/test/run-make-fulldeps/stdin-non-utf8/non-utf8 diff --git a/src/test/run-make/suspicious-library/Makefile b/src/test/run-make-fulldeps/suspicious-library/Makefile similarity index 100% rename from src/test/run-make/suspicious-library/Makefile rename to src/test/run-make-fulldeps/suspicious-library/Makefile diff --git a/src/test/run-make/suspicious-library/bar.rs b/src/test/run-make-fulldeps/suspicious-library/bar.rs similarity index 100% rename from src/test/run-make/suspicious-library/bar.rs rename to src/test/run-make-fulldeps/suspicious-library/bar.rs diff --git a/src/test/run-make/suspicious-library/foo.rs b/src/test/run-make-fulldeps/suspicious-library/foo.rs similarity index 100% rename from src/test/run-make/suspicious-library/foo.rs rename to src/test/run-make-fulldeps/suspicious-library/foo.rs diff --git a/src/test/run-make/symbol-visibility/Makefile b/src/test/run-make-fulldeps/symbol-visibility/Makefile similarity index 100% rename from src/test/run-make/symbol-visibility/Makefile rename to src/test/run-make-fulldeps/symbol-visibility/Makefile diff --git a/src/test/run-make/symbol-visibility/a_cdylib.rs b/src/test/run-make-fulldeps/symbol-visibility/a_cdylib.rs similarity index 100% rename from src/test/run-make/symbol-visibility/a_cdylib.rs rename to src/test/run-make-fulldeps/symbol-visibility/a_cdylib.rs diff --git a/src/test/run-make/symbol-visibility/a_rust_dylib.rs b/src/test/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs similarity index 100% rename from src/test/run-make/symbol-visibility/a_rust_dylib.rs rename to src/test/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs diff --git a/src/test/run-make/symbol-visibility/an_executable.rs b/src/test/run-make-fulldeps/symbol-visibility/an_executable.rs similarity index 100% rename from src/test/run-make/symbol-visibility/an_executable.rs rename to src/test/run-make-fulldeps/symbol-visibility/an_executable.rs diff --git a/src/test/run-make/symbol-visibility/an_rlib.rs b/src/test/run-make-fulldeps/symbol-visibility/an_rlib.rs similarity index 100% rename from src/test/run-make/symbol-visibility/an_rlib.rs rename to src/test/run-make-fulldeps/symbol-visibility/an_rlib.rs diff --git a/src/test/run-make/symbols-are-reasonable/Makefile b/src/test/run-make-fulldeps/symbols-are-reasonable/Makefile similarity index 100% rename from src/test/run-make/symbols-are-reasonable/Makefile rename to src/test/run-make-fulldeps/symbols-are-reasonable/Makefile diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs similarity index 100% rename from src/test/run-make/symbols-are-reasonable/lib.rs rename to src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs diff --git a/src/test/run-make/symbols-include-type-name/Makefile b/src/test/run-make-fulldeps/symbols-include-type-name/Makefile similarity index 100% rename from src/test/run-make/symbols-include-type-name/Makefile rename to src/test/run-make-fulldeps/symbols-include-type-name/Makefile diff --git a/src/test/run-make/symbols-include-type-name/lib.rs b/src/test/run-make-fulldeps/symbols-include-type-name/lib.rs similarity index 100% rename from src/test/run-make/symbols-include-type-name/lib.rs rename to src/test/run-make-fulldeps/symbols-include-type-name/lib.rs diff --git a/src/test/run-make/symlinked-extern/Makefile b/src/test/run-make-fulldeps/symlinked-extern/Makefile similarity index 100% rename from src/test/run-make/symlinked-extern/Makefile rename to src/test/run-make-fulldeps/symlinked-extern/Makefile diff --git a/src/test/run-make/symlinked-extern/bar.rs b/src/test/run-make-fulldeps/symlinked-extern/bar.rs similarity index 100% rename from src/test/run-make/symlinked-extern/bar.rs rename to src/test/run-make-fulldeps/symlinked-extern/bar.rs diff --git a/src/test/run-make/symlinked-extern/baz.rs b/src/test/run-make-fulldeps/symlinked-extern/baz.rs similarity index 100% rename from src/test/run-make/symlinked-extern/baz.rs rename to src/test/run-make-fulldeps/symlinked-extern/baz.rs diff --git a/src/test/run-make/symlinked-extern/foo.rs b/src/test/run-make-fulldeps/symlinked-extern/foo.rs similarity index 100% rename from src/test/run-make/symlinked-extern/foo.rs rename to src/test/run-make-fulldeps/symlinked-extern/foo.rs diff --git a/src/test/run-make/symlinked-libraries/Makefile b/src/test/run-make-fulldeps/symlinked-libraries/Makefile similarity index 100% rename from src/test/run-make/symlinked-libraries/Makefile rename to src/test/run-make-fulldeps/symlinked-libraries/Makefile diff --git a/src/test/run-make/symlinked-libraries/bar.rs b/src/test/run-make-fulldeps/symlinked-libraries/bar.rs similarity index 100% rename from src/test/run-make/symlinked-libraries/bar.rs rename to src/test/run-make-fulldeps/symlinked-libraries/bar.rs diff --git a/src/test/run-make/symlinked-libraries/foo.rs b/src/test/run-make-fulldeps/symlinked-libraries/foo.rs similarity index 100% rename from src/test/run-make/symlinked-libraries/foo.rs rename to src/test/run-make-fulldeps/symlinked-libraries/foo.rs diff --git a/src/test/run-make/symlinked-rlib/Makefile b/src/test/run-make-fulldeps/symlinked-rlib/Makefile similarity index 100% rename from src/test/run-make/symlinked-rlib/Makefile rename to src/test/run-make-fulldeps/symlinked-rlib/Makefile diff --git a/src/test/run-make/symlinked-rlib/bar.rs b/src/test/run-make-fulldeps/symlinked-rlib/bar.rs similarity index 100% rename from src/test/run-make/symlinked-rlib/bar.rs rename to src/test/run-make-fulldeps/symlinked-rlib/bar.rs diff --git a/src/test/run-make/symlinked-rlib/foo.rs b/src/test/run-make-fulldeps/symlinked-rlib/foo.rs similarity index 100% rename from src/test/run-make/symlinked-rlib/foo.rs rename to src/test/run-make-fulldeps/symlinked-rlib/foo.rs diff --git a/src/test/run-make/sysroot-crates-are-unstable/Makefile b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile similarity index 100% rename from src/test/run-make/sysroot-crates-are-unstable/Makefile rename to src/test/run-make-fulldeps/sysroot-crates-are-unstable/Makefile diff --git a/src/test/run-make/sysroot-crates-are-unstable/test.py b/src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py similarity index 100% rename from src/test/run-make/sysroot-crates-are-unstable/test.py rename to src/test/run-make-fulldeps/sysroot-crates-are-unstable/test.py diff --git a/src/test/run-make/target-cpu-native/Makefile b/src/test/run-make-fulldeps/target-cpu-native/Makefile similarity index 100% rename from src/test/run-make/target-cpu-native/Makefile rename to src/test/run-make-fulldeps/target-cpu-native/Makefile diff --git a/src/test/run-make/target-cpu-native/foo.rs b/src/test/run-make-fulldeps/target-cpu-native/foo.rs similarity index 100% rename from src/test/run-make/target-cpu-native/foo.rs rename to src/test/run-make-fulldeps/target-cpu-native/foo.rs diff --git a/src/test/run-make/target-specs/Makefile b/src/test/run-make-fulldeps/target-specs/Makefile similarity index 100% rename from src/test/run-make/target-specs/Makefile rename to src/test/run-make-fulldeps/target-specs/Makefile diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make-fulldeps/target-specs/foo.rs similarity index 100% rename from src/test/run-make/target-specs/foo.rs rename to src/test/run-make-fulldeps/target-specs/foo.rs diff --git a/src/test/run-make/target-specs/my-awesome-platform.json b/src/test/run-make-fulldeps/target-specs/my-awesome-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-awesome-platform.json rename to src/test/run-make-fulldeps/target-specs/my-awesome-platform.json diff --git a/src/test/run-make/target-specs/my-incomplete-platform.json b/src/test/run-make-fulldeps/target-specs/my-incomplete-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-incomplete-platform.json rename to src/test/run-make-fulldeps/target-specs/my-incomplete-platform.json diff --git a/src/test/run-make/target-specs/my-invalid-platform.json b/src/test/run-make-fulldeps/target-specs/my-invalid-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-invalid-platform.json rename to src/test/run-make-fulldeps/target-specs/my-invalid-platform.json diff --git a/src/test/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json b/src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json similarity index 100% rename from src/test/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json rename to src/test/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json diff --git a/src/test/run-make/target-without-atomics/Makefile b/src/test/run-make-fulldeps/target-without-atomics/Makefile similarity index 100% rename from src/test/run-make/target-without-atomics/Makefile rename to src/test/run-make-fulldeps/target-without-atomics/Makefile diff --git a/src/test/run-make/test-harness/Makefile b/src/test/run-make-fulldeps/test-harness/Makefile similarity index 100% rename from src/test/run-make/test-harness/Makefile rename to src/test/run-make-fulldeps/test-harness/Makefile diff --git a/src/test/run-make/test-harness/test-ignore-cfg.rs b/src/test/run-make-fulldeps/test-harness/test-ignore-cfg.rs similarity index 100% rename from src/test/run-make/test-harness/test-ignore-cfg.rs rename to src/test/run-make-fulldeps/test-harness/test-ignore-cfg.rs diff --git a/src/test/run-make/tools.mk b/src/test/run-make-fulldeps/tools.mk similarity index 100% rename from src/test/run-make/tools.mk rename to src/test/run-make-fulldeps/tools.mk diff --git a/src/test/run-make/treat-err-as-bug/Makefile b/src/test/run-make-fulldeps/treat-err-as-bug/Makefile similarity index 100% rename from src/test/run-make/treat-err-as-bug/Makefile rename to src/test/run-make-fulldeps/treat-err-as-bug/Makefile diff --git a/src/test/run-make/treat-err-as-bug/err.rs b/src/test/run-make-fulldeps/treat-err-as-bug/err.rs similarity index 100% rename from src/test/run-make/treat-err-as-bug/err.rs rename to src/test/run-make-fulldeps/treat-err-as-bug/err.rs diff --git a/src/test/run-make/type-mismatch-same-crate-name/Makefile b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/Makefile rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/Makefile diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateA.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/crateA.rs rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateB.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/crateB.rs rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs diff --git a/src/test/run-make/type-mismatch-same-crate-name/crateC.rs b/src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs similarity index 100% rename from src/test/run-make/type-mismatch-same-crate-name/crateC.rs rename to src/test/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs diff --git a/src/test/run-make/use-extern-for-plugins/Makefile b/src/test/run-make-fulldeps/use-extern-for-plugins/Makefile similarity index 100% rename from src/test/run-make/use-extern-for-plugins/Makefile rename to src/test/run-make-fulldeps/use-extern-for-plugins/Makefile diff --git a/src/test/run-make/use-extern-for-plugins/bar.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/bar.rs similarity index 100% rename from src/test/run-make/use-extern-for-plugins/bar.rs rename to src/test/run-make-fulldeps/use-extern-for-plugins/bar.rs diff --git a/src/test/run-make/use-extern-for-plugins/baz.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/baz.rs similarity index 100% rename from src/test/run-make/use-extern-for-plugins/baz.rs rename to src/test/run-make-fulldeps/use-extern-for-plugins/baz.rs diff --git a/src/test/run-make/use-extern-for-plugins/foo.rs b/src/test/run-make-fulldeps/use-extern-for-plugins/foo.rs similarity index 100% rename from src/test/run-make/use-extern-for-plugins/foo.rs rename to src/test/run-make-fulldeps/use-extern-for-plugins/foo.rs diff --git a/src/test/run-make/used/Makefile b/src/test/run-make-fulldeps/used/Makefile similarity index 100% rename from src/test/run-make/used/Makefile rename to src/test/run-make-fulldeps/used/Makefile diff --git a/src/test/run-make/used/used.rs b/src/test/run-make-fulldeps/used/used.rs similarity index 100% rename from src/test/run-make/used/used.rs rename to src/test/run-make-fulldeps/used/used.rs diff --git a/src/test/run-make/version/Makefile b/src/test/run-make-fulldeps/version/Makefile similarity index 100% rename from src/test/run-make/version/Makefile rename to src/test/run-make-fulldeps/version/Makefile diff --git a/src/test/run-make/volatile-intrinsics/Makefile b/src/test/run-make-fulldeps/volatile-intrinsics/Makefile similarity index 100% rename from src/test/run-make/volatile-intrinsics/Makefile rename to src/test/run-make-fulldeps/volatile-intrinsics/Makefile diff --git a/src/test/run-make/volatile-intrinsics/main.rs b/src/test/run-make-fulldeps/volatile-intrinsics/main.rs similarity index 100% rename from src/test/run-make/volatile-intrinsics/main.rs rename to src/test/run-make-fulldeps/volatile-intrinsics/main.rs diff --git a/src/test/run-make/weird-output-filenames/Makefile b/src/test/run-make-fulldeps/weird-output-filenames/Makefile similarity index 100% rename from src/test/run-make/weird-output-filenames/Makefile rename to src/test/run-make-fulldeps/weird-output-filenames/Makefile diff --git a/src/test/run-make/weird-output-filenames/foo.rs b/src/test/run-make-fulldeps/weird-output-filenames/foo.rs similarity index 100% rename from src/test/run-make/weird-output-filenames/foo.rs rename to src/test/run-make-fulldeps/weird-output-filenames/foo.rs diff --git a/src/test/run-make/windows-spawn/Makefile b/src/test/run-make-fulldeps/windows-spawn/Makefile similarity index 100% rename from src/test/run-make/windows-spawn/Makefile rename to src/test/run-make-fulldeps/windows-spawn/Makefile diff --git a/src/test/run-make/windows-spawn/hello.rs b/src/test/run-make-fulldeps/windows-spawn/hello.rs similarity index 100% rename from src/test/run-make/windows-spawn/hello.rs rename to src/test/run-make-fulldeps/windows-spawn/hello.rs diff --git a/src/test/run-make/windows-spawn/spawn.rs b/src/test/run-make-fulldeps/windows-spawn/spawn.rs similarity index 100% rename from src/test/run-make/windows-spawn/spawn.rs rename to src/test/run-make-fulldeps/windows-spawn/spawn.rs diff --git a/src/test/run-make/windows-subsystem/Makefile b/src/test/run-make-fulldeps/windows-subsystem/Makefile similarity index 100% rename from src/test/run-make/windows-subsystem/Makefile rename to src/test/run-make-fulldeps/windows-subsystem/Makefile diff --git a/src/test/run-make/windows-subsystem/console.rs b/src/test/run-make-fulldeps/windows-subsystem/console.rs similarity index 100% rename from src/test/run-make/windows-subsystem/console.rs rename to src/test/run-make-fulldeps/windows-subsystem/console.rs diff --git a/src/test/run-make/windows-subsystem/windows.rs b/src/test/run-make-fulldeps/windows-subsystem/windows.rs similarity index 100% rename from src/test/run-make/windows-subsystem/windows.rs rename to src/test/run-make-fulldeps/windows-subsystem/windows.rs diff --git a/src/test/run-make/wasm-custom-section/Makefile b/src/test/run-make/wasm-custom-section/Makefile new file mode 100644 index 000000000000..399951e51631 --- /dev/null +++ b/src/test/run-make/wasm-custom-section/Makefile @@ -0,0 +1,10 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) foo.rs --target wasm32-unknown-unknown + $(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown + $(NODE) foo.js $(TMPDIR)/bar.wasm +else +all: +endif diff --git a/src/test/run-make/wasm-custom-section/bar.rs b/src/test/run-make/wasm-custom-section/bar.rs new file mode 100644 index 000000000000..e3db36d6dbd4 --- /dev/null +++ b/src/test/run-make/wasm-custom-section/bar.rs @@ -0,0 +1,24 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "cdylib"] +#![feature(wasm_custom_section)] +#![deny(warnings)] + +extern crate foo; + +#[wasm_custom_section = "foo"] +const A: [u8; 2] = [5, 6]; + +#[wasm_custom_section = "baz"] +const B: [u8; 2] = [7, 8]; + +#[no_mangle] +pub extern fn foo() {} diff --git a/src/test/run-make/wasm-custom-section/foo.js b/src/test/run-make/wasm-custom-section/foo.js new file mode 100644 index 000000000000..df69354f3a40 --- /dev/null +++ b/src/test/run-make/wasm-custom-section/foo.js @@ -0,0 +1,46 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const fs = require('fs'); +const process = require('process'); +const assert = require('assert'); +const buffer = fs.readFileSync(process.argv[2]); + +let m = new WebAssembly.Module(buffer); +let sections = WebAssembly.Module.customSections(m, "baz"); +console.log('section baz', sections); +assert.strictEqual(sections.length, 1); +let section = new Uint8Array(sections[0]); +console.log('contents', section); +assert.strictEqual(section.length, 2); +assert.strictEqual(section[0], 7); +assert.strictEqual(section[1], 8); + +sections = WebAssembly.Module.customSections(m, "bar"); +console.log('section bar', sections); +assert.strictEqual(sections.length, 1, "didn't pick up `bar` section from dependency"); +section = new Uint8Array(sections[0]); +console.log('contents', section); +assert.strictEqual(section.length, 2); +assert.strictEqual(section[0], 3); +assert.strictEqual(section[1], 4); + +sections = WebAssembly.Module.customSections(m, "foo"); +console.log('section foo', sections); +assert.strictEqual(sections.length, 1, "didn't create `foo` section"); +section = new Uint8Array(sections[0]); +console.log('contents', section); +assert.strictEqual(section.length, 4, "didn't concatenate `foo` sections"); +assert.strictEqual(section[0], 5); +assert.strictEqual(section[1], 6); +assert.strictEqual(section[2], 1); +assert.strictEqual(section[3], 2); + +process.exit(1); diff --git a/src/test/run-make/wasm-custom-section/foo.rs b/src/test/run-make/wasm-custom-section/foo.rs new file mode 100644 index 000000000000..44d1efd7c2d6 --- /dev/null +++ b/src/test/run-make/wasm-custom-section/foo.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(wasm_custom_section)] +#![deny(warnings)] + +#[wasm_custom_section = "foo"] +const A: [u8; 2] = [1, 2]; + +#[wasm_custom_section = "bar"] +const B: [u8; 2] = [3, 4]; diff --git a/src/test/ui/feature-gate-wasm_custom_section.rs b/src/test/ui/feature-gate-wasm_custom_section.rs new file mode 100644 index 000000000000..c695ef4ff068 --- /dev/null +++ b/src/test/ui/feature-gate-wasm_custom_section.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable +const A: [u8; 2] = [1, 2]; + +fn main() {} diff --git a/src/test/ui/feature-gate-wasm_custom_section.stderr b/src/test/ui/feature-gate-wasm_custom_section.stderr new file mode 100644 index 000000000000..5977ec9edad5 --- /dev/null +++ b/src/test/ui/feature-gate-wasm_custom_section.stderr @@ -0,0 +1,11 @@ +error[E0658]: attribute is currently unstable + --> $DIR/feature-gate-wasm_custom_section.rs:11:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(wasm_custom_section)] to the crate attributes to enable + +error: aborting due to previous error + +If you want more information on this error, try using "rustc --explain E0658" diff --git a/src/test/ui/wasm-custom-section/malformed.rs b/src/test/ui/wasm-custom-section/malformed.rs new file mode 100644 index 000000000000..13b1685a4807 --- /dev/null +++ b/src/test/ui/wasm-custom-section/malformed.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_custom_section)] + +#[wasm_custom_section] //~ ERROR: must be of the form +const A: [u8; 1] = [0]; + +#[wasm_custom_section(foo)] //~ ERROR: must be of the form +const B: [u8; 1] = [0]; + +fn main() {} diff --git a/src/test/ui/wasm-custom-section/malformed.stderr b/src/test/ui/wasm-custom-section/malformed.stderr new file mode 100644 index 000000000000..c716c824aebd --- /dev/null +++ b/src/test/ui/wasm-custom-section/malformed.stderr @@ -0,0 +1,14 @@ +error: must be of the form #[wasm_custom_section = "foo"] + --> $DIR/malformed.rs:13:1 + | +LL | #[wasm_custom_section] //~ ERROR: must be of the form + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: must be of the form #[wasm_custom_section = "foo"] + --> $DIR/malformed.rs:16:1 + | +LL | #[wasm_custom_section(foo)] //~ ERROR: must be of the form + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/wasm-custom-section/not-const.rs b/src/test/ui/wasm-custom-section/not-const.rs new file mode 100644 index 000000000000..68077fb2fe4a --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-const.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_custom_section)] + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +static A: [u8; 2] = [1, 2]; + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +struct B {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +enum C {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +impl B {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +mod d {} + +#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts +fn main() {} diff --git a/src/test/ui/wasm-custom-section/not-const.stderr b/src/test/ui/wasm-custom-section/not-const.stderr new file mode 100644 index 000000000000..17c85b3e848e --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-const.stderr @@ -0,0 +1,38 @@ +error: only allowed on consts + --> $DIR/not-const.rs:13:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:16:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:19:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:22:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:25:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: only allowed on consts + --> $DIR/not-const.rs:28:1 + | +LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + diff --git a/src/test/ui/wasm-custom-section/not-slice.rs b/src/test/ui/wasm-custom-section/not-slice.rs new file mode 100644 index 000000000000..2d91641a5f75 --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-slice.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_custom_section)] + +#[wasm_custom_section = "foo"] +const A: u8 = 0; //~ ERROR: must be an array of bytes + +#[wasm_custom_section = "foo"] +const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes + +#[wasm_custom_section = "foo"] +const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes + +fn main() {} diff --git a/src/test/ui/wasm-custom-section/not-slice.stderr b/src/test/ui/wasm-custom-section/not-slice.stderr new file mode 100644 index 000000000000..f2563ce0dddc --- /dev/null +++ b/src/test/ui/wasm-custom-section/not-slice.stderr @@ -0,0 +1,20 @@ +error: must be an array of bytes like `[u8; N]` + --> $DIR/not-slice.rs:14:1 + | +LL | const A: u8 = 0; //~ ERROR: must be an array of bytes + | ^^^^^^^^^^^^^^^^ + +error: must be an array of bytes like `[u8; N]` + --> $DIR/not-slice.rs:17:1 + | +LL | const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: must be an array of bytes like `[u8; N]` + --> $DIR/not-slice.rs:20:1 + | +LL | const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 43220af4893b..93b1b1f08e63 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2396,13 +2396,6 @@ impl<'test> TestCx<'test> { .env("S", src_root) .env("RUST_BUILD_STAGE", &self.config.stage_id) .env("RUSTC", cwd.join(&self.config.rustc_path)) - .env( - "RUSTDOC", - cwd.join(&self.config - .rustdoc_path - .as_ref() - .expect("--rustdoc-path passed")), - ) .env("TMPDIR", &tmpdir) .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path)) @@ -2417,6 +2410,14 @@ impl<'test> TestCx<'test> { .env_remove("MFLAGS") .env_remove("CARGO_MAKEFLAGS"); + if let Some(ref rustdoc) = self.config.rustdoc_path { + cmd.env("RUSTDOC", cwd.join(rustdoc)); + } + + if let Some(ref node) = self.config.nodejs { + cmd.env("NODE", node); + } + if let Some(ref linker) = self.config.linker { cmd.env("RUSTC_LINKER", linker); } From d889957dab5ee0778f9dd64faeafc8872645efed Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 10 Feb 2018 14:28:17 -0800 Subject: [PATCH 504/830] rustc: Add a `#[wasm_import_module]` attribute This commit adds a new attribute to the Rust compiler specific to the wasm target (and no other targets). The `#[wasm_import_module]` attribute is used to specify the module that a name is imported from, and is used like so: #[wasm_import_module = "./foo.js"] extern { fn some_js_function(); } Here the import of the symbol `some_js_function` is tagged with the `./foo.js` module in the wasm output file. Wasm-the-format includes two fields on all imports, a module and a field. The field is the symbol name (`some_js_function` above) and the module has historically unconditionally been `"env"`. I'm not sure if this `"env"` convention has asm.js or LLVM roots, but regardless we'd like the ability to configure it! The proposed ES module integration with wasm (aka a wasm module is "just another ES module") requires that the import module of wasm imports is interpreted as an ES module import, meaning that you'll need to encode paths, NPM packages, etc. As a result, we'll need this to be something other than `"env"`! Unfortunately neither our version of LLVM nor LLD supports custom import modules (aka anything not `"env"`). My hope is that by the time LLVM 7 is released both will have support, but in the meantime this commit adds some primitive encoding/decoding of wasm files to the compiler. This way rustc postprocesses the wasm module that LLVM emits to ensure it's got all the imports we'd like to have in it. Eventually I'd ideally like to unconditionally require this attribute to be placed on all `extern { ... }` blocks. For now though it seemed prudent to add it as an unstable attribute, so for now it's not required (as that'd force usage of a feature gate). Hopefully it doesn't take too long to "stabilize" this! cc rust-lang-nursery/rust-wasm#29 --- src/ci/docker/wasm32-unknown/Dockerfile | 1 + src/librustc/dep_graph/dep_node.rs | 3 + src/librustc/hir/check_attr.rs | 43 ++- src/librustc/ich/impls_cstore.rs | 7 +- src/librustc/middle/cstore.rs | 6 + src/librustc/ty/maps/config.rs | 18 ++ src/librustc/ty/maps/mod.rs | 9 +- src/librustc/ty/maps/plumbing.rs | 5 + src/librustc_metadata/creader.rs | 20 +- src/librustc_metadata/cstore.rs | 6 +- src/librustc_metadata/cstore_impl.rs | 22 +- src/librustc_metadata/decoder.rs | 10 +- src/librustc_metadata/encoder.rs | 12 +- src/librustc_metadata/foreign_modules.rs | 48 ++++ src/librustc_metadata/lib.rs | 1 + src/librustc_metadata/native_libs.rs | 7 +- src/librustc_metadata/schema.rs | 3 +- src/librustc_trans/attributes.rs | 46 +++ src/librustc_trans/back/link.rs | 1 + src/librustc_trans/back/wasm.rs | 267 ++++++++++++++++-- src/librustc_trans/base.rs | 52 +++- src/librustc_trans/lib.rs | 3 + src/libsyntax/feature_gate.rs | 7 + src/test/run-make/wasm-custom-section/foo.js | 2 +- src/test/run-make/wasm-import-module/Makefile | 10 + src/test/run-make/wasm-import-module/bar.rs | 29 ++ src/test/run-make/wasm-import-module/foo.js | 28 ++ src/test/run-make/wasm-import-module/foo.rs | 18 ++ .../feature-gate-wasm_custom_section.stderr | 2 +- .../ui/feature-gate-wasm_import_module.rs | 15 + .../ui/feature-gate-wasm_import_module.stderr | 11 + src/test/ui/wasm-import-module.rs | 20 ++ src/test/ui/wasm-import-module.stderr | 14 + 33 files changed, 662 insertions(+), 84 deletions(-) create mode 100644 src/librustc_metadata/foreign_modules.rs create mode 100644 src/test/run-make/wasm-import-module/Makefile create mode 100644 src/test/run-make/wasm-import-module/bar.rs create mode 100644 src/test/run-make/wasm-import-module/foo.js create mode 100644 src/test/run-make/wasm-import-module/foo.rs create mode 100644 src/test/ui/feature-gate-wasm_import_module.rs create mode 100644 src/test/ui/feature-gate-wasm_import_module.stderr create mode 100644 src/test/ui/wasm-import-module.rs create mode 100644 src/test/ui/wasm-import-module.stderr diff --git a/src/ci/docker/wasm32-unknown/Dockerfile b/src/ci/docker/wasm32-unknown/Dockerfile index 0972eb85191a..6c0ec1ad9d4e 100644 --- a/src/ci/docker/wasm32-unknown/Dockerfile +++ b/src/ci/docker/wasm32-unknown/Dockerfile @@ -26,6 +26,7 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.lld ENV SCRIPT python2.7 /checkout/x.py test --target $TARGETS \ + src/test/run-make \ src/test/ui \ src/test/run-pass \ src/test/compile-fail \ diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 09d7ce599ab0..8bcec79d99f1 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -593,6 +593,7 @@ define_dep_nodes!( <'tcx> [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId }, [] AllTraitImplementations(CrateNum), + [] DllimportForeignItems(CrateNum), [] IsDllimportForeignItem(DefId), [] IsStaticallyIncludedForeignItem(DefId), [] NativeLibraryKind(DefId), @@ -655,6 +656,8 @@ define_dep_nodes!( <'tcx> [input] Features, [] ProgramClausesFor(DefId), + [] WasmImportModuleMap(CrateNum), + [] ForeignModules(CrateNum), ); trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index f141cac16148..9b2647ad4db2 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -26,6 +26,7 @@ enum Target { Union, Enum, Const, + ForeignMod, Other, } @@ -37,6 +38,7 @@ impl Target { hir::ItemUnion(..) => Target::Union, hir::ItemEnum(..) => Target::Enum, hir::ItemConst(..) => Target::Const, + hir::ItemForeignMod(..) => Target::ForeignMod, _ => Target::Other, } } @@ -57,25 +59,42 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { .emit(); } + let mut has_wasm_import_module = false; for attr in &item.attrs { - if let Some(name) = attr.name() { - if name == "inline" { - self.check_inline(attr, item, target) + if attr.check_name("inline") { + self.check_inline(attr, item, target) + } else if attr.check_name("wasm_import_module") { + has_wasm_import_module = true; + if attr.value_str().is_none() { + self.tcx.sess.span_err(attr.span, "\ + must be of the form #[wasm_import_module = \"...\"]"); + } + if target != Target::ForeignMod { + self.tcx.sess.span_err(attr.span, "\ + must only be attached to foreign modules"); + } + } else if attr.check_name("wasm_custom_section") { + if target != Target::Const { + self.tcx.sess.span_err(attr.span, "only allowed on consts"); } - if name == "wasm_custom_section" { - if target != Target::Const { - self.tcx.sess.span_err(attr.span, "only allowed on consts"); - } - - if attr.value_str().is_none() { - self.tcx.sess.span_err(attr.span, "must be of the form \ - #[wasm_custom_section = \"foo\"]"); - } + if attr.value_str().is_none() { + self.tcx.sess.span_err(attr.span, "must be of the form \ + #[wasm_custom_section = \"foo\"]"); } } } + if target == Target::ForeignMod && + !has_wasm_import_module && + self.tcx.sess.target.target.arch == "wasm32" && + false // FIXME: eventually enable this warning when stable + { + self.tcx.sess.span_warn(item.span, "\ + must have a #[wasm_import_module = \"...\"] attribute, this \ + will become a hard error before too long"); + } + self.check_repr(item, target); } diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs index 18a02ff5c588..0071850e1052 100644 --- a/src/librustc/ich/impls_cstore.rs +++ b/src/librustc/ich/impls_cstore.rs @@ -33,7 +33,12 @@ impl_stable_hash_for!(struct middle::cstore::NativeLibrary { kind, name, cfg, - foreign_items + foreign_module +}); + +impl_stable_hash_for!(struct middle::cstore::ForeignModule { + foreign_items, + def_id }); impl_stable_hash_for!(enum middle::cstore::LinkagePreference { diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 3c451d7ae46a..add9b621596b 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -132,7 +132,13 @@ pub struct NativeLibrary { pub kind: NativeLibraryKind, pub name: Symbol, pub cfg: Option, + pub foreign_module: Option, +} + +#[derive(Clone, Hash, RustcEncodable, RustcDecodable)] +pub struct ForeignModule { pub foreign_items: Vec, + pub def_id: DefId, } pub enum LoadedMacro { diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 0b41c3ab2fa2..7565e90df986 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -430,6 +430,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::native_libraries<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::foreign_modules<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("looking up the foreign modules of a linked crate") + } +} + impl<'tcx> QueryDescription<'tcx> for queries::plugin_registrar_fn<'tcx> { fn describe(_tcx: TyCtxt, _: CrateNum) -> String { format!("looking up the plugin registrar for a crate") @@ -705,6 +711,18 @@ impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("wasm import module map") + } +} + +impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("wasm import module map") + } +} + macro_rules! impl_disk_cacheable_query( ($query_name:ident, |$key:tt| $cond:expr) => { impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> { diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2b4c1992762e..c16ad0d8ca14 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -18,7 +18,7 @@ use infer::canonical::{Canonical, QueryResult}; use lint; use middle::borrowck::BorrowCheckResult; use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, - ExternBodyNestedBodies}; + ExternBodyNestedBodies, ForeignModule}; use middle::cstore::{NativeLibraryKind, DepKind, CrateSource, ExternConstBody}; use middle::privacy::AccessLevels; use middle::reachable::ReachableSet; @@ -320,6 +320,9 @@ define_maps! { <'tcx> [] fn native_libraries: NativeLibraries(CrateNum) -> Lrc>, + + [] fn foreign_modules: ForeignModules(CrateNum) -> Lrc>, + [] fn plugin_registrar_fn: PluginRegistrarFn(CrateNum) -> Option, [] fn derive_registrar_fn: DeriveRegistrarFn(CrateNum) -> Option, [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator, @@ -331,6 +334,8 @@ define_maps! { <'tcx> [] fn all_trait_implementations: AllTraitImplementations(CrateNum) -> Lrc>, + [] fn dllimport_foreign_items: DllimportForeignItems(CrateNum) + -> Lrc>, [] fn is_dllimport_foreign_item: IsDllimportForeignItem(DefId) -> bool, [] fn is_statically_included_foreign_item: IsStaticallyIncludedForeignItem(DefId) -> bool, [] fn native_library_kind: NativeLibraryKind(DefId) @@ -426,6 +431,8 @@ define_maps! { <'tcx> [] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc>>, [] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc>, + [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum) + -> Lrc>, } ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 910c00b832ef..46106d8ec0e9 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -886,6 +886,9 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, force!(all_trait_implementations, krate!()); } + DepKind::DllimportForeignItems => { + force!(dllimport_foreign_items, krate!()); + } DepKind::IsDllimportForeignItem => { force!(is_dllimport_foreign_item, def_id!()); } @@ -941,6 +944,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); } DepKind::WasmCustomSections => { force!(wasm_custom_sections, krate!()); } + DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); } + DepKind::ForeignModules => { force!(foreign_modules, krate!()); } } true diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index a0546b369a8e..baaf57c89089 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -12,7 +12,6 @@ use cstore::{self, CStore, CrateSource, MetadataBlob}; use locator::{self, CratePaths}; -use native_libs::relevant_lib; use schema::CrateRoot; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; @@ -230,7 +229,7 @@ impl<'a> CrateLoader<'a> { .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls)) .collect(); - let mut cmeta = cstore::CrateMetadata { + let cmeta = cstore::CrateMetadata { name, extern_crate: Lock::new(None), def_path_table: Lrc::new(def_path_table), @@ -250,25 +249,8 @@ impl<'a> CrateLoader<'a> { rlib, rmeta, }, - // Initialize this with an empty set. The field is populated below - // after we were able to deserialize its contents. - dllimport_foreign_items: FxHashSet(), }; - let dllimports: FxHashSet<_> = cmeta - .root - .native_libraries - .decode((&cmeta, self.sess)) - .filter(|lib| relevant_lib(self.sess, lib) && - lib.kind == cstore::NativeLibraryKind::NativeUnknown) - .flat_map(|lib| { - assert!(lib.foreign_items.iter().all(|def_id| def_id.krate == cnum)); - lib.foreign_items.into_iter().map(|def_id| def_id.index) - }) - .collect(); - - cmeta.dllimport_foreign_items = dllimports; - let cmeta = Lrc::new(cmeta); self.cstore.set_crate_data(cnum, cmeta.clone()); (cnum, cmeta) diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index bd5ad93946e3..53986f074100 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -20,7 +20,7 @@ use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; use rustc::session::{Session, CrateDisambiguator}; use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; -use rustc::util::nodemap::{FxHashMap, FxHashSet, NodeMap}; +use rustc::util::nodemap::{FxHashMap, NodeMap}; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; use syntax::{ast, attr}; @@ -30,7 +30,7 @@ use syntax_pos; pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference}; pub use rustc::middle::cstore::NativeLibraryKind::*; -pub use rustc::middle::cstore::{CrateSource, LibSource}; +pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule}; pub use cstore_impl::{provide, provide_extern}; @@ -84,8 +84,6 @@ pub struct CrateMetadata { pub source: CrateSource, pub proc_macros: Option)>>, - // Foreign items imported from a dylib (Windows only) - pub dllimport_foreign_items: FxHashSet, } pub struct CStore { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 3c2f984ef8b3..e911a03bbe2b 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -12,6 +12,7 @@ use cstore; use encoder; use link_args; use native_libs; +use foreign_modules; use schema; use rustc::ty::maps::QueryConfig; @@ -197,6 +198,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, Lrc::new(reachable_non_generics) } native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) } + foreign_modules => { Lrc::new(cdata.get_foreign_modules(tcx.sess)) } plugin_registrar_fn => { cdata.root.plugin_registrar_fn.map(|index| { DefId { krate: def_id.krate, index } @@ -224,9 +226,6 @@ provide! { <'tcx> tcx, def_id, other, cdata, Lrc::new(result) } - is_dllimport_foreign_item => { - cdata.is_dllimport_foreign_item(def_id.index) - } visibility => { cdata.get_visibility(def_id.index) } dep_kind => { let r = *cdata.dep_kind.lock(); @@ -306,13 +305,28 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { tcx.native_libraries(id.krate) .iter() .filter(|lib| native_libs::relevant_lib(&tcx.sess, lib)) - .find(|l| l.foreign_items.contains(&id)) + .find(|lib| { + let fm_id = match lib.foreign_module { + Some(id) => id, + None => return false, + }; + tcx.foreign_modules(id.krate) + .iter() + .find(|m| m.def_id == fm_id) + .expect("failed to find foreign module") + .foreign_items + .contains(&id) + }) .map(|l| l.kind) }, native_libraries: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); Lrc::new(native_libs::collect(tcx)) }, + foreign_modules: |tcx, cnum| { + assert_eq!(cnum, LOCAL_CRATE); + Lrc::new(foreign_modules::collect(tcx)) + }, link_args: |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); Lrc::new(link_args::collect(tcx)) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0e5df3142af6..e72f9ddd82ab 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -10,7 +10,7 @@ // Decoding metadata from a single crate's metadata -use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary}; +use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; use schema::*; use rustc_data_structures::sync::{Lrc, ReadGuard}; @@ -1031,6 +1031,10 @@ impl<'a, 'tcx> CrateMetadata { self.root.native_libraries.decode((self, sess)).collect() } + pub fn get_foreign_modules(&self, sess: &Session) -> Vec { + self.root.foreign_modules.decode((self, sess)).collect() + } + pub fn get_dylib_dependency_formats(&self) -> Vec<(CrateNum, LinkagePreference)> { self.root .dylib_dependency_formats @@ -1103,10 +1107,6 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn is_dllimport_foreign_item(&self, id: DefIndex) -> bool { - self.dllimport_foreign_items.contains(&id) - } - pub fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 56981b8f4a1e..39de1ec852ec 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -14,7 +14,7 @@ use isolated_encoder::IsolatedEncoder; use schema::*; use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary, - EncodedMetadata}; + EncodedMetadata, ForeignModule}; use rustc::hir::def::CtorKind; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE}; use rustc::hir::map::definitions::DefPathTable; @@ -412,6 +412,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { ()); let native_lib_bytes = self.position() - i; + let foreign_modules = self.tracked( + IsolatedEncoder::encode_foreign_modules, + ()); + // Encode codemap i = self.position(); let codemap = self.encode_codemap(); @@ -480,6 +484,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { lang_items, lang_items_missing, native_libraries, + foreign_modules, codemap, def_path_table, impls, @@ -1337,6 +1342,11 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { self.lazy_seq(used_libraries.iter().cloned()) } + fn encode_foreign_modules(&mut self, _: ()) -> LazySeq { + let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE); + self.lazy_seq(foreign_modules.iter().cloned()) + } + fn encode_crate_deps(&mut self, _: ()) -> LazySeq { let crates = self.tcx.crates(); diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs new file mode 100644 index 000000000000..c44d891b7f39 --- /dev/null +++ b/src/librustc_metadata/foreign_modules.rs @@ -0,0 +1,48 @@ +// 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::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir; +use rustc::middle::cstore::ForeignModule; +use rustc::ty::TyCtxt; + +pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Vec { + let mut collector = Collector { + tcx, + modules: Vec::new(), + }; + tcx.hir.krate().visit_all_item_likes(&mut collector); + return collector.modules +} + +struct Collector<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + modules: Vec, +} + +impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { + fn visit_item(&mut self, it: &'tcx hir::Item) { + let fm = match it.node { + hir::ItemForeignMod(ref fm) => fm, + _ => return, + }; + + let foreign_items = fm.items.iter() + .map(|it| self.tcx.hir.local_def_id(it.id)) + .collect(); + self.modules.push(ForeignModule { + foreign_items, + def_id: self.tcx.hir.local_def_id(it.id), + }); + } + + fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem) {} + fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem) {} +} diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index f77c22bd8954..850996674494 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -56,6 +56,7 @@ mod isolated_encoder; mod schema; mod native_libs; mod link_args; +mod foreign_modules; pub mod creader; pub mod cstore; diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 2504f8dc251f..4bb6d8fb87cf 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -105,14 +105,11 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { } else { None }; - let foreign_items = fm.items.iter() - .map(|it| self.tcx.hir.local_def_id(it.id)) - .collect(); let lib = NativeLibrary { name: n, kind, cfg, - foreign_items, + foreign_module: Some(self.tcx.hir.local_def_id(it.id)), }; self.register_native_lib(Some(m.span), lib); } @@ -218,7 +215,7 @@ impl<'a, 'tcx> Collector<'a, 'tcx> { name: Symbol::intern(new_name.unwrap_or(name)), kind: if let Some(k) = kind { k } else { cstore::NativeUnknown }, cfg: None, - foreign_items: Vec::new(), + foreign_module: None, }; self.register_native_lib(None, lib); } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 001772623e75..983279452970 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -15,8 +15,8 @@ use rustc::hir; use rustc::hir::def::{self, CtorKind}; use rustc::hir::def_id::{DefIndex, DefId, CrateNum}; use rustc::ich::StableHashingContext; -use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; +use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule}; use rustc::middle::lang_items; use rustc::mir; use rustc::session::CrateDisambiguator; @@ -200,6 +200,7 @@ pub struct CrateRoot { pub lang_items: LazySeq<(DefIndex, usize)>, pub lang_items_missing: LazySeq, pub native_libraries: LazySeq, + pub foreign_modules: LazySeq, pub codemap: LazySeq, pub def_path_table: Lazy, pub impls: LazySeq, diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index 16253aa92acc..df78ccdd2298 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -18,6 +18,7 @@ use rustc::session::config::Sanitizer; use rustc::ty::TyCtxt; use rustc::ty::maps::Providers; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::fx::FxHashMap; use llvm::{self, Attribute, ValueRef}; use llvm::AttributePlace::Function; @@ -141,6 +142,20 @@ pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) { llfn, llvm::AttributePlace::Function, cstr("target-features\0"), &val); } + + // Note that currently the `wasm-import-module` doesn't do anything, but + // eventually LLVM 7 should read this and ferry the appropriate import + // module to the output file. + if cx.tcx.sess.target.target.arch == "wasm32" { + if let Some(module) = wasm_import_module(cx.tcx, id) { + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + cstr("wasm-import-module\0"), + &module, + ); + } + } } fn cstr(s: &'static str) -> &CStr { @@ -170,6 +185,8 @@ pub fn provide(providers: &mut Providers) { tcx.hir.krate().visit_all_item_likes(&mut finder); Lrc::new(finder.list) }; + + provide_extern(providers); } struct WasmSectionFinder<'a, 'tcx: 'a> { @@ -192,3 +209,32 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for WasmSectionFinder<'a, 'tcx> { fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {} } + +pub fn provide_extern(providers: &mut Providers) { + providers.wasm_import_module_map = |tcx, cnum| { + let mut ret = FxHashMap(); + for lib in tcx.foreign_modules(cnum).iter() { + let attrs = tcx.get_attrs(lib.def_id); + let mut module = None; + for attr in attrs.iter().filter(|a| a.check_name("wasm_import_module")) { + module = attr.value_str(); + } + let module = match module { + Some(s) => s, + None => continue, + }; + for id in lib.foreign_items.iter() { + assert_eq!(id.krate, cnum); + ret.insert(*id, module.to_string()); + } + } + + Lrc::new(ret) + } +} + +fn wasm_import_module(tcx: TyCtxt, id: DefId) -> Option { + tcx.wasm_import_module_map(id.krate) + .get(&id) + .map(|s| CString::new(&s[..]).unwrap()) +} diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 8e8ba823b6f8..542cdc5baad3 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -813,6 +813,7 @@ fn link_natively(sess: &Session, } if sess.opts.target_triple == "wasm32-unknown-unknown" { + wasm::rewrite_imports(&out_filename, &trans.crate_info.wasm_imports); wasm::add_custom_sections(&out_filename, &trans.crate_info.wasm_custom_sections); } diff --git a/src/librustc_trans/back/wasm.rs b/src/librustc_trans/back/wasm.rs index 99f1e4b7e78f..d6d386c9fbe7 100644 --- a/src/librustc_trans/back/wasm.rs +++ b/src/librustc_trans/back/wasm.rs @@ -8,37 +8,254 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::collections::BTreeMap; use std::fs; use std::path::Path; -use std::collections::BTreeMap; +use std::str; +use rustc_data_structures::fx::FxHashMap; use serialize::leb128; +// https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec +const WASM_IMPORT_SECTION_ID: u8 = 2; + +const WASM_EXTERNAL_KIND_FUNCTION: u8 = 0; +const WASM_EXTERNAL_KIND_TABLE: u8 = 1; +const WASM_EXTERNAL_KIND_MEMORY: u8 = 2; +const WASM_EXTERNAL_KIND_GLOBAL: u8 = 3; + +/// Append all the custom sections listed in `sections` to the wasm binary +/// specified at `path`. +/// +/// LLVM 6 which we're using right now doesn't have the ability to create custom +/// sections in wasm files nor does LLD have the ability to merge these sections +/// into one larger section when linking. It's expected that this will +/// eventually get implemented, however! +/// +/// Until that time though this is a custom implementation in rustc to append +/// all sections to a wasm file to the finished product that LLD produces. +/// +/// Support for this is landing in LLVM in https://reviews.llvm.org/D43097, +/// although after that support will need to be in LLD as well. pub fn add_custom_sections(path: &Path, sections: &BTreeMap>) { - let mut wasm = fs::read(path).expect("failed to read wasm output"); - - // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section - for (section, bytes) in sections { - // write the `id` identifier, 0 for a custom section - let len = wasm.len(); - leb128::write_u32_leb128(&mut wasm, len, 0); - - // figure out how long our name descriptor will be - let mut name = Vec::new(); - leb128::write_u32_leb128(&mut name, 0, section.len() as u32); - name.extend_from_slice(section.as_bytes()); - - // write the length of the payload - let len = wasm.len(); - let total_len = bytes.len() + name.len(); - leb128::write_u32_leb128(&mut wasm, len, total_len as u32); - - // write out the name section - wasm.extend(name); - - // and now the payload itself - wasm.extend_from_slice(bytes); + if sections.len() == 0 { + return } - fs::write(path, &wasm).expect("failed to write wasm output"); + let wasm = fs::read(path).expect("failed to read wasm output"); + + // see https://webassembly.github.io/spec/core/binary/modules.html#custom-section + let mut wasm = WasmEncoder { data: wasm }; + for (section, bytes) in sections { + // write the `id` identifier, 0 for a custom section + wasm.byte(0); + + // figure out how long our name descriptor will be + let mut name = WasmEncoder::new(); + name.str(section); + + // write the length of the payload followed by all its contents + wasm.u32((bytes.len() + name.data.len()) as u32); + wasm.data.extend_from_slice(&name.data); + wasm.data.extend_from_slice(bytes); + } + + fs::write(path, &wasm.data).expect("failed to write wasm output"); +} + +/// Rewrite the module imports are listed from in a wasm module given the field +/// name to module name mapping in `import_map`. +/// +/// LLVM 6 which we're using right now doesn't have the ability to configure the +/// module a wasm symbol is import from. Rather all imported symbols come from +/// the bland `"env"` module unconditionally. Furthermore we'd *also* need +/// support in LLD for preserving these import modules, which it unfortunately +/// currently does not. +/// +/// This function is intended as a hack for now where we manually rewrite the +/// wasm output by LLVM to have the correct import modules listed. The +/// `#[wasm_import_module]` attribute in Rust translates to the module that each +/// symbol is imported from, so here we manually go through the wasm file, +/// decode it, rewrite imports, and then rewrite the wasm module. +/// +/// Support for this was added to LLVM in +/// https://github.com/llvm-mirror/llvm/commit/0f32e1365, although support still +/// needs to be added (AFAIK at the time of this writing) to LLD +pub fn rewrite_imports(path: &Path, import_map: &FxHashMap) { + if import_map.len() == 0 { + return + } + + let wasm = fs::read(path).expect("failed to read wasm output"); + let mut ret = WasmEncoder::new(); + ret.data.extend(&wasm[..8]); + + // skip the 8 byte wasm/version header + for (id, raw) in WasmSections(WasmDecoder::new(&wasm[8..])) { + ret.byte(id); + if id == WASM_IMPORT_SECTION_ID { + info!("rewriting import section"); + let data = rewrite_import_section( + &mut WasmDecoder::new(raw), + import_map, + ); + ret.bytes(&data); + } else { + info!("carry forward section {}, {} bytes long", id, raw.len()); + ret.bytes(raw); + } + } + + fs::write(path, &ret.data).expect("failed to write wasm output"); + + fn rewrite_import_section( + wasm: &mut WasmDecoder, + import_map: &FxHashMap, + ) + -> Vec + { + let mut dst = WasmEncoder::new(); + let n = wasm.u32(); + dst.u32(n); + info!("rewriting {} imports", n); + for _ in 0..n { + rewrite_import_entry(wasm, &mut dst, import_map); + } + return dst.data + } + + fn rewrite_import_entry(wasm: &mut WasmDecoder, + dst: &mut WasmEncoder, + import_map: &FxHashMap) { + // More info about the binary format here is available at: + // https://webassembly.github.io/spec/core/binary/modules.html#import-section + // + // Note that you can also find the whole point of existence of this + // function here, where we map the `module` name to a different one if + // we've got one listed. + let module = wasm.str(); + let field = wasm.str(); + let new_module = if module == "env" { + import_map.get(field).map(|s| &**s).unwrap_or(module) + } else { + module + }; + info!("import rewrite ({} => {}) / {}", module, new_module, field); + dst.str(new_module); + dst.str(field); + let kind = wasm.byte(); + dst.byte(kind); + match kind { + WASM_EXTERNAL_KIND_FUNCTION => dst.u32(wasm.u32()), + WASM_EXTERNAL_KIND_TABLE => { + dst.byte(wasm.byte()); // element_type + dst.limits(wasm.limits()); + } + WASM_EXTERNAL_KIND_MEMORY => dst.limits(wasm.limits()), + WASM_EXTERNAL_KIND_GLOBAL => { + dst.byte(wasm.byte()); // content_type + dst.bool(wasm.bool()); // mutable + } + b => panic!("unknown kind: {}", b), + } + } +} + +struct WasmSections<'a>(WasmDecoder<'a>); + +impl<'a> Iterator for WasmSections<'a> { + type Item = (u8, &'a [u8]); + + fn next(&mut self) -> Option<(u8, &'a [u8])> { + if self.0.data.len() == 0 { + return None + } + + // see https://webassembly.github.io/spec/core/binary/modules.html#sections + let id = self.0.byte(); + let section_len = self.0.u32(); + info!("new section {} / {} bytes", id, section_len); + let section = self.0.skip(section_len as usize); + Some((id, section)) + } +} + +struct WasmDecoder<'a> { + data: &'a [u8], +} + +impl<'a> WasmDecoder<'a> { + fn new(data: &'a [u8]) -> WasmDecoder<'a> { + WasmDecoder { data } + } + + fn byte(&mut self) -> u8 { + self.skip(1)[0] + } + + fn u32(&mut self) -> u32 { + let (n, l1) = leb128::read_u32_leb128(self.data); + self.data = &self.data[l1..]; + return n + } + + fn skip(&mut self, amt: usize) -> &'a [u8] { + let (data, rest) = self.data.split_at(amt); + self.data = rest; + data + } + + fn str(&mut self) -> &'a str { + let len = self.u32(); + str::from_utf8(self.skip(len as usize)).unwrap() + } + + fn bool(&mut self) -> bool { + self.byte() == 1 + } + + fn limits(&mut self) -> (u32, Option) { + let has_max = self.bool(); + (self.u32(), if has_max { Some(self.u32()) } else { None }) + } +} + +struct WasmEncoder { + data: Vec, +} + +impl WasmEncoder { + fn new() -> WasmEncoder { + WasmEncoder { data: Vec::new() } + } + + fn u32(&mut self, val: u32) { + let at = self.data.len(); + leb128::write_u32_leb128(&mut self.data, at, val); + } + + fn byte(&mut self, val: u8) { + self.data.push(val); + } + + fn bytes(&mut self, val: &[u8]) { + self.u32(val.len() as u32); + self.data.extend_from_slice(val); + } + + fn str(&mut self, val: &str) { + self.bytes(val.as_bytes()) + } + + fn bool(&mut self, b: bool) { + self.byte(b as u8); + } + + fn limits(&mut self, limits: (u32, Option)) { + self.bool(limits.1.is_some()); + self.u32(limits.0); + if let Some(c) = limits.1 { + self.u32(c); + } + } } diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 11f952bc5bc7..56eece9f31e7 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -72,6 +72,7 @@ use type_::Type; use type_of::LayoutLlvmExt; use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; +use rustc_data_structures::sync::Lrc; use std::any::Any; use std::collections::BTreeMap; @@ -1072,14 +1073,15 @@ impl CrateInfo { used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic), used_crate_source: FxHashMap(), wasm_custom_sections: BTreeMap::new(), + wasm_imports: FxHashMap(), }; - let load_wasm_sections = tcx.sess.crate_types.borrow() + let load_wasm_items = tcx.sess.crate_types.borrow() .iter() .any(|c| *c != config::CrateTypeRlib) && tcx.sess.opts.target_triple == "wasm32-unknown-unknown"; - if load_wasm_sections { + if load_wasm_items { info!("attempting to load all wasm sections"); for &id in tcx.wasm_custom_sections(LOCAL_CRATE).iter() { let (name, contents) = fetch_wasm_section(tcx, id); @@ -1087,6 +1089,7 @@ impl CrateInfo { .or_insert(Vec::new()) .extend(contents); } + info.load_wasm_imports(tcx, LOCAL_CRATE); } for &cnum in tcx.crates().iter() { @@ -1108,19 +1111,27 @@ impl CrateInfo { if tcx.is_no_builtins(cnum) { info.is_no_builtins.insert(cnum); } - if load_wasm_sections { + if load_wasm_items { for &id in tcx.wasm_custom_sections(cnum).iter() { let (name, contents) = fetch_wasm_section(tcx, id); info.wasm_custom_sections.entry(name) .or_insert(Vec::new()) .extend(contents); } + info.load_wasm_imports(tcx, cnum); } } - return info } + + fn load_wasm_imports(&mut self, tcx: TyCtxt, cnum: CrateNum) { + for (&id, module) in tcx.wasm_import_module_map(cnum).iter() { + let instance = Instance::mono(tcx, id); + let import_name = tcx.symbol_name(instance); + self.wasm_imports.insert(import_name.to_string(), module.clone()); + } + } } fn is_translated_item(tcx: TyCtxt, id: DefId) -> bool { @@ -1248,6 +1259,39 @@ pub fn provide(providers: &mut Providers) { .expect(&format!("failed to find cgu with name {:?}", name)) }; providers.compile_codegen_unit = compile_codegen_unit; + + provide_extern(providers); +} + +pub fn provide_extern(providers: &mut Providers) { + providers.dllimport_foreign_items = |tcx, krate| { + let module_map = tcx.foreign_modules(krate); + let module_map = module_map.iter() + .map(|lib| (lib.def_id, lib)) + .collect::>(); + + let dllimports = tcx.native_libraries(krate) + .iter() + .filter(|lib| { + if lib.kind != cstore::NativeLibraryKind::NativeUnknown { + return false + } + let cfg = match lib.cfg { + Some(ref cfg) => cfg, + None => return true, + }; + attr::cfg_matches(cfg, &tcx.sess.parse_sess, None) + }) + .filter_map(|lib| lib.foreign_module) + .map(|id| &module_map[&id]) + .flat_map(|module| module.foreign_items.iter().cloned()) + .collect(); + Lrc::new(dllimports) + }; + + providers.is_dllimport_foreign_item = |tcx, def_id| { + tcx.dllimport_foreign_items(def_id.krate).contains(&def_id) + }; } pub fn linkage_to_llvm(linkage: Linkage) -> llvm::Linkage { diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index bb2aeca37488..9f654c8ab29c 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -216,6 +216,8 @@ impl TransCrate for LlvmTransCrate { fn provide_extern(&self, providers: &mut ty::maps::Providers) { back::symbol_export::provide_extern(providers); + base::provide_extern(providers); + attributes::provide_extern(providers); } fn trans_crate<'a, 'tcx>( @@ -403,6 +405,7 @@ struct CrateInfo { used_crates_static: Vec<(CrateNum, LibSource)>, used_crates_dynamic: Vec<(CrateNum, LibSource)>, wasm_custom_sections: BTreeMap>, + wasm_imports: FxHashMap, } __build_diagnostic_array! { librustc_trans, DIAGNOSTICS } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index dbcfee208ca2..270cee26948e 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -454,6 +454,9 @@ declare_features! ( // The #[wasm_custom_section] attribute (active, wasm_custom_section, "1.26.0", None, None), + + // The #![wasm_import_module] attribute + (active, wasm_import_module, "1.26.0", None, None), ); declare_features! ( @@ -920,6 +923,10 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "the `#[no_debug]` attribute was an experimental feature that has been \ deprecated due to lack of demand", cfg_fn!(no_debug))), + ("wasm_import_module", Normal, Gated(Stability::Unstable, + "wasm_import_module", + "experimental attribute", + cfg_fn!(wasm_import_module))), ("omit_gdb_pretty_printer_section", Whitelisted, Gated(Stability::Unstable, "omit_gdb_pretty_printer_section", "the `#[omit_gdb_pretty_printer_section]` \ diff --git a/src/test/run-make/wasm-custom-section/foo.js b/src/test/run-make/wasm-custom-section/foo.js index df69354f3a40..e7a4cfc344ef 100644 --- a/src/test/run-make/wasm-custom-section/foo.js +++ b/src/test/run-make/wasm-custom-section/foo.js @@ -43,4 +43,4 @@ assert.strictEqual(section[1], 6); assert.strictEqual(section[2], 1); assert.strictEqual(section[3], 2); -process.exit(1); +process.exit(0); diff --git a/src/test/run-make/wasm-import-module/Makefile b/src/test/run-make/wasm-import-module/Makefile new file mode 100644 index 000000000000..399951e51631 --- /dev/null +++ b/src/test/run-make/wasm-import-module/Makefile @@ -0,0 +1,10 @@ +-include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) foo.rs --target wasm32-unknown-unknown + $(RUSTC) bar.rs -C lto -O --target wasm32-unknown-unknown + $(NODE) foo.js $(TMPDIR)/bar.wasm +else +all: +endif diff --git a/src/test/run-make/wasm-import-module/bar.rs b/src/test/run-make/wasm-import-module/bar.rs new file mode 100644 index 000000000000..9e659223c651 --- /dev/null +++ b/src/test/run-make/wasm-import-module/bar.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "cdylib"] +#![feature(wasm_import_module)] +#![deny(warnings)] + +extern crate foo; + +#[wasm_import_module = "./me"] +extern { + #[link_name = "me_in_dep"] + fn dep(); +} + +#[no_mangle] +pub extern fn foo() { + unsafe { + foo::dep(); + dep(); + } +} diff --git a/src/test/run-make/wasm-import-module/foo.js b/src/test/run-make/wasm-import-module/foo.js new file mode 100644 index 000000000000..369962e55b1e --- /dev/null +++ b/src/test/run-make/wasm-import-module/foo.js @@ -0,0 +1,28 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const fs = require('fs'); +const process = require('process'); +const assert = require('assert'); +const buffer = fs.readFileSync(process.argv[2]); + +let m = new WebAssembly.Module(buffer); +let imports = WebAssembly.Module.imports(m); +console.log('imports', imports); +assert.strictEqual(imports.length, 2); + +assert.strictEqual(imports[0].kind, 'function'); +assert.strictEqual(imports[1].kind, 'function'); + +let modules = [imports[0].module, imports[1].module]; +modules.sort(); + +assert.strictEqual(modules[0], './dep'); +assert.strictEqual(modules[1], './me'); diff --git a/src/test/run-make/wasm-import-module/foo.rs b/src/test/run-make/wasm-import-module/foo.rs new file mode 100644 index 000000000000..bcd2ca70befa --- /dev/null +++ b/src/test/run-make/wasm-import-module/foo.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] +#![feature(wasm_import_module)] +#![deny(warnings)] + +#[wasm_import_module = "./dep"] +extern { + pub fn dep(); +} diff --git a/src/test/ui/feature-gate-wasm_custom_section.stderr b/src/test/ui/feature-gate-wasm_custom_section.stderr index 5977ec9edad5..1b4415539f44 100644 --- a/src/test/ui/feature-gate-wasm_custom_section.stderr +++ b/src/test/ui/feature-gate-wasm_custom_section.stderr @@ -8,4 +8,4 @@ LL | #[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable error: aborting due to previous error -If you want more information on this error, try using "rustc --explain E0658" +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-wasm_import_module.rs b/src/test/ui/feature-gate-wasm_import_module.rs new file mode 100644 index 000000000000..c5898a9c1269 --- /dev/null +++ b/src/test/ui/feature-gate-wasm_import_module.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[wasm_import_module = "test"] //~ ERROR: experimental +extern { +} + +fn main() {} diff --git a/src/test/ui/feature-gate-wasm_import_module.stderr b/src/test/ui/feature-gate-wasm_import_module.stderr new file mode 100644 index 000000000000..bae5fa9d5956 --- /dev/null +++ b/src/test/ui/feature-gate-wasm_import_module.stderr @@ -0,0 +1,11 @@ +error[E0658]: experimental attribute + --> $DIR/feature-gate-wasm_import_module.rs:11:1 + | +LL | #[wasm_import_module = "test"] //~ ERROR: experimental + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(wasm_import_module)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/wasm-import-module.rs b/src/test/ui/wasm-import-module.rs new file mode 100644 index 000000000000..0b743d9e486b --- /dev/null +++ b/src/test/ui/wasm-import-module.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(wasm_import_module)] + +#[wasm_import_module] //~ ERROR: must be of the form +extern {} + +#[wasm_import_module = "foo"] //~ ERROR: must only be attached to +fn foo() {} + +fn main() {} + diff --git a/src/test/ui/wasm-import-module.stderr b/src/test/ui/wasm-import-module.stderr new file mode 100644 index 000000000000..bf301ce5269a --- /dev/null +++ b/src/test/ui/wasm-import-module.stderr @@ -0,0 +1,14 @@ +error: must be of the form #[wasm_import_module = "..."] + --> $DIR/wasm-import-module.rs:13:1 + | +LL | #[wasm_import_module] //~ ERROR: must be of the form + | ^^^^^^^^^^^^^^^^^^^^^ + +error: must only be attached to foreign modules + --> $DIR/wasm-import-module.rs:16:1 + | +LL | #[wasm_import_module = "foo"] //~ ERROR: must only be attached to + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 73fa6d52ed99651940267affa941a1069cc20f35 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 22 Mar 2018 20:49:05 +0000 Subject: [PATCH 505/830] Remove std/test documentation from compiler docs. --- src/bootstrap/dist.rs | 4 ++-- src/bootstrap/doc.rs | 16 ++++------------ 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e25a7e185258..5563b153f5af 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -163,7 +163,7 @@ impl Step for RustcDocs { let image = tmpdir(build).join(format!("{}-{}-image", name, host)); let _ = fs::remove_dir_all(&image); - let dst = image.join("share/doc/rustc/html"); + let dst = image.join("share/doc/rust/html"); t!(fs::create_dir_all(&dst)); let src = build.compiler_doc_out(host); cp_r(&src, &dst); @@ -179,7 +179,7 @@ impl Step for RustcDocs { .arg(format!("--package-name={}-{}", name, host)) .arg("--component-name=rustc-docs") .arg("--legacy-manifest-dirs=rustlib,cargo") - .arg("--bulk-dirs=share/doc/rustc/html"); + .arg("--bulk-dirs=share/doc/rust/html"); build.run(&mut cmd); t!(fs::remove_dir_all(&image)); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index e525bdb98fc0..44073a5b0757 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -690,17 +690,10 @@ impl Step for Rustc { builder.ensure(compile::Rustc { compiler, target }); let out_dir = build.stage_out(compiler, Mode::Librustc) .join(target).join("doc"); - - // See docs in std above for why we symlink - // - // This step must happen after other documentation steps. This - // invariant ensures that compiler documentation is not included - // in the standard documentation tarballs but that all the - // documentation from the standard documentation tarballs is included - // in the compiler documentation tarball. - let my_out = build.crate_doc_out(target); - build.clear_if_dirty(&my_out, &rustdoc); - t!(symlink_dir_force(&my_out, &out_dir)); + // We do not symlink to the same shared folder that already contains std library + // documentation from previous steps as we do not want to include that. + build.clear_if_dirty(&out, &rustdoc); + t!(symlink_dir_force(&out, &out_dir)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); compile::rustc_cargo(build, &mut cargo); @@ -720,7 +713,6 @@ impl Step for Rustc { } build.run(&mut cargo); - cp_r(&my_out, &out); } } From 1b26be575020c26b400b918342ac5c0c9ec76c58 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Mar 2018 04:24:27 -0400 Subject: [PATCH 506/830] rustfmt lowering.rs --- src/librustc/hir/lowering.rs | 2201 +++++++++++++++++++--------------- 1 file changed, 1246 insertions(+), 955 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index f6bdfde15fc5..f86e003f3630 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -43,8 +43,8 @@ use dep_graph::DepGraph; use hir; use hir::HirVec; -use hir::map::{Definitions, DefKey, DefPathData}; -use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX, DefIndexAddressSpace}; +use hir::map::{DefKey, DefPathData, Definitions}; +use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX}; use hir::def::{Def, PathResolution}; use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES}; use middle::cstore::CrateStore; @@ -63,10 +63,10 @@ use syntax::errors; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::print::pprust; use syntax::ptr::P; -use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind}; +use syntax::codemap::{self, respan, CompilerDesugaringKind, Spanned}; use syntax::std_inject; -use syntax::symbol::{Symbol, keywords}; -use syntax::tokenstream::{TokenStream, TokenTree, Delimited}; +use syntax::symbol::{keywords, Symbol}; +use syntax::tokenstream::{Delimited, TokenStream, TokenTree}; use syntax::parse::token::Token; use syntax::util::small_vector::SmallVector; use syntax::visit::{self, Visitor}; @@ -80,13 +80,13 @@ pub struct LoweringContext<'a> { // Use to assign ids to hir nodes that do not directly correspond to an ast node sess: &'a Session, - cstore: &'a dyn CrateStore, + cstore: &'a CrateStore, // As we walk the AST we must keep track of the current 'parent' def id (in // the form of a DefIndex) so that if we create a new node which introduces // a definition, then we can properly create the def id. parent_def: Option, - resolver: &'a mut dyn Resolver, + resolver: &'a mut Resolver, name_map: FxHashMap, /// The items being lowered are collected here. @@ -154,8 +154,13 @@ pub trait Resolver { /// Given suffix ["b","c","d"], creates a HIR path for `[::crate_root]::b::c::d` and resolves /// it based on `is_value`. - fn resolve_str_path(&mut self, span: Span, crate_root: Option<&str>, - components: &[&str], is_value: bool) -> hir::Path; + fn resolve_str_path( + &mut self, + span: Span, + crate_root: Option<&str>, + components: &[&str], + is_value: bool, + ) -> hir::Path; } #[derive(Clone, Copy, Debug)] @@ -176,12 +181,13 @@ enum ImplTraitContext { Disallowed, } -pub fn lower_crate(sess: &Session, - cstore: &dyn CrateStore, - dep_graph: &DepGraph, - krate: &Crate, - resolver: &mut dyn Resolver) - -> hir::Crate { +pub fn lower_crate( + sess: &Session, + cstore: &CrateStore, + dep_graph: &DepGraph, + krate: &Crate, + resolver: &mut Resolver, +) -> hir::Crate { // We're constructing the HIR here; we don't care what we will // read, since we haven't even constructed the *input* to // incr. comp. yet. @@ -222,7 +228,7 @@ enum ParamMode { /// Any path in a type context. Explicit, /// The `module::Type` in `module::Type::method` in an expression. - Optional + Optional, } struct LoweredNodeId { @@ -252,13 +258,15 @@ impl<'a> LoweringContext<'a> { self.lctx.allocate_hir_id_counter(item.id, item); match item.node { - ItemKind::Struct(_, ref generics) | - ItemKind::Union(_, ref generics) | - ItemKind::Enum(_, ref generics) | - ItemKind::Ty(_, ref generics) | - ItemKind::Trait(_, _, ref generics, ..) => { + ItemKind::Struct(_, ref generics) + | ItemKind::Union(_, ref generics) + | ItemKind::Enum(_, ref generics) + | ItemKind::Ty(_, ref generics) + | ItemKind::Trait(_, _, ref generics, ..) => { let def_id = self.lctx.resolver.definitions().local_def_id(item.id); - let count = generics.params.iter() + let count = generics + .params + .iter() .filter(|param| param.is_lifetime_param()) .count(); self.lctx.type_def_lifetime_params.insert(def_id, count); @@ -285,7 +293,8 @@ impl<'a> LoweringContext<'a> { impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> { fn with_trait_impl_ref(&mut self, trait_impl_ref: &Option, f: F) - where F: FnOnce(&mut Self) + where + F: FnOnce(&mut Self), { let old = self.lctx.is_in_trait_impl; self.lctx.is_in_trait_impl = if let &None = trait_impl_ref { @@ -311,22 +320,24 @@ impl<'a> LoweringContext<'a> { if item_lowered { let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node { - hir::Item_::ItemImpl(_,_,_,ref generics,..) | - hir::Item_::ItemTrait(_,_,ref generics,..) => - generics.lifetimes().cloned().collect::>(), + hir::Item_::ItemImpl(_, _, _, ref generics, ..) + | hir::Item_::ItemTrait(_, _, ref generics, ..) => { + generics.lifetimes().cloned().collect::>() + } _ => Vec::new(), }; - self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| { - let this = &mut ItemLowerer { lctx: this }; - if let ItemKind::Impl(_,_,_,_,ref opt_trait_ref,_,_) = item.node { - this.with_trait_impl_ref(opt_trait_ref, |this| { - visit::walk_item(this, item) - }); - } else { - visit::walk_item(this, item); - } - }); + self.lctx + .with_parent_impl_lifetime_defs(&item_lifetimes, |this| { + let this = &mut ItemLowerer { lctx: this }; + if let ItemKind::Impl(_, _, _, _, ref opt_trait_ref, _, _) = item.node { + this.with_trait_impl_ref(opt_trait_ref, |this| { + visit::walk_item(this, item) + }); + } else { + visit::walk_item(this, item); + } + }); } } @@ -379,27 +390,26 @@ impl<'a> LoweringContext<'a> { } } - fn allocate_hir_id_counter(&mut self, - owner: NodeId, - debug: &T) { + fn allocate_hir_id_counter(&mut self, owner: NodeId, debug: &T) { if self.item_local_id_counters.insert(owner, 0).is_some() { - bug!("Tried to allocate item_local_id_counter for {:?} twice", debug); + bug!( + "Tried to allocate item_local_id_counter for {:?} twice", + debug + ); } // Always allocate the first HirId for the owner itself self.lower_node_id_with_owner(owner, owner); } - fn lower_node_id_generic(&mut self, - ast_node_id: NodeId, - alloc_hir_id: F) - -> LoweredNodeId - where F: FnOnce(&mut Self) -> hir::HirId + fn lower_node_id_generic(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId + where + F: FnOnce(&mut Self) -> hir::HirId, { if ast_node_id == DUMMY_NODE_ID { return LoweredNodeId { node_id: DUMMY_NODE_ID, hir_id: hir::DUMMY_HIR_ID, - } + }; } let min_size = ast_node_id.as_usize() + 1; @@ -427,11 +437,12 @@ impl<'a> LoweringContext<'a> { } fn with_hir_id_owner(&mut self, owner: NodeId, f: F) - where F: FnOnce(&mut Self) + where + F: FnOnce(&mut Self), { let counter = self.item_local_id_counters - .insert(owner, HIR_ID_COUNTER_LOCKED) - .unwrap(); + .insert(owner, HIR_ID_COUNTER_LOCKED) + .unwrap(); let def_index = self.resolver.definitions().opt_def_index(owner).unwrap(); self.current_hir_id_owner.push((def_index, counter)); f(self); @@ -440,7 +451,9 @@ impl<'a> LoweringContext<'a> { debug_assert!(def_index == new_def_index); debug_assert!(new_counter >= counter); - let prev = self.item_local_id_counters.insert(owner, new_counter).unwrap(); + let prev = self.item_local_id_counters + .insert(owner, new_counter) + .unwrap(); debug_assert!(prev == HIR_ID_COUNTER_LOCKED); } @@ -452,9 +465,8 @@ impl<'a> LoweringContext<'a> { /// properly. Calling the method twice with the same NodeId is fine though. fn lower_node_id(&mut self, ast_node_id: NodeId) -> LoweredNodeId { self.lower_node_id_generic(ast_node_id, |this| { - let &mut (def_index, ref mut local_id_counter) = this.current_hir_id_owner - .last_mut() - .unwrap(); + let &mut (def_index, ref mut local_id_counter) = + this.current_hir_id_owner.last_mut().unwrap(); let local_id = *local_id_counter; *local_id_counter += 1; hir::HirId { @@ -464,14 +476,9 @@ impl<'a> LoweringContext<'a> { }) } - fn lower_node_id_with_owner(&mut self, - ast_node_id: NodeId, - owner: NodeId) - -> LoweredNodeId { + fn lower_node_id_with_owner(&mut self, ast_node_id: NodeId, owner: NodeId) -> LoweredNodeId { self.lower_node_id_generic(ast_node_id, |this| { - let local_id_counter = this.item_local_id_counters - .get_mut(&owner) - .unwrap(); + let local_id_counter = this.item_local_id_counters.get_mut(&owner).unwrap(); let local_id = *local_id_counter; // We want to be sure not to modify the counter in the map while it @@ -489,8 +496,7 @@ impl<'a> LoweringContext<'a> { }) } - fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) - -> hir::BodyId { + fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) -> hir::BodyId { let body = hir::Body { arguments: decl.map_or(hir_vec![], |decl| { decl.inputs.iter().map(|x| self.lower_arg(x)).collect() @@ -524,8 +530,7 @@ impl<'a> LoweringContext<'a> { Symbol::gensym(s) } - fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span - { + fn allow_internal_unstable(&self, reason: CompilerDesugaringKind, span: Span) -> Span { let mark = Mark::fresh(Mark::root()); mark.set_expn_info(codemap::ExpnInfo { call_site: span, @@ -545,8 +550,10 @@ impl<'a> LoweringContext<'a> { fn collect_in_band_defs( &mut self, parent_id: Option, - f: F - ) -> (Vec, T) where F: FnOnce(&mut LoweringContext) -> T + f: F, + ) -> (Vec, T) + where + F: FnOnce(&mut LoweringContext) -> T, { assert!(!self.is_collecting_in_band_lifetimes); assert!(self.lifetimes_to_define.is_empty()); @@ -562,7 +569,9 @@ impl<'a> LoweringContext<'a> { let lifetimes_to_define = self.lifetimes_to_define.split_off(0); let mut params = match parent_id { - Some(parent_id) => lifetimes_to_define.into_iter().map(|(span, name)| { + Some(parent_id) => lifetimes_to_define + .into_iter() + .map(|(span, name)| { let def_node_id = self.next_id().node_id; // Add a definition for the in-band lifetime def @@ -572,7 +581,7 @@ impl<'a> LoweringContext<'a> { DefPathData::LifetimeDef(name.as_str()), DefIndexAddressSpace::High, Mark::root(), - span + span, ); hir::GenericParam::Lifetime(hir::LifetimeDef { @@ -585,11 +594,16 @@ impl<'a> LoweringContext<'a> { pure_wrt_drop: false, in_band: true, }) - }).collect(), + }) + .collect(), None => Vec::new(), }; - params.extend(in_band_ty_params.into_iter().map(|tp| hir::GenericParam::Type(tp))); + params.extend( + in_band_ty_params + .into_iter() + .map(|tp| hir::GenericParam::Type(tp)), + ); (params, res) } @@ -598,11 +612,9 @@ impl<'a> LoweringContext<'a> { // This is used to track which lifetimes have already been defined, and // which are new in-band lifetimes that need to have a definition created // for them. - fn with_in_scope_lifetime_defs( - &mut self, - lt_defs: &[LifetimeDef], - f: F - ) -> T where F: FnOnce(&mut LoweringContext) -> T + fn with_in_scope_lifetime_defs(&mut self, lt_defs: &[LifetimeDef], f: F) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let old_len = self.in_scope_lifetimes.len(); let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.ident.name); @@ -619,11 +631,9 @@ impl<'a> LoweringContext<'a> { // This should only be used with generics that have already had their // in-band lifetimes added. In practice, this means that this function is // only used when lowering a child item of a trait or impl. - fn with_parent_impl_lifetime_defs( - &mut self, - lt_defs: &[hir::LifetimeDef], - f: F - ) -> T where F: FnOnce(&mut LoweringContext) -> T + fn with_parent_impl_lifetime_defs(&mut self, lt_defs: &[hir::LifetimeDef], f: F) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let old_len = self.in_scope_lifetimes.len(); let lt_def_names = lt_defs.iter().map(|lt_def| lt_def.lifetime.name.name()); @@ -641,41 +651,50 @@ impl<'a> LoweringContext<'a> { &mut self, generics: &Generics, parent_id: Option, - f: F + f: F, ) -> (hir::Generics, T) - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { - let (in_band_defs, (mut lowered_generics, res)) = - self.with_in_scope_lifetime_defs( - &generics.params - .iter() - .filter_map(|p| match *p { - GenericParam::Lifetime(ref ld) => Some(ld.clone()), - _ => None, - }) - .collect::>(), - |this| { - this.collect_in_band_defs(parent_id, |this| { - (this.lower_generics(generics), f(this)) - }) - } - ); + let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs( + &generics + .params + .iter() + .filter_map(|p| match *p { + GenericParam::Lifetime(ref ld) => Some(ld.clone()), + _ => None, + }) + .collect::>(), + |this| { + this.collect_in_band_defs(parent_id, |this| { + (this.lower_generics(generics), f(this)) + }) + }, + ); - lowered_generics.params = - lowered_generics.params.iter().cloned().chain(in_band_defs).collect(); + lowered_generics.params = lowered_generics + .params + .iter() + .cloned() + .chain(in_band_defs) + .collect(); (lowered_generics, res) } fn with_catch_scope(&mut self, catch_id: NodeId, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let len = self.catch_scopes.len(); self.catch_scopes.push(catch_id); let result = f(self); - assert_eq!(len + 1, self.catch_scopes.len(), - "catch scopes should be added and removed in stack order"); + assert_eq!( + len + 1, + self.catch_scopes.len(), + "catch scopes should be added and removed in stack order" + ); self.catch_scopes.pop().unwrap(); @@ -683,17 +702,19 @@ impl<'a> LoweringContext<'a> { } fn lower_body(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId - where F: FnOnce(&mut LoweringContext) -> hir::Expr + where + F: FnOnce(&mut LoweringContext) -> hir::Expr, { let prev = mem::replace(&mut self.is_generator, false); let result = f(self); let r = self.record_body(result, decl); self.is_generator = prev; - return r + return r; } fn with_loop_scope(&mut self, loop_id: NodeId, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { // We're no longer in the base loop's condition; we're in another loop. let was_in_loop_condition = self.is_in_loop_condition; @@ -703,8 +724,11 @@ impl<'a> LoweringContext<'a> { self.loop_scopes.push(loop_id); let result = f(self); - assert_eq!(len + 1, self.loop_scopes.len(), - "Loop scopes should be added and removed in stack order"); + assert_eq!( + len + 1, + self.loop_scopes.len(), + "Loop scopes should be added and removed in stack order" + ); self.loop_scopes.pop().unwrap(); @@ -714,7 +738,8 @@ impl<'a> LoweringContext<'a> { } fn with_loop_condition_scope(&mut self, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = true; @@ -727,7 +752,8 @@ impl<'a> LoweringContext<'a> { } fn with_new_scopes(&mut self, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; @@ -744,7 +770,8 @@ impl<'a> LoweringContext<'a> { } fn with_parent_def(&mut self, parent_id: NodeId, f: F) -> T - where F: FnOnce(&mut LoweringContext) -> T + where + F: FnOnce(&mut LoweringContext) -> T, { let old_def = self.parent_def; self.parent_def = { @@ -771,16 +798,19 @@ impl<'a> LoweringContext<'a> { if ident.ctxt == SyntaxContext::empty() { return ident.name; } - *self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident)) + *self.name_map + .entry(ident) + .or_insert_with(|| Symbol::from_ident(ident)) } fn lower_label(&mut self, label: Option(' + // @matches - '_x: impl (T); + +impl S { + // @has foo/struct.S.html + // @has - 'bar(' + // @matches - '_bar: impl (' + // @matches - '_baz:.+struct\.S\.html.+impl .+trait\.Clone\.html' + pub fn baz(_baz: S) { + } +} + +// @has - 'method(' +// @matches - '_x: impl Trait for S {} From 4800afa5f5982b06d9cf27ae6003b058ca8855c8 Mon Sep 17 00:00:00 2001 From: Shotaro Yamada Date: Fri, 23 Mar 2018 22:06:28 +0900 Subject: [PATCH 576/830] Cleanup --- src/librustdoc/clean/mod.rs | 3 ++- src/librustdoc/html/format.rs | 15 ++------------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0154c6a08557..3985229669d5 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1901,7 +1901,8 @@ impl<'a, 'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { vec![].into_iter() } else { cx.tcx.fn_arg_names(did).into_iter() - }.peekable(); + }; + FnDecl { output: Return(sig.skip_binder().output().clean(cx)), attrs: Attributes::default(), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0c4cd3accf61..0a7e19fc643f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -581,7 +581,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: } many => { primitive_link(f, PrimitiveType::Tuple, "(")?; - fmt::Display::fmt(&CommaSep(&many), f)?; + fmt::Display::fmt(&CommaSep(many), f)?; primitive_link(f, PrimitiveType::Tuple, ")") } } @@ -667,18 +667,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt: } } clean::ImplTrait(ref bounds) => { - write!(f, "impl ")?; - for (i, bound) in bounds.iter().enumerate() { - if i != 0 { - write!(f, " + ")?; - } - if f.alternate() { - write!(f, "{:#}", *bound)?; - } else { - write!(f, "{}", *bound)?; - } - } - Ok(()) + write!(f, "impl {}", TyParamBounds(bounds)) } clean::QPath { ref name, ref self_type, ref trait_ } => { let should_show_cast = match *trait_ { From d6926ca12daa51fd786f233019ac539d1a732493 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 23 Mar 2018 23:47:22 -0700 Subject: [PATCH 577/830] Add a codegen test for exact_div intrinsic --- src/test/codegen/exact_div.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/codegen/exact_div.rs diff --git a/src/test/codegen/exact_div.rs b/src/test/codegen/exact_div.rs new file mode 100644 index 000000000000..9ba6c0c00063 --- /dev/null +++ b/src/test/codegen/exact_div.rs @@ -0,0 +1,30 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +use std::intrinsics::exact_div; + +// CHECK-LABEL: @exact_sdiv +#[no_mangle] +pub unsafe fn exact_sdiv(x: i32, y: i32) -> i32 { +// CHECK: sdiv exact + exact_div(x, y) +} + +// CHECK-LABEL: @exact_udiv +#[no_mangle] +pub unsafe fn exact_udiv(x: u32, y: u32) -> u32 { +// CHECK: udiv exact + exact_div(x, y) +} From 7cae6fef710c4668d650219319a055e8f2157ab5 Mon Sep 17 00:00:00 2001 From: Jimmy Brush Date: Sat, 24 Mar 2018 10:01:46 -0400 Subject: [PATCH 578/830] don't pass -no-pie to gnu ld fixes #48884 --- src/librustc_trans/back/link.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 542cdc5baad3..b2bcbb295ced 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -712,6 +712,7 @@ fn link_natively(sess: &Session, // linking executables as pie. Different versions of gcc seem to use // different quotes in the error message so don't check for them. if sess.target.target.options.linker_is_gnu && + sess.linker_flavor() != LinkerFlavor::Ld && (out.contains("unrecognized command line option") || out.contains("unknown argument")) && out.contains("-no-pie") && @@ -1007,8 +1008,9 @@ fn link_args(cmd: &mut Linker, } else { // recent versions of gcc can be configured to generate position // independent executables by default. We have to pass -no-pie to - // explicitly turn that off. - if sess.target.target.options.linker_is_gnu { + // explicitly turn that off. Not applicable to ld. + if sess.target.target.options.linker_is_gnu + && sess.linker_flavor() != LinkerFlavor::Ld { cmd.no_position_independent_executable(); } } From 36322d00dfc11cb67814b3992d4432adc396edea Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Fri, 23 Mar 2018 23:29:52 +0100 Subject: [PATCH 579/830] update books for next release --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/book b/src/doc/book index 98921e9de849..b889e1e30c5e 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 98921e9de849acdaeaed08cfad6758bb89769b7d +Subproject commit b889e1e30c5e9953834aa9fa6c982bb28df46ac9 diff --git a/src/doc/nomicon b/src/doc/nomicon index ad5ddd62c098..6a8f0a27e9a5 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit ad5ddd62c098d5b424151beda574ae7df2154df1 +Subproject commit 6a8f0a27e9a58c55c89d07bc43a176fdae5e051c diff --git a/src/doc/reference b/src/doc/reference index 254df654a9b7..76296346e97c 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 254df654a9b75abf6ca08806535dbe1fad41be3f +Subproject commit 76296346e97c3702974d3398fdb94af9e10111a2 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index ebb28c95b2ea..d5ec87eabe57 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit ebb28c95b2ea68b96eddb9e71aff4d32eacc74f0 +Subproject commit d5ec87eabe5733cc2348c7dada89fc67c086f391 From 4083bdff0b7550534d93712c85164cb287acb856 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 24 Mar 2018 16:38:16 +0100 Subject: [PATCH 580/830] Fix impl assoc constant link not working --- src/librustdoc/clean/mod.rs | 14 ++++++-------- src/test/rustdoc/link-assoc-const.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 src/test/rustdoc/link-assoc-const.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a42b02140cd..73b3ae32cef6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1022,11 +1022,12 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option .flat_map(|imp| cx.tcx.associated_items(*imp)) .find(|item| item.name == item_name); if let Some(item) = item { - if item.kind == ty::AssociatedKind::Method && is_val { - Ok((ty.def, Some(format!("method.{}", item_name)))) - } else { - Err(()) - } + let out = match item.kind { + ty::AssociatedKind::Method if is_val => "method", + ty::AssociatedKind::Const if is_val => "associatedconstant", + _ => return Err(()) + }; + Ok((ty.def, Some(format!("{}.{}", out, item_name)))) } else { Err(()) } @@ -1139,9 +1140,6 @@ impl Clean for [ast::Attribute] { &link[..] }.trim(); - // avoid resolving things (i.e. regular links) which aren't like paths - // FIXME(Manishearth) given that most links have slashes in them might be worth - // doing a check for slashes first if path_str.contains(|ch: char| !(ch.is_alphanumeric() || ch == ':' || ch == '_')) { continue; diff --git a/src/test/rustdoc/link-assoc-const.rs b/src/test/rustdoc/link-assoc-const.rs new file mode 100644 index 000000000000..aa7ef07d5c0c --- /dev/null +++ b/src/test/rustdoc/link-assoc-const.rs @@ -0,0 +1,26 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +// @has foo/index.html '//a[@href="../foo/foo/constant.FIRSTCONST.html"]' 'foo::FIRSTCONST' +// @has foo/index.html '//a[@href="../foo/struct.Bar.html#associatedconstant.CONST"]' 'Bar::CONST' + +//! We have here [`foo::FIRSTCONST`] and [`Bar::CONST`]. + +pub mod foo { + pub const FIRSTCONST: u32 = 42; +} + +pub struct Bar; + +impl Bar { + pub const CONST: u32 = 42; +} From 433a03e6ff914bd367f129457a3d80822c9c6a42 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Sat, 24 Mar 2018 17:07:58 +0100 Subject: [PATCH 581/830] fixup! Some comments and documentation for name resolution crate --- src/librustc_resolve/lib.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cb2c206c69b1..d3689f7b5277 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -878,8 +878,9 @@ enum RibKind<'a> { /// /// A rib represents a scope names can live in. Note that these appear in many places, not just /// around braces. At any place where the list of accessible names (of the given namespace) -/// changes, a new rib is put onto a stack. This may be, for example, a `let` statement (because it -/// introduces variables), a macro, etc. +/// changes or a new restrictions on the name accessibility are introduced, a new rib is put onto a +/// stack. This may be, for example, a `let` statement (because it introduces variables), a macro, +/// etc. /// /// Different [rib kinds](enum.RibKind) are transparent for different names. /// @@ -935,11 +936,26 @@ enum PathResult<'a> { } enum ModuleKind { - /// Inline `mod something { ... }`. - Block(NodeId), - /// Module from another file. + /// An anonymous module, eg. just a block. /// - /// Also called a normal module in the following code. + /// ``` + /// fn main() { + /// fn f() {} // (1) + /// { // This is an anonymous module + /// f(); // This resolves to (2) as we are inside the block. + /// fn f() {} // (2) + /// } + /// f(); // Resolves to (1) + /// } + /// ``` + Block(NodeId), + /// Any module with a name. + /// + /// This could be: + /// + /// * A normal module ‒ either `mod from_file;` or `mod from_block { }`. + /// * A trait or an enum (it implicitly contains associated types, methods and variant + /// constructors). Def(Def, Name), } @@ -1444,8 +1460,8 @@ impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> { } } -/// This is the interface through which the rest of the compiler asks about name resolution after -/// the whole AST has been indexed. +/// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that +/// the resolver is no longer needed as all the relevant information is inline. impl<'a> hir::lowering::Resolver for Resolver<'a> { fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) { self.resolve_hir_path_cb(path, is_value, From 796c78a353d8746a7bd891eac4ad1505eca315dc Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 24 Mar 2018 13:44:28 -0700 Subject: [PATCH 582/830] appveyor: Move run-pass-fulldeps to extra builders We've made headway towards splitting the test suite across two appveyor builders and this moves one more tests suite between builders. The last [failed build][fail] had its longest running test suite and I've moved that to the secondary builder. cc #48844 [fail]: https://ci.appveyor.com/project/rust-lang/rust/build/1.0.6782 --- appveyor.yml | 8 ++++---- src/bootstrap/mk/Makefile.in | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 45e1b4b90d6c..54c15f662e13 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,10 +20,10 @@ environment: SCRIPT: python x.py test - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc - SCRIPT: python x.py test --exclude src/test/run-pass --exclude src/test/compile-fail + SCRIPT: make appveyor-subset-1 - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc - SCRIPT: python x.py test src/test/run-pass src/test/compile-fail + SCRIPT: make appveyor-subset-2 # MSVC aux tests - MSYS_BITS: 64 @@ -53,13 +53,13 @@ environment: # SourceForge is notoriously flaky, so we mirror it on our own infrastructure. - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu - SCRIPT: python x.py test --exclude src/test/run-pass --exclude src/test/compile-fail + SCRIPT: make appveyor-subset-1 MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 - MSYS_BITS: 32 RUST_CONFIGURE_ARGS: --build=i686-pc-windows-gnu - SCRIPT: python x.py test src/test/run-pass src/test/compile-fail + SCRIPT: make appveyor-subset-2 MINGW_URL: https://s3-us-west-1.amazonaws.com/rust-lang-ci2/rust-ci-mirror MINGW_ARCHIVE: i686-6.3.0-release-posix-dwarf-rt_v5-rev2.7z MINGW_DIR: mingw32 diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 7897af4f7247..bcf2f6a675e0 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -85,5 +85,12 @@ check-stage2-T-arm-linux-androideabi-H-x86_64-unknown-linux-gnu: check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu: $(Q)$(BOOTSTRAP) test --target x86_64-unknown-linux-musl +TESTS_IN_2 := src/test/run-pass src/test/compile-fail src/test/run-pass-fulldeps + +appveyor-subset-1: + $(Q)$(BOOTSTRAP) test $(TESTS_IN_2:%=--exclude %) +appveyor-subset-2: + $(Q)$(BOOTSTRAP) test $(TESTS_IN_2) + .PHONY: dist From 2f0dd4a8f0717bc50430817552cd8c9890fc60aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20L=C3=B6thberg?= Date: Tue, 20 Mar 2018 16:23:31 +0100 Subject: [PATCH 583/830] Add flag for telling the linker to strip debuginfo when building without it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johannes Löthberg --- src/librustc/session/config.rs | 2 ++ src/librustc_trans/back/linker.rs | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d24da1ff7c8e..4203985136a1 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1292,6 +1292,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "format compiler diagnostics in a way that's better suitable for UI testing"), embed_bitcode: bool = (false, parse_bool, [TRACKED], "embed LLVM bitcode in object files"), + strip_debuginfo_if_disabled: Option = (None, parse_opt_bool, [TRACKED], + "tell the linker to strip debuginfo when building without debuginfo enabled."), } pub fn default_lib_output() -> CrateType { diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 9bd7d83a1918..53a9dd6a76fc 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -281,7 +281,18 @@ impl<'a> Linker for GccLinker<'a> { } fn debuginfo(&mut self) { - // Don't do anything special here for GNU-style linkers. + match self.sess.opts.debuginfo { + DebugInfoLevel::NoDebugInfo => { + // If we are building without debuginfo enabled and we were called with + // `-Zstrip-debuginfo-if-disabled=yes`, tell the linker to strip any debuginfo + // found when linking to get rid of symbols from libstd. + match self.sess.opts.debugging_opts.strip_debuginfo_if_disabled { + Some(true) => { self.linker_arg("-S"); }, + _ => {}, + } + }, + _ => {}, + }; } fn no_default_libraries(&mut self) { From e8a1575cf6fe7105535db36e396a3a9a58765205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 01:40:48 +0100 Subject: [PATCH 584/830] profiler-builtins: define COMPILER_RT_HAS_UNAME on non-msvc platforms. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise lprofGetHostName, used by the PGO generator, won't be available. This means that PGO and coverage profiling would be restricted to systems with uname, but that seems acceptable. Signed-off-by: Emilio Cobos Álvarez --- src/libprofiler_builtins/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index dd88dd933f69..92244886552e 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -50,6 +50,7 @@ fn main() { cfg.flag("-fomit-frame-pointer"); cfg.flag("-ffreestanding"); cfg.define("VISIBILITY_HIDDEN", None); + cfg.define("COMPILER_RT_HAS_UNAME", Some("1")); } for src in profile_sources { From 804f959507ec38f5b3e1f7593c8c3aef5a7a2c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 01:46:39 +0100 Subject: [PATCH 585/830] session: Add two tracked, exclusive codegen options for PGO profile usage and generation. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/librustc/session/config.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index f41765b642d9..e5d7a618b355 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1027,6 +1027,11 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "`-C save-temps` might not produce all requested temporary products \ when incremental compilation is enabled.")], "save all temporary output files during compilation"), + pgo_gen: Option = (None, parse_opt_string, [TRACKED], + "Generate PGO profile data, to a given file, or to the default \ + location if it's empty."), + pgo_use: String = (String::new(), parse_string, [TRACKED], + "Use PGO profile data from the given profile file."), rpath: bool = (false, parse_bool, [UNTRACKED], "set rpath values in libs/exes"), overflow_checks: Option = (None, parse_opt_bool, [TRACKED], @@ -1801,6 +1806,13 @@ pub fn build_session_options_and_crate_config( let mut codegen_units = cg.codegen_units; let mut disable_thinlto = false; + if cg.pgo_gen.is_some() && !cg.pgo_use.is_empty() { + early_error( + error_format, + "options `-C pgo-gen` and `-C pgo-use` are exclussive", + ); + } + // Issue #30063: if user requests llvm-related output to one // particular path, disable codegen-units. let incompatible: Vec<_> = output_types @@ -2824,6 +2836,14 @@ mod tests { opts.cg.lto = Lto::Fat; assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + opts = reference.clone(); + opts.cg.pgo_gen = Some(String::from("abc")); + assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.cg.pgo_use = String::from("abc"); + assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); + opts = reference.clone(); opts.cg.target_cpu = Some(String::from("abc")); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); From 50a38725e1841aa2283f198dbc8ef2bd5bd1370b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 01:55:50 +0100 Subject: [PATCH 586/830] rustc_metadata: Load the profiler runtime if we're generating PGO profile data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This contains all the actual profiling code. Signed-off-by: Emilio Cobos Álvarez --- src/librustc_metadata/creader.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index baaf57c89089..812bbf29cf19 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -784,7 +784,9 @@ impl<'a> CrateLoader<'a> { } fn inject_profiler_runtime(&mut self) { - if self.sess.opts.debugging_opts.profile { + if self.sess.opts.debugging_opts.profile || + self.sess.opts.cg.pgo_gen.is_some() + { info!("loading profiler"); let symbol = Symbol::intern("profiler_builtins"); From 324ca7acd59be59abe0562287d5493f78a60823a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 01:57:12 +0100 Subject: [PATCH 587/830] rustc_llvm: rustc_trans: Thread the PGO config down to the pass manager builder. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/librustc_llvm/ffi.rs | 4 +++- src/librustc_trans/back/write.rs | 37 +++++++++++++++++++++++++++----- src/rustllvm/PassWrapper.cpp | 12 ++++++++++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index c0cdd2127706..25506f6a86e8 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1641,7 +1641,9 @@ extern "C" { OptLevel: CodeGenOptLevel, MergeFunctions: bool, SLPVectorize: bool, - LoopVectorize: bool); + LoopVectorize: bool, + PGOGenPath: *const c_char, + PGOUsePath: *const c_char); pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef, M: ModuleRef, DisableSimplifyLibCalls: bool); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 3e7422557e9b..2a8d280ee263 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -240,6 +240,9 @@ pub struct ModuleConfig { /// Some(level) to optimize binary size, or None to not affect program size. opt_size: Option, + pgo_gen: Option, + pgo_use: String, + // Flags indicating which outputs to produce. emit_no_opt_bc: bool, emit_bc: bool, @@ -274,6 +277,9 @@ impl ModuleConfig { opt_level: None, opt_size: None, + pgo_gen: None, + pgo_use: String::new(), + emit_no_opt_bc: false, emit_bc: false, emit_bc_compressed: false, @@ -932,6 +938,9 @@ pub fn start_async_translation(tcx: TyCtxt, modules_config.passes.push("insert-gcov-profiling".to_owned()) } + modules_config.pgo_gen = sess.opts.cg.pgo_gen.clone(); + modules_config.pgo_use = sess.opts.cg.pgo_use.clone(); + modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize)); modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize)); @@ -2046,6 +2055,8 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef, config: &ModuleConfig, opt_level: llvm::CodeGenOptLevel, f: &mut FnMut(llvm::PassManagerBuilderRef)) { + use std::ptr; + // Create the PassManagerBuilder for LLVM. We configure it with // reasonable defaults and prepare it to actually populate the pass // manager. @@ -2053,11 +2064,27 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef, let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone); let inline_threshold = config.inline_threshold; - llvm::LLVMRustConfigurePassManagerBuilder(builder, - opt_level, - config.merge_functions, - config.vectorize_slp, - config.vectorize_loop); + let pgo_gen_path = config.pgo_gen.as_ref().map(|s| { + let s = if s.is_empty() { "default_%m.profraw" } else { s }; + CString::new(s.as_bytes()).unwrap() + }); + + let pgo_use_path = if config.pgo_use.is_empty() { + None + } else { + Some(CString::new(config.pgo_use.as_bytes()).unwrap()) + }; + + llvm::LLVMRustConfigurePassManagerBuilder( + builder, + opt_level, + config.merge_functions, + config.vectorize_slp, + config.vectorize_loop, + pgo_gen_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + pgo_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()), + ); + llvm::LLVMPassManagerBuilderSetSizeLevel(builder, opt_size as u32); if opt_size != llvm::CodeGenOptSizeNone { diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 06d1301d7000..bee8ae5853f8 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -428,12 +428,22 @@ extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM, extern "C" void LLVMRustConfigurePassManagerBuilder( LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel, - bool MergeFunctions, bool SLPVectorize, bool LoopVectorize) { + bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, + const char* PGOGenPath, const char* PGOUsePath) { // Ignore mergefunc for now as enabling it causes crashes. // unwrap(PMBR)->MergeFunctions = MergeFunctions; unwrap(PMBR)->SLPVectorize = SLPVectorize; unwrap(PMBR)->OptLevel = fromRust(OptLevel); unwrap(PMBR)->LoopVectorize = LoopVectorize; + if (PGOGenPath) { + assert(!PGOUsePath); + unwrap(PMBR)->EnablePGOInstrGen = true; + unwrap(PMBR)->PGOInstrGen = PGOGenPath; + } + if (PGOUsePath) { + assert(!PGOGenPath); + unwrap(PMBR)->PGOInstrUse = PGOUsePath; + } } // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo` From 99127abca8c9678e14ee11bee4d46bc34ec8b164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 01:57:55 +0100 Subject: [PATCH 588/830] rustc_trans: disable probestack when using pgo-gen. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Executables crash in the probestack function otherwise... I haven't debugged much further than that. Signed-off-by: Emilio Cobos Álvarez --- src/librustc_trans/attributes.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index df78ccdd2298..f53c1e84f6e8 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -92,6 +92,11 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) { _ => {} } + // probestack doesn't play nice either with pgo-gen. + if cx.sess().opts.cg.pgo_gen.is_some() { + return; + } + // Flag our internal `__rust_probestack` function as the stack probe symbol. // This is defined in the `compiler-builtins` crate for each architecture. llvm::AddFunctionAttrStringValue( From 9c61c7284a39db3471b395ccc5704ef77dc653ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 02:04:49 +0100 Subject: [PATCH 589/830] rustc_trans: Fix PGO generation linking on Linux by adding the relevant linker commands. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See the linked LLVM reviews for the clang counter-parts. Signed-off-by: Emilio Cobos Álvarez --- src/librustc_trans/back/link.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 542cdc5baad3..657563eac2cf 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1085,6 +1085,20 @@ fn link_args(cmd: &mut Linker, cmd.build_static_executable(); } + // If we're doing PGO generation stuff and on a GNU-like linker, use the + // "-u" flag to properly pull in the profiler runtime bits. + // + // This is because LLVM otherwise won't add the needed initialization for us + // on Linux (though the extra flag should be harmless if it does). + // + // See https://reviews.llvm.org/D14033 and https://reviews.llvm.org/D14030. + // + // Though it may be worth to try to revert those changes upstream, since the + // overhead of the initialization should be minor. + if sess.opts.cg.pgo_gen.is_some() && sess.target.target.options.linker_is_gnu { + cmd.args(&["-u".to_owned(), "__llvm_profile_runtime".to_owned()]); + } + // FIXME (#2397): At some point we want to rpath our guesses as to // where extern libraries might live, based on the // addl_lib_search_paths From e2183d3c707e87f2b333f9742b8de9885d36b7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 02:49:48 +0100 Subject: [PATCH 590/830] Test that pgo-gen works properly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/test/run-make/pgo-gen/Makefile | 8 ++++++++ src/test/run-make/pgo-gen/test.rs | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/test/run-make/pgo-gen/Makefile create mode 100644 src/test/run-make/pgo-gen/test.rs diff --git a/src/test/run-make/pgo-gen/Makefile b/src/test/run-make/pgo-gen/Makefile new file mode 100644 index 000000000000..a6b7b2c02b28 --- /dev/null +++ b/src/test/run-make/pgo-gen/Makefile @@ -0,0 +1,8 @@ +-include ../tools.mk + +all: +ifeq ($(PROFILER_SUPPORT),1) + $(RUSTC) -g -C pgo-gen=test.profraw test.rs + $(call RUN,test) || exit 1 + [ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1) +endif diff --git a/src/test/run-make/pgo-gen/test.rs b/src/test/run-make/pgo-gen/test.rs new file mode 100644 index 000000000000..3f07b46791d2 --- /dev/null +++ b/src/test/run-make/pgo-gen/test.rs @@ -0,0 +1,11 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() {} From aaeb40ab3b13d02ae148104ca6defffe6e77851f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Feb 2018 03:20:51 +0100 Subject: [PATCH 591/830] profiler_builtins: Add missing ProfilingNameVar file to the profiler build. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise opt builds with pgo-gen fail, d'oh. Signed-off-by: Emilio Cobos Álvarez --- src/libprofiler_builtins/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 92244886552e..6c7407760dfa 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -27,6 +27,7 @@ fn main() { "InstrProfilingFile.c", "InstrProfilingMerge.c", "InstrProfilingMergeFile.c", + "InstrProfilingNameVar.c", "InstrProfilingPlatformDarwin.c", "InstrProfilingPlatformLinux.c", "InstrProfilingPlatformOther.c", From a95c8c66a72e82e2eb41bccb450e2bf5b0d67e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 12 Mar 2018 18:11:59 +0100 Subject: [PATCH 592/830] librustc_llvm: Show PGO diagnostics properly. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/librustc_llvm/diagnostic.rs | 5 +++++ src/librustc_llvm/ffi.rs | 1 + src/librustc_trans/back/write.rs | 9 +++++++-- src/rustllvm/RustWrapper.cpp | 3 +++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs index c5cdf6566921..e73c570ed823 100644 --- a/src/librustc_llvm/diagnostic.rs +++ b/src/librustc_llvm/diagnostic.rs @@ -121,6 +121,7 @@ impl InlineAsmDiagnostic { pub enum Diagnostic { Optimization(OptimizationDiagnostic), InlineAsm(InlineAsmDiagnostic), + PGO(DiagnosticInfoRef), /// LLVM has other types that we do not wrap here. UnknownDiagnostic(DiagnosticInfoRef), @@ -160,6 +161,10 @@ impl Diagnostic { Optimization(OptimizationDiagnostic::unpack(OptimizationFailure, di)) } + Dk::PGOProfile => { + PGO(di) + } + _ => UnknownDiagnostic(di), } } diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 25506f6a86e8..1271773fa02b 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -322,6 +322,7 @@ pub enum DiagnosticKind { OptimizationRemarkAnalysisAliasing, OptimizationRemarkOther, OptimizationFailure, + PGOProfile, } /// LLVMRustArchiveKind diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 2a8d280ee263..99558652d690 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -498,8 +498,13 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo opt.message)); } } - - _ => (), + llvm::diagnostic::PGO(diagnostic_ref) => { + let msg = llvm::build_string(|s| { + llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) + }).expect("non-UTF8 PGO diagnostic"); + diag_handler.note_without_error(&msg); + } + llvm::diagnostic::UnknownDiagnostic(..) => {}, } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index a5644d6f9e2e..970c1c6a0110 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1021,6 +1021,7 @@ enum class LLVMRustDiagnosticKind { OptimizationRemarkAnalysisAliasing, OptimizationRemarkOther, OptimizationFailure, + PGOProfile, }; static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { @@ -1043,6 +1044,8 @@ static LLVMRustDiagnosticKind toRust(DiagnosticKind Kind) { return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute; case DK_OptimizationRemarkAnalysisAliasing: return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing; + case DK_PGOProfile: + return LLVMRustDiagnosticKind::PGOProfile; default: return (Kind >= DK_FirstRemark && Kind <= DK_LastRemark) ? LLVMRustDiagnosticKind::OptimizationRemarkOther From 036e0d7943f274fc3269a9cd67d2c922e397fcaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 12 Mar 2018 20:45:35 +0100 Subject: [PATCH 593/830] librustc_trans: disable profiling pre-inlining. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It destroys performance actually. Signed-off-by: Emilio Cobos Álvarez --- src/librustc_trans/llvm_util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 5113b65a5c47..12364b32d116 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -61,6 +61,7 @@ unsafe fn configure_llvm(sess: &Session) { add("rustc"); // fake program name if sess.time_llvm_passes() { add("-time-passes"); } if sess.print_llvm_passes() { add("-debug-pass=Structure"); } + add("-disable-preinline"); for arg in &sess.opts.cg.llvm_args { add(&(*arg)); From 688275a4009a7a87fb211f0b690f386fc2de8740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 12 Mar 2018 21:11:25 +0100 Subject: [PATCH 594/830] librustc: Convert -C pgo-gen and -C pgo-use into -Z flags. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/librustc/session/config.rs | 40 +++++++++++++++--------------- src/librustc_metadata/creader.rs | 2 +- src/librustc_trans/attributes.rs | 2 +- src/librustc_trans/back/link.rs | 4 ++- src/librustc_trans/back/write.rs | 4 +-- src/test/run-make/pgo-gen/Makefile | 2 +- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index e5d7a618b355..7f92a087ebfc 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1027,11 +1027,6 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, "`-C save-temps` might not produce all requested temporary products \ when incremental compilation is enabled.")], "save all temporary output files during compilation"), - pgo_gen: Option = (None, parse_opt_string, [TRACKED], - "Generate PGO profile data, to a given file, or to the default \ - location if it's empty."), - pgo_use: String = (String::new(), parse_string, [TRACKED], - "Use PGO profile data from the given profile file."), rpath: bool = (false, parse_bool, [UNTRACKED], "set rpath values in libs/exes"), overflow_checks: Option = (None, parse_opt_bool, [TRACKED], @@ -1254,6 +1249,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "extra arguments to prepend to the linker invocation (space separated)"), profile: bool = (false, parse_bool, [TRACKED], "insert profiling code"), + pgo_gen: Option = (None, parse_opt_string, [TRACKED], + "Generate PGO profile data, to a given file, or to the default \ + location if it's empty."), + pgo_use: String = (String::new(), parse_string, [TRACKED], + "Use PGO profile data from the given profile file."), relro_level: Option = (None, parse_relro_level, [TRACKED], "choose which RELRO level to use"), nll: bool = (false, parse_bool, [UNTRACKED], @@ -1776,6 +1776,13 @@ pub fn build_session_options_and_crate_config( ); } + if debugging_opts.pgo_gen.is_some() && !debugging_opts.pgo_use.is_empty() { + early_error( + error_format, + "options `-Z pgo-gen` and `-Z pgo-use` are exclusive", + ); + } + let mut output_types = BTreeMap::new(); if !debugging_opts.parse_only { for list in matches.opt_strs("emit") { @@ -1806,13 +1813,6 @@ pub fn build_session_options_and_crate_config( let mut codegen_units = cg.codegen_units; let mut disable_thinlto = false; - if cg.pgo_gen.is_some() && !cg.pgo_use.is_empty() { - early_error( - error_format, - "options `-C pgo-gen` and `-C pgo-use` are exclussive", - ); - } - // Issue #30063: if user requests llvm-related output to one // particular path, disable codegen-units. let incompatible: Vec<_> = output_types @@ -2836,14 +2836,6 @@ mod tests { opts.cg.lto = Lto::Fat; assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); - opts = reference.clone(); - opts.cg.pgo_gen = Some(String::from("abc")); - assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); - - opts = reference.clone(); - opts.cg.pgo_use = String::from("abc"); - assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); - opts = reference.clone(); opts.cg.target_cpu = Some(String::from("abc")); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); @@ -2904,6 +2896,14 @@ mod tests { opts.debugging_opts.tls_model = Some(String::from("tls model")); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + opts = reference.clone(); + opts.debugging_opts.pgo_gen = Some(String::from("abc")); + assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.debugging_opts.pgo_use = String::from("abc"); + assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash()); + opts = reference.clone(); opts.cg.metadata = vec![String::from("A"), String::from("B")]; assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 812bbf29cf19..802665b6ddbc 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -785,7 +785,7 @@ impl<'a> CrateLoader<'a> { fn inject_profiler_runtime(&mut self) { if self.sess.opts.debugging_opts.profile || - self.sess.opts.cg.pgo_gen.is_some() + self.sess.opts.debugging_opts.pgo_gen.is_some() { info!("loading profiler"); diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index f53c1e84f6e8..c968b8525a5b 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -93,7 +93,7 @@ pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) { } // probestack doesn't play nice either with pgo-gen. - if cx.sess().opts.cg.pgo_gen.is_some() { + if cx.sess().opts.debugging_opts.pgo_gen.is_some() { return; } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 657563eac2cf..19f0d5866ef3 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1095,7 +1095,9 @@ fn link_args(cmd: &mut Linker, // // Though it may be worth to try to revert those changes upstream, since the // overhead of the initialization should be minor. - if sess.opts.cg.pgo_gen.is_some() && sess.target.target.options.linker_is_gnu { + if sess.opts.debugging_opts.pgo_gen.is_some() && + sess.target.target.options.linker_is_gnu + { cmd.args(&["-u".to_owned(), "__llvm_profile_runtime".to_owned()]); } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 99558652d690..26cdca1cdbf4 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -943,8 +943,8 @@ pub fn start_async_translation(tcx: TyCtxt, modules_config.passes.push("insert-gcov-profiling".to_owned()) } - modules_config.pgo_gen = sess.opts.cg.pgo_gen.clone(); - modules_config.pgo_use = sess.opts.cg.pgo_use.clone(); + modules_config.pgo_gen = sess.opts.debugging_opts.pgo_gen.clone(); + modules_config.pgo_use = sess.opts.debugging_opts.pgo_use.clone(); modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize)); modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize)); diff --git a/src/test/run-make/pgo-gen/Makefile b/src/test/run-make/pgo-gen/Makefile index a6b7b2c02b28..bc5cef2370c6 100644 --- a/src/test/run-make/pgo-gen/Makefile +++ b/src/test/run-make/pgo-gen/Makefile @@ -2,7 +2,7 @@ all: ifeq ($(PROFILER_SUPPORT),1) - $(RUSTC) -g -C pgo-gen=test.profraw test.rs + $(RUSTC) -g -Z pgo-gen=test.profraw test.rs $(call RUN,test) || exit 1 [ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1) endif From e31addf7c358aba28ce0910e93d009397a72a05f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 12 Mar 2018 21:15:16 +0100 Subject: [PATCH 595/830] librustc_trans: Gate the preinliner with another -Z flag. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Emilio Cobos Álvarez --- src/librustc/session/config.rs | 3 +++ src/librustc_trans/llvm_util.rs | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 7f92a087ebfc..9fd370c54be9 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1254,6 +1254,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, location if it's empty."), pgo_use: String = (String::new(), parse_string, [TRACKED], "Use PGO profile data from the given profile file."), + disable_instrumentation_preinliner: bool = + (false, parse_bool, [TRACKED], "Disable the instrumentation pre-inliner, \ + useful for profiling / PGO."), relro_level: Option = (None, parse_relro_level, [TRACKED], "choose which RELRO level to use"), nll: bool = (false, parse_bool, [UNTRACKED], diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs index 12364b32d116..1c8f09ce7b3f 100644 --- a/src/librustc_trans/llvm_util.rs +++ b/src/librustc_trans/llvm_util.rs @@ -61,7 +61,9 @@ unsafe fn configure_llvm(sess: &Session) { add("rustc"); // fake program name if sess.time_llvm_passes() { add("-time-passes"); } if sess.print_llvm_passes() { add("-debug-pass=Structure"); } - add("-disable-preinline"); + if sess.opts.debugging_opts.disable_instrumentation_preinliner { + add("-disable-preinline"); + } for arg in &sess.opts.cg.llvm_args { add(&(*arg)); From 8a4cebd16f4fa3ba2234c6d4453051b568c6d904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 12 Mar 2018 21:18:01 +0100 Subject: [PATCH 596/830] librustc_trans: Turn PGO diagnostics into warnings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They should at least be that, they usually warn about control flow mismatches, and or the profile being useless, which looks like at least a warning to me. Signed-off-by: Emilio Cobos Álvarez --- src/librustc_trans/back/write.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 26cdca1cdbf4..2cbb88fed05c 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -502,7 +502,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo let msg = llvm::build_string(|s| { llvm::LLVMRustWriteDiagnosticInfoToString(diagnostic_ref, s) }).expect("non-UTF8 PGO diagnostic"); - diag_handler.note_without_error(&msg); + diag_handler.warn(&msg); } llvm::diagnostic::UnknownDiagnostic(..) => {}, } From 4053e25bfb55b6e1bf6766158ccd06cb87de79c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 13 Mar 2018 12:40:57 +0100 Subject: [PATCH 597/830] librustc_trans: Mark some profiler symbols as exported to avoid LTO removing them. --- src/librustc_trans/back/symbol_export.rs | 14 ++++++++++++++ src/test/run-make/pgo-gen-lto/Makefile | 8 ++++++++ src/test/run-make/pgo-gen-lto/test.rs | 11 +++++++++++ 3 files changed, 33 insertions(+) create mode 100644 src/test/run-make/pgo-gen-lto/Makefile create mode 100644 src/test/run-make/pgo-gen-lto/test.rs diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index fd79ae7435ed..d205e6ca4eda 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -223,6 +223,20 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } + if tcx.sess.opts.debugging_opts.pgo_gen.is_some() { + // These are weak symbols that point to the profile version and the + // profile name, which need to be treated as exported so LTO doesn't nix + // them. + const PROFILER_WEAK_SYMBOLS: [&'static str; 2] = [ + "__llvm_profile_raw_version", + "__llvm_profile_filename", + ]; + for sym in &PROFILER_WEAK_SYMBOLS { + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(sym)); + symbols.push((exported_symbol, SymbolExportLevel::C)); + } + } + if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) { let symbol_name = metadata_symbol_name(tcx); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(&symbol_name)); diff --git a/src/test/run-make/pgo-gen-lto/Makefile b/src/test/run-make/pgo-gen-lto/Makefile new file mode 100644 index 000000000000..5de2c707f357 --- /dev/null +++ b/src/test/run-make/pgo-gen-lto/Makefile @@ -0,0 +1,8 @@ +-include ../tools.mk + +all: +ifeq ($(PROFILER_SUPPORT),1) + $(RUSTC) -Copt-level=3 -Clto=fat -Z pgo-gen=test.profraw test.rs + $(call RUN,test) || exit 1 + [ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1) +endif diff --git a/src/test/run-make/pgo-gen-lto/test.rs b/src/test/run-make/pgo-gen-lto/test.rs new file mode 100644 index 000000000000..3f07b46791d2 --- /dev/null +++ b/src/test/run-make/pgo-gen-lto/test.rs @@ -0,0 +1,11 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() {} From e155ecdc9714f3ac76b554dc15ba06e219f576e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 15 Mar 2018 16:56:45 +0100 Subject: [PATCH 598/830] try to fix the build on older LLVM versions. --- src/librustc_llvm/ffi.rs | 1 + src/librustc_trans/base.rs | 7 +++++++ src/rustllvm/PassWrapper.cpp | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 1271773fa02b..d9c18e6cf0c4 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1739,6 +1739,7 @@ extern "C" { pub fn LLVMRustModuleCost(M: ModuleRef) -> u64; pub fn LLVMRustThinLTOAvailable() -> bool; + pub fn LLVMRustPGOAvailable() -> bool; pub fn LLVMRustWriteThinBitcodeToFile(PMR: PassManagerRef, M: ModuleRef, BC: *const c_char) -> bool; diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 56eece9f31e7..c839e5340f58 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -708,6 +708,13 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } + if (tcx.sess.opts.debugging_opts.pgo_gen.is_some() || + !tcx.sess.opts.debugging_opts.pgo_use.is_empty()) && + unsafe { !llvm::LLVMRustPGOAvailable() } + { + tcx.sess.fatal("this compiler's LLVM does not support PGO"); + } + let crate_hash = tcx.crate_hash(LOCAL_CRATE); let link_meta = link::build_link_meta(crate_hash); diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index bee8ae5853f8..3d5cce81278a 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -44,6 +44,10 @@ #include "llvm-c/Transforms/PassManagerBuilder.h" +#if LLVM_VERSION_GE(4, 0) +#define PGO_AVAILABLE +#endif + using namespace llvm; using namespace llvm::legacy; @@ -435,6 +439,8 @@ extern "C" void LLVMRustConfigurePassManagerBuilder( unwrap(PMBR)->SLPVectorize = SLPVectorize; unwrap(PMBR)->OptLevel = fromRust(OptLevel); unwrap(PMBR)->LoopVectorize = LoopVectorize; + +#ifdef PGO_AVAILABLE if (PGOGenPath) { assert(!PGOUsePath); unwrap(PMBR)->EnablePGOInstrGen = true; @@ -444,6 +450,9 @@ extern "C" void LLVMRustConfigurePassManagerBuilder( assert(!PGOGenPath); unwrap(PMBR)->PGOInstrUse = PGOUsePath; } +#else + assert(!PGOGenPath && !PGOUsePath && "Should've caught earlier"); +#endif } // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo` @@ -776,6 +785,15 @@ LLVMRustThinLTOAvailable() { #endif } +extern "C" bool +LLVMRustPGOAvailable() { +#ifdef PGO_AVAILABLE + return true; +#else + return false; +#endif +} + #if LLVM_VERSION_GE(4, 0) // Here you'll find an implementation of ThinLTO as used by the Rust compiler From 96b87296ce89d5b5cb53f21cd7893b3ae3d80c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 19 Mar 2018 22:29:58 +0100 Subject: [PATCH 599/830] Move linker code to the Linker trait instead. --- src/librustc_trans/back/link.rs | 16 ++-------------- src/librustc_trans/back/linker.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 19f0d5866ef3..75ba83a7c620 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -1085,20 +1085,8 @@ fn link_args(cmd: &mut Linker, cmd.build_static_executable(); } - // If we're doing PGO generation stuff and on a GNU-like linker, use the - // "-u" flag to properly pull in the profiler runtime bits. - // - // This is because LLVM otherwise won't add the needed initialization for us - // on Linux (though the extra flag should be harmless if it does). - // - // See https://reviews.llvm.org/D14033 and https://reviews.llvm.org/D14030. - // - // Though it may be worth to try to revert those changes upstream, since the - // overhead of the initialization should be minor. - if sess.opts.debugging_opts.pgo_gen.is_some() && - sess.target.target.options.linker_is_gnu - { - cmd.args(&["-u".to_owned(), "__llvm_profile_runtime".to_owned()]); + if sess.opts.debugging_opts.pgo_gen.is_some() { + cmd.pgo_gen(); } // FIXME (#2397): At some point we want to rpath our guesses as to diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index 9bd7d83a1918..c8bbfed41eb5 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -117,6 +117,7 @@ pub trait Linker { fn partial_relro(&mut self); fn no_relro(&mut self); fn optimize(&mut self); + fn pgo_gen(&mut self); fn debuginfo(&mut self); fn no_default_libraries(&mut self); fn build_dylib(&mut self, out_filename: &Path); @@ -280,6 +281,24 @@ impl<'a> Linker for GccLinker<'a> { } } + fn pgo_gen(&mut self) { + if !self.sess.target.target.options.linker_is_gnu { return } + + // If we're doing PGO generation stuff and on a GNU-like linker, use the + // "-u" flag to properly pull in the profiler runtime bits. + // + // This is because LLVM otherwise won't add the needed initialization + // for us on Linux (though the extra flag should be harmless if it + // does). + // + // See https://reviews.llvm.org/D14033 and https://reviews.llvm.org/D14030. + // + // Though it may be worth to try to revert those changes upstream, since + // the overhead of the initialization should be minor. + self.cmd.arg("-u"); + self.cmd.arg("__llvm_profile_runtime"); + } + fn debuginfo(&mut self) { // Don't do anything special here for GNU-style linkers. } @@ -509,6 +528,10 @@ impl<'a> Linker for MsvcLinker<'a> { // Needs more investigation of `/OPT` arguments } + fn pgo_gen(&mut self) { + // Nothing needed here. + } + fn debuginfo(&mut self) { // This will cause the Microsoft linker to generate a PDB file // from the CodeView line tables in the object files. @@ -712,6 +735,10 @@ impl<'a> Linker for EmLinker<'a> { self.cmd.args(&["--memory-init-file", "0"]); } + fn pgo_gen(&mut self) { + // noop, but maybe we need something like the gnu linker? + } + fn debuginfo(&mut self) { // Preserve names or generate source maps depending on debug info self.cmd.arg(match self.sess.opts.debuginfo { @@ -877,6 +904,9 @@ impl Linker for WasmLd { fn optimize(&mut self) { } + fn pgo_gen(&mut self) { + } + fn debuginfo(&mut self) { } From 5af2f80fdd152bc9ffb6f19043de8967fe9d0071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 25 Mar 2018 03:29:15 +0200 Subject: [PATCH 600/830] pgo: Move the tests to run-make-fulldeps, and make the profile file be in the tmp directory properly. --- src/test/{run-make => run-make-fulldeps}/pgo-gen-lto/Makefile | 2 +- src/test/{run-make => run-make-fulldeps}/pgo-gen-lto/test.rs | 0 src/test/{run-make => run-make-fulldeps}/pgo-gen/Makefile | 2 +- src/test/{run-make => run-make-fulldeps}/pgo-gen/test.rs | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename src/test/{run-make => run-make-fulldeps}/pgo-gen-lto/Makefile (67%) rename src/test/{run-make => run-make-fulldeps}/pgo-gen-lto/test.rs (100%) rename src/test/{run-make => run-make-fulldeps}/pgo-gen/Makefile (73%) rename src/test/{run-make => run-make-fulldeps}/pgo-gen/test.rs (100%) diff --git a/src/test/run-make/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile similarity index 67% rename from src/test/run-make/pgo-gen-lto/Makefile rename to src/test/run-make-fulldeps/pgo-gen-lto/Makefile index 5de2c707f357..e8c695f52bec 100644 --- a/src/test/run-make/pgo-gen-lto/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile @@ -2,7 +2,7 @@ all: ifeq ($(PROFILER_SUPPORT),1) - $(RUSTC) -Copt-level=3 -Clto=fat -Z pgo-gen=test.profraw test.rs + $(RUSTC) -Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)/test.profraw" test.rs $(call RUN,test) || exit 1 [ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1) endif diff --git a/src/test/run-make/pgo-gen-lto/test.rs b/src/test/run-make-fulldeps/pgo-gen-lto/test.rs similarity index 100% rename from src/test/run-make/pgo-gen-lto/test.rs rename to src/test/run-make-fulldeps/pgo-gen-lto/test.rs diff --git a/src/test/run-make/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile similarity index 73% rename from src/test/run-make/pgo-gen/Makefile rename to src/test/run-make-fulldeps/pgo-gen/Makefile index bc5cef2370c6..7dc227b5a145 100644 --- a/src/test/run-make/pgo-gen/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen/Makefile @@ -2,7 +2,7 @@ all: ifeq ($(PROFILER_SUPPORT),1) - $(RUSTC) -g -Z pgo-gen=test.profraw test.rs + $(RUSTC) -g -Z pgo-gen="$(TMPDIR)/test.profraw" test.rs $(call RUN,test) || exit 1 [ -e "$(TMPDIR)/test.profraw" ] || (echo "No .profraw file"; exit 1) endif diff --git a/src/test/run-make/pgo-gen/test.rs b/src/test/run-make-fulldeps/pgo-gen/test.rs similarity index 100% rename from src/test/run-make/pgo-gen/test.rs rename to src/test/run-make-fulldeps/pgo-gen/test.rs From d37a7ab32b4f4f1a0b944abaa3ca104978aecb12 Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Sat, 24 Mar 2018 22:00:38 -0400 Subject: [PATCH 601/830] Extend two-phase borrows to apply to method receiver autorefs This is required to compile things like src/test/ui/borrowck/two-phase-method-receivers.rs --- src/librustc_typeck/check/cast.rs | 5 +- src/librustc_typeck/check/coercion.rs | 37 ++++++++++---- src/librustc_typeck/check/demand.rs | 10 ++-- src/librustc_typeck/check/mod.rs | 7 +-- .../borrowck/two-phase-nonrecv-autoref.rs | 49 ++++++++++++------- .../ui/borrowck/two-phase-method-receivers.rs | 29 +++++++++++ 6 files changed, 100 insertions(+), 37 deletions(-) create mode 100644 src/test/ui/borrowck/two-phase-method-receivers.rs diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index e4bad8349ea2..70fe3afa6d25 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -434,7 +434,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { let f = self.expr_ty.fn_sig(fcx.tcx); let res = fcx.try_coerce(self.expr, self.expr_ty, - fcx.tcx.mk_fn_ptr(f)); + fcx.tcx.mk_fn_ptr(f), + false); if !res.is_ok() { return Err(CastError::NonScalar); } @@ -616,7 +617,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool { - fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty).is_ok() + fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, false).is_ok() } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 269ee49f38e7..255794aeab43 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -84,6 +84,12 @@ struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, cause: ObligationCause<'tcx>, use_lub: bool, + /// Determines whether or not allow_two_phase_borrow is set on any + /// autoref adjustments we create while coercing. We don't want to + /// allow deref coercions to create two-phase borrows, at least initially, + /// but we do need two-phase borrows for function argument reborrows. + /// See #47489 and #48598 + allow_two_phase: bool, } impl<'a, 'gcx, 'tcx> Deref for Coerce<'a, 'gcx, 'tcx> { @@ -123,10 +129,13 @@ fn success<'tcx>(adj: Vec>, } impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { - fn new(fcx: &'f FnCtxt<'f, 'gcx, 'tcx>, cause: ObligationCause<'tcx>) -> Self { + fn new(fcx: &'f FnCtxt<'f, 'gcx, 'tcx>, + cause: ObligationCause<'tcx>, + allow_two_phase: bool) -> Self { Coerce { fcx, cause, + allow_two_phase, use_lub: false, } } @@ -424,10 +433,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let mutbl = match mt_b.mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { - // Deref-coercion is a case where we deliberately - // disallow two-phase borrows in its initial - // deployment; see discussion on PR #47489. - allow_two_phase_borrow: false, + allow_two_phase_borrow: self.allow_two_phase, } }; adjustments.push(Adjustment { @@ -473,6 +479,9 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let mutbl = match mt_b.mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { + // We don't allow two-phase borrows here, at least for initial + // implementation. If it happens that this coercion is a function argument, + // the reborrow in coerce_borrowed_ptr will pick it up. allow_two_phase_borrow: false, } }; @@ -751,13 +760,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn try_coerce(&self, expr: &hir::Expr, expr_ty: Ty<'tcx>, - target: Ty<'tcx>) + target: Ty<'tcx>, + allow_two_phase: bool) -> RelateResult<'tcx, Ty<'tcx>> { let source = self.resolve_type_vars_with_obligations(expr_ty); debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target); let cause = self.cause(expr.span, ObligationCauseCode::ExprAssignable); - let coerce = Coerce::new(self, cause); + let coerce = Coerce::new(self, cause, allow_two_phase); let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?; let (adjustments, _) = self.register_infer_ok_obligations(ok); @@ -771,7 +781,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { debug!("coercion::can({:?} -> {:?})", source, target); let cause = self.cause(syntax_pos::DUMMY_SP, ObligationCauseCode::ExprAssignable); - let coerce = Coerce::new(self, cause); + // We don't ever need two-phase here since we throw out the result of the coercion + let coerce = Coerce::new(self, cause, false); self.probe(|_| coerce.coerce(source, target)).is_ok() } @@ -840,7 +851,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return Ok(fn_ptr); } - let mut coerce = Coerce::new(self, cause.clone()); + // Configure a Coerce instance to compute the LUB. + // We don't allow two-phase borrows on any autorefs this creates since we + // probably aren't processing function arguments here and even if we were, + // they're going to get autorefed again anyway and we can apply 2-phase borrows + // at that time. + let mut coerce = Coerce::new(self, cause.clone(), false); coerce.use_lub = true; // First try to coerce the new expression to the type of the previous ones, @@ -1106,7 +1122,8 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> if self.pushed == 0 { // Special-case the first expression we are coercing. // To be honest, I'm not entirely sure why we do this. - fcx.try_coerce(expression, expression_ty, self.expected_ty) + // We don't allow two-phase borrows, see comment in try_find_coercion_lub for why + fcx.try_coerce(expression, expression_ty, self.expected_ty, false) } else { match self.expressions { Expressions::Dynamic(ref exprs) => diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 634a7ee56991..ab89e17d81fe 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -79,9 +79,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn demand_coerce(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, - expected: Ty<'tcx>) + expected: Ty<'tcx>, + allow_two_phase: bool) -> Ty<'tcx> { - let (ty, err) = self.demand_coerce_diag(expr, checked_ty, expected); + let (ty, err) = self.demand_coerce_diag(expr, checked_ty, expected, allow_two_phase); if let Some(mut err) = err { err.emit(); } @@ -96,11 +97,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn demand_coerce_diag(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, - expected: Ty<'tcx>) + expected: Ty<'tcx>, + allow_two_phase: bool) -> (Ty<'tcx>, Option>) { let expected = self.resolve_type_vars_with_obligations(expected); - let e = match self.try_coerce(expr, checked_ty, expected) { + let e = match self.try_coerce(expr, checked_ty, expected, allow_two_phase) { Ok(ty) => return (ty, None), Err(e) => e }; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 4a685cfddb7a..fe27dd50af47 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2649,7 +2649,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // to, which is `expected_ty` if `rvalue_hint` returns an // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise. let coerce_ty = expected.and_then(|e| e.only_has_type(self)); - self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty)); + self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty), true); // 3. Relate the expected type and the formal one, // if the expected type was used for the coercion. @@ -2812,7 +2812,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr, ExpectHasType(expected), needs); - self.demand_coerce(expr, ty, expected) + self.demand_coerce(expr, ty, expected, false) } fn check_expr_with_hint(&self, expr: &'gcx hir::Expr, @@ -4112,7 +4112,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let base_t = self.structurally_resolved_type(expr.span, base_t); match self.lookup_indexing(expr, base, base_t, idx_t, needs) { Some((index_ty, element_ty)) => { - self.demand_coerce(idx, idx_t, index_ty); + // two-phase not needed because index_ty is never mutable + self.demand_coerce(idx, idx_t, index_ty, false); element_ty } None => { diff --git a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs index bf8e02adb1ae..ef39fabda10e 100644 --- a/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs +++ b/src/test/compile-fail/borrowck/two-phase-nonrecv-autoref.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// revisions: lxl nll +// revisions: ast lxl nll +//[ast]compile-flags: //[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows //[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll @@ -33,17 +34,14 @@ use std::ops::{Index, IndexMut}; -// This is case outlined by Niko that we want to ensure we reject -// (at least initially). - fn foo(x: &mut u32, y: u32) { *x += y; } fn deref_coercion(x: &mut u32) { foo(x, *x); - //[lxl]~^ ERROR cannot use `*x` because it was mutably borrowed [E0503] - //[nll]~^^ ERROR cannot use `*x` because it was mutably borrowed [E0503] + //[ast]~^ ERROR cannot use `*x` because it was mutably borrowed [E0503] + // Above error is a known limitation of AST borrowck } // While adding a flag to adjustments (indicating whether they @@ -74,22 +72,25 @@ fn overloaded_call_traits() { //[lxl]~^ ERROR cannot borrow `*f` as mutable more than once at a time //[nll]~^^ ERROR cannot borrow `*f` as mutable more than once at a time //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time + //[ast]~^^^^ ERROR cannot borrow `*f` as mutable more than once at a time } fn twice_ten_si i32>(f: &mut F) { f(f(10)); } fn twice_ten_so i32>(f: Box) { f(f(10)); - //[lxl]~^ ERROR use of moved value: `*f` - //[nll]~^^ ERROR use of moved value: `*f` - //[g2p]~^^^ ERROR use of moved value: `*f` + //[lxl]~^ ERROR use of moved value: `*f` + //[nll]~^^ ERROR use of moved value: `*f` + //[g2p]~^^^ ERROR use of moved value: `*f` + //[ast]~^^^^ ERROR use of moved value: `*f` } fn twice_ten_om(f: &mut FnMut(i32) -> i32) { f(f(10)); - //[lxl]~^ ERROR cannot borrow `*f` as mutable more than once at a time + //[lxl]~^ ERROR cannot borrow `*f` as mutable more than once at a time //[nll]~^^ ERROR cannot borrow `*f` as mutable more than once at a time - //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time + //[g2p]~^^^ ERROR cannot borrow `*f` as mutable more than once at a time + //[ast]~^^^^ ERROR cannot borrow `*f` as mutable more than once at a time } fn twice_ten_oi(f: &mut Fn(i32) -> i32) { f(f(10)); @@ -105,6 +106,7 @@ fn overloaded_call_traits() { //[g2p]~^^^^^^^ ERROR cannot move a value of type //[g2p]~^^^^^^^^ ERROR cannot move a value of type //[g2p]~^^^^^^^^^ ERROR use of moved value: `*f` + //[ast]~^^^^^^^^^^ ERROR use of moved value: `*f` } twice_ten_sm(&mut |x| x + 1); @@ -142,12 +144,15 @@ fn coerce_unsized() { // This is not okay. double_access(&mut a, &a); - //[lxl]~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] - //[nll]~^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] - //[g2p]~^^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] + //[lxl]~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] + //[nll]~^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] + //[g2p]~^^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] + //[ast]~^^^^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] // But this is okay. a.m(a.i(10)); + //[ast]~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable [E0502] + // Above error is an expected limitation of AST borrowck } struct I(i32); @@ -168,14 +173,16 @@ impl IndexMut for I { fn coerce_index_op() { let mut i = I(10); i[i[3]] = 4; - //[lxl]~^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] - //[nll]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] + //[lxl]~^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] + //[nll]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] + //[ast]~^^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] i[3] = i[4]; i[i[3]] = i[4]; - //[lxl]~^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] - //[nll]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] + //[lxl]~^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] + //[nll]~^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] + //[ast]~^^^ ERROR cannot borrow `i` as immutable because it is also borrowed as mutable [E0502] } fn main() { @@ -183,6 +190,8 @@ fn main() { // As a reminder, this is the basic case we want to ensure we handle. let mut v = vec![1, 2, 3]; v.push(v.len()); + //[ast]~^ ERROR cannot borrow `v` as immutable because it is also borrowed as mutable [E0502] + // Error above is an expected limitation of AST borrowck // (as a rule, pnkfelix does not like to write tests with dead code.) @@ -192,9 +201,13 @@ fn main() { let mut s = S; s.m(s.i(10)); + //[ast]~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable [E0502] + // Error above is an expected limitation of AST borrowck let mut t = T; t.m(t.i(10)); + //[ast]~^ ERROR cannot borrow `t` as immutable because it is also borrowed as mutable [E0502] + // Error above is an expected limitation of AST borrowck coerce_unsized(); coerce_index_op(); diff --git a/src/test/ui/borrowck/two-phase-method-receivers.rs b/src/test/ui/borrowck/two-phase-method-receivers.rs new file mode 100644 index 000000000000..e690263a916f --- /dev/null +++ b/src/test/ui/borrowck/two-phase-method-receivers.rs @@ -0,0 +1,29 @@ +// 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. + +// revisions: lxl nll +//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows +//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll + +// run-pass + +struct Foo<'a> { + x: &'a i32 +} + +impl<'a> Foo<'a> { + fn method(&mut self, _: &i32) { + } +} + +fn main() { + let a = &mut Foo { x: &22 }; + Foo::method(a, a.x); +} From 02b5851258c5a0db32d1c735d1c29e5e56f45ed1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 24 Mar 2018 19:15:12 -0700 Subject: [PATCH 602/830] Polyfill LLVMBuildExactUDiv It was added 32 days after LLVM 3.9 shipped. --- src/rustllvm/RustWrapper.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index a5644d6f9e2e..e815d151aeba 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1492,3 +1492,11 @@ LLVMRustBuildVectorReduceFMax(LLVMBuilderRef, LLVMValueRef, bool) { return nullptr; } #endif + +#if LLVM_VERSION_LT(4, 0) +extern "C" LLVMValueRef +LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name) { + return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name)); +} +#endif From 8334977dcffbd538fbd1457555ea3d80cc5eb64b Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 24 Mar 2018 23:35:16 -0400 Subject: [PATCH 603/830] Fix incorrect lower bounds --- src/libcore/char.rs | 7 ++++++- src/libcore/iter/traits.rs | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 2f56238a4638..4420eff06ed2 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -905,7 +905,12 @@ impl> Iterator for DecodeUtf8 { #[inline] fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() + let len = self.iter.len(); + + // A code point is at most 4 bytes long. + let min_code_points = len / 4; + + (min_code_points, Some(len)) } } diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 5e4622f804af..c3aebc4fb23c 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -903,7 +903,12 @@ impl Iterator for ResultShunt } fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + if self.error.is_some() { + (0, Some(0)) + } else { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } } From 4a097ea53251e59063cf5bdc9901f0313664f90e Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 24 Mar 2018 20:37:31 -0700 Subject: [PATCH 604/830] Documentation and naming improvements --- src/libcore/ptr.rs | 48 +++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index cbd45bb6a39e..3fc8421d3b04 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -669,7 +669,7 @@ impl *const T { /// `mem::size_of::()` then the result of the division is rounded towards /// zero. /// - /// This function returns `None` if `T` is a zero-sized typed. + /// This function returns `None` if `T` is a zero-sized type. /// /// # Examples /// @@ -719,7 +719,7 @@ impl *const T { /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. /// /// * The distance between the pointers, in bytes, must be an exact multiple - /// of the size of `T` and `T` must not be a Zero-Sized Type ("ZST"). + /// of the size of `T`. /// /// * The distance being in bounds cannot rely on "wrapping around" the address space. /// @@ -740,6 +740,10 @@ impl *const T { /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// # Panics + /// + /// This function panics if `T` is a Zero-Sized Type ("ZST"). + /// /// # Examples /// /// Basic usage: @@ -759,12 +763,14 @@ impl *const T { /// ``` #[unstable(feature = "ptr_offset_from", issue = "41079")] #[inline] - pub unsafe fn offset_from(self, other: *const T) -> isize where T: Sized { + pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized { let pointee_size = mem::size_of::(); assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize); - // FIXME: can this be nuw/nsw? - let d = isize::wrapping_sub(self as _, other as _); + // This is the same sequence that Clang emits for pointer subtraction. + // It can be neither `nsw` nor `nuw` because the input is treated as + // unsigned but then the output is treated as signed, so neither works. + let d = isize::wrapping_sub(self as _, origin as _); intrinsics::exact_div(d, pointee_size as _) } @@ -775,9 +781,13 @@ impl *const T { /// `mem::size_of::()` then the result of the division is rounded towards /// zero. /// + /// Though this method is safe for any two pointers, note that its result + /// will be mostly useless if the two pointers aren't into the same allocated + /// object, for example if they point to two different local variables. + /// /// # Panics /// - /// This function panics if `T` is a zero-sized typed. + /// This function panics if `T` is a zero-sized type. /// /// # Examples /// @@ -800,11 +810,11 @@ impl *const T { /// ``` #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")] #[inline] - pub fn wrapping_offset_from(self, other: *const T) -> isize where T: Sized { + pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized { let pointee_size = mem::size_of::(); assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize); - let d = isize::wrapping_sub(self as _, other as _); + let d = isize::wrapping_sub(self as _, origin as _); d.wrapping_div(pointee_size as _) } @@ -1424,7 +1434,7 @@ impl *mut T { /// `mem::size_of::()` then the result of the division is rounded towards /// zero. /// - /// This function returns `None` if `T` is a zero-sized typed. + /// This function returns `None` if `T` is a zero-sized type. /// /// # Examples /// @@ -1474,7 +1484,7 @@ impl *mut T { /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`. /// /// * The distance between the pointers, in bytes, must be an exact multiple - /// of the size of `T` and `T` must not be a Zero-Sized Type ("ZST"). + /// of the size of `T`. /// /// * The distance being in bounds cannot rely on "wrapping around" the address space. /// @@ -1495,6 +1505,10 @@ impl *mut T { /// difficult to satisfy. The only advantage of this method is that it /// enables more aggressive compiler optimizations. /// + /// # Panics + /// + /// This function panics if `T` is a Zero-Sized Type ("ZST"). + /// /// # Examples /// /// Basic usage: @@ -1514,8 +1528,8 @@ impl *mut T { /// ``` #[unstable(feature = "ptr_offset_from", issue = "41079")] #[inline] - pub unsafe fn offset_from(self, other: *const T) -> isize where T: Sized { - (self as *const T).offset_from(other) + pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized { + (self as *const T).offset_from(origin) } /// Calculates the distance between two pointers. The returned value is in @@ -1525,9 +1539,13 @@ impl *mut T { /// `mem::size_of::()` then the result of the division is rounded towards /// zero. /// + /// Though this method is safe for any two pointers, note that its result + /// will be mostly useless if the two pointers aren't into the same allocated + /// object, for example if they point to two different local variables. + /// /// # Panics /// - /// This function panics if `T` is a zero-sized typed. + /// This function panics if `T` is a zero-sized type. /// /// # Examples /// @@ -1550,8 +1568,8 @@ impl *mut T { /// ``` #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")] #[inline] - pub fn wrapping_offset_from(self, other: *const T) -> isize where T: Sized { - (self as *const T).wrapping_offset_from(other) + pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized { + (self as *const T).wrapping_offset_from(origin) } /// Computes the byte offset that needs to be applied in order to From 62649524b94fb83e2ed472088ea1a0cd87079fd2 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 24 Mar 2018 20:41:20 -0700 Subject: [PATCH 605/830] Fix doctest mutability copy-pasta --- src/libcore/ptr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 3fc8421d3b04..0723fa8a23d9 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1516,7 +1516,7 @@ impl *mut T { /// ``` /// #![feature(ptr_offset_from)] /// - /// let a = [0; 5]; + /// let mut a = [0; 5]; /// let ptr1: *mut i32 = &mut a[1]; /// let ptr2: *mut i32 = &mut a[3]; /// unsafe { @@ -1554,7 +1554,7 @@ impl *mut T { /// ``` /// #![feature(ptr_wrapping_offset_from)] /// - /// let a = [0; 5]; + /// let mut a = [0; 5]; /// let ptr1: *mut i32 = &mut a[1]; /// let ptr2: *mut i32 = &mut a[3]; /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2); From efd04423c3300d79d0430c78602545ddf5b7f415 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 24 Mar 2018 23:41:34 -0400 Subject: [PATCH 606/830] Add backticks --- src/libstd/net/addr.rs | 4 ++-- src/libstd/net/ip.rs | 6 +++--- src/libstd/time.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index 57efc3095fc9..bc2c9f522d3b 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -64,7 +64,7 @@ pub enum SocketAddr { /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// -/// The size of a SocketAddrV4 struct may vary depending on the target operating +/// The size of a `SocketAddrV4` struct may vary depending on the target operating /// system. /// /// [IETF RFC 793]: https://tools.ietf.org/html/rfc793 @@ -94,7 +94,7 @@ pub struct SocketAddrV4 { inner: c::sockaddr_in } /// /// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses. /// -/// The size of a SocketAddrV6 struct may vary depending on the target operating +/// The size of a `SocketAddrV6` struct may vary depending on the target operating /// system. /// /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3 diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 67b9e7a2f9d6..031fae6d59bf 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -26,7 +26,7 @@ use sys_common::{AsInner, FromInner}; /// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their /// respective documentation for more details. /// -/// The size of an IpAddr instance may vary depending on the target operating +/// The size of an `IpAddr` instance may vary depending on the target operating /// system. /// /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html @@ -64,7 +64,7 @@ pub enum IpAddr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// -/// The size of an Ipv4Addr struct may vary depending on the target operating +/// The size of an `Ipv4Addr` struct may vary depending on the target operating /// system. /// /// [IETF RFC 791]: https://tools.ietf.org/html/rfc791 @@ -99,7 +99,7 @@ pub struct Ipv4Addr { /// /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses. /// -/// The size of an Ipv6Addr struct may vary depending on the target operating +/// The size of an `Ipv6Addr` struct may vary depending on the target operating /// system. /// /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291 diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 4e08301fe05b..7256ac43e27e 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -49,7 +49,7 @@ pub use core::time::Duration; /// allows measuring the duration between two instants (or comparing two /// instants). /// -/// The size of an Instant struct may vary depending on the target operating +/// The size of an `Instant` struct may vary depending on the target operating /// system. /// /// Example: @@ -91,7 +91,7 @@ pub struct Instant(time::Instant); /// fixed point in time, a `SystemTime` can be converted to a human-readable time, /// or perhaps some other string representation. /// -/// The size of a SystemTime struct may vary depending on the target operating +/// The size of a `SystemTime` struct may vary depending on the target operating /// system. /// /// [`Instant`]: ../../std/time/struct.Instant.html From a907d9aad20a728e02897f660995b07646658a44 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 24 Mar 2018 23:45:20 -0400 Subject: [PATCH 607/830] Fix syntax error --- src/libcore/char.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 4420eff06ed2..b8d1f91c2479 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -905,7 +905,7 @@ impl> Iterator for DecodeUtf8 { #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.iter.len(); + let len = self.0.len(); // A code point is at most 4 bytes long. let min_code_points = len / 4; From 01af316867dd6477072e0feae2d7cead2229ebfd Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 25 Mar 2018 00:00:18 -0400 Subject: [PATCH 608/830] Fix incorrect copy-pasted code It's late. --- src/libcore/char.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index b8d1f91c2479..c74b23da39cf 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -905,12 +905,12 @@ impl> Iterator for DecodeUtf8 { #[inline] fn size_hint(&self) -> (usize, Option) { - let len = self.0.len(); + let (lower, upper) = self.0.size_hint(); // A code point is at most 4 bytes long. - let min_code_points = len / 4; + let min_code_points = lower / 4; - (min_code_points, Some(len)) + (min_code_points, upper) } } From f198b0acf512458bdbe5079d12414ff94b03f7ac Mon Sep 17 00:00:00 2001 From: Sean Silva Date: Sat, 24 Mar 2018 22:31:17 -0700 Subject: [PATCH 609/830] Fix confusing doc for `scan` The comment "the value passed on to the next iteration" confused me since it sounded more like what Haskell's [scanl](http://hackage.haskell.org/package/base-4.11.0.0/docs/Prelude.html#v:scanl) does where the closure's return value serves as both the "yielded value" *and* the new value of the "state". I tried changing the example to make it clear that the closure's return value is decoupled from the state argument. --- src/libcore/iter/iterator.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 2cfbc0922934..31f77f92435d 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -974,13 +974,13 @@ pub trait Iterator { /// // each iteration, we'll multiply the state by the element /// *state = *state * x; /// - /// // the value passed on to the next iteration - /// Some(*state) + /// // then, we'll yield the negation of the state + /// Some(-*state) /// }); /// - /// assert_eq!(iter.next(), Some(1)); - /// assert_eq!(iter.next(), Some(2)); - /// assert_eq!(iter.next(), Some(6)); + /// assert_eq!(iter.next(), Some(-1)); + /// assert_eq!(iter.next(), Some(-2)); + /// assert_eq!(iter.next(), Some(-6)); /// assert_eq!(iter.next(), None); /// ``` #[inline] From f9661126ca1904d3712eb19d24a5880c6dc7b8ed Mon Sep 17 00:00:00 2001 From: Alexander Ronald Altman Date: Sun, 25 Mar 2018 00:15:50 -0500 Subject: [PATCH 610/830] Minor formatting consistency fix. --- src/libstd/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index c877bf6aa35c..92e9f48f7ebe 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -1444,7 +1444,7 @@ pub fn id() -> u32 { #[unstable(feature = "termination_trait_lib", issue = "43301")] #[rustc_on_unimplemented( message="`main` has invalid return type `{Self}`", - label="`main` can only return types that implement {Termination}")] + label="`main` can only return types that implement `{Termination}`")] pub trait Termination { /// Is called to get the representation of the value as status code. /// This status code is returned to the operating system. From 9e6991ce498e81b25854263696138f3b465865d7 Mon Sep 17 00:00:00 2001 From: Alexander Ronald Altman Date: Sun, 25 Mar 2018 01:29:57 -0500 Subject: [PATCH 611/830] Modify tests --- .../rfc-1937-termination-trait/termination-trait-main-i32.rs | 2 +- .../termination-trait-main-wrong-type.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs index 0e6ddf7c92f1..49f5621de1b2 100644 --- a/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs +++ b/src/test/compile-fail/rfc-1937-termination-trait/termination-trait-main-i32.rs @@ -10,7 +10,7 @@ fn main() -> i32 { //~^ ERROR `main` has invalid return type `i32` -//~| NOTE `main` can only return types that implement std::process::Termination +//~| NOTE `main` can only return types that implement `std::process::Termination` //~| HELP consider using `()`, or a `Result` 0 } diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr index 5109d9275c58..e53872593843 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-main-wrong-type.stderr @@ -2,7 +2,7 @@ error[E0277]: `main` has invalid return type `char` --> $DIR/termination-trait-main-wrong-type.rs:11:14 | LL | fn main() -> char { //~ ERROR - | ^^^^ `main` can only return types that implement std::process::Termination + | ^^^^ `main` can only return types that implement `std::process::Termination` | = help: consider using `()`, or a `Result` From d39b02c2c9e8aa472ab47ccfb5de63bc616daf62 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 25 Mar 2018 16:08:03 +0900 Subject: [PATCH 612/830] Use a more conservative way to deinit stack guard --- src/libstd/sys/unix/thread.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index b9ec0d4a4033..6064b55489ef 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -223,8 +223,8 @@ pub mod guard { #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc; - use libc::{mmap, munmap}; - use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; + use libc::mmap; + use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; use ops::Range; use sys::os; @@ -347,9 +347,19 @@ pub mod guard { pub unsafe fn deinit() { if !cfg!(target_os = "linux") { if let Some(stackaddr) = get_stack_start_aligned() { - // Undo the guard page mapping. - if munmap(stackaddr, PAGE_SIZE) != 0 { - panic!("unable to deallocate the guard page"); + // Remove the protection on the guard page. + // FIXME: we cannot unmap the page, because when we mmap() + // above it may be already mapped by the OS, which we can't + // detect from mmap()'s return value. If we unmap this page, + // it will lead to failure growing stack size on platforms like + // macOS. Instead, just restore the page to a writable state. + // This ain't Linux, so we probably don't need to care about + // execstack. + let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); + + if result != stackaddr || result == MAP_FAILED { + panic!("unable to reset the guard page"); } } } From 23013c791c70a297b430e9d1c0408493705d36e0 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sun, 25 Mar 2018 14:19:27 +0200 Subject: [PATCH 613/830] update wording as per feedback --- src/libcore/sync/atomic.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index fd6e5140a099..c1f6c492e983 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -207,7 +207,9 @@ pub enum Ordering { Acquire, /// Has the effects of both [`Acquire`] and [`Release`] together. /// - /// If you only are concerned about a load or a store, consider using one of those instead. + /// This ordering is only applicable for operations that combine both loads and stores. + /// + /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering. /// /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire /// [`Release`]: http://llvm.org/docs/Atomics.html#release From 1e1d907e6a407a474d46af343678e45c4eb327f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 25 Mar 2018 23:17:47 +0200 Subject: [PATCH 614/830] pgo: Blindly try to fix Windows build. --- src/libprofiler_builtins/build.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 6c7407760dfa..8d6c7d68dfe2 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -43,6 +43,8 @@ fn main() { cfg.define("strdup", Some("_strdup")); cfg.define("open", Some("_open")); cfg.define("fdopen", Some("_fdopen")); + cfg.define("getpid", Some("_getpid")); + cfg.define("fileno", Some("_fileno")); } else { // Turn off various features of gcc and such, mostly copying // compiler-rt's build system already From fbec3ec5a78747ee458518e4be7cfe1b5eac9e3b Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Mon, 25 Dec 2017 00:00:04 +0000 Subject: [PATCH 615/830] Implement get_key_value for HashMap, BTreeMap --- src/liballoc/btree/map.rs | 27 +++++++++++++++++++++++++++ src/libstd/collections/hash/map.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index ed9c8c18f0d6..cada190032aa 100644 --- a/src/liballoc/btree/map.rs +++ b/src/liballoc/btree/map.rs @@ -576,6 +576,33 @@ impl BTreeMap { } } + /// Returns the key-value pair corresponding to the supplied key. + /// + /// The supplied key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// + /// # Examples + /// + /// ``` + /// #![feature(map_get_key_value)] + /// use std::collections::BTreeMap; + /// + /// let mut map = BTreeMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); + /// assert_eq!(map.get_key_value(&2), None); + /// ``` + #[unstable(feature = "map_get_key_value", issue = "49347")] + pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> + where K: Borrow, + Q: Ord + { + match search::search_tree(self.root.as_ref(), k) { + Found(handle) => Some(handle.into_kv()), + GoDown(_) => None, + } + } + /// Returns `true` if the map contains a value for the specified key. /// /// The key may be any borrowed form of the map's key type, but the ordering diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index b18b38ec3024..f0bb781411fb 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1184,6 +1184,34 @@ impl HashMap self.search(k).map(|bucket| bucket.into_refs().1) } + /// Returns the key-value pair corresponding to the supplied key. + /// + /// The supplied key may be any borrowed form of the map's key type, but + /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for + /// the key type. + /// + /// [`Eq`]: ../../std/cmp/trait.Eq.html + /// [`Hash`]: ../../std/hash/trait.Hash.html + /// + /// # Examples + /// + /// ``` + /// #![feature(map_get_key_value)] + /// use std::collections::HashMap; + /// + /// let mut map = HashMap::new(); + /// map.insert(1, "a"); + /// assert_eq!(map.get_key_value(&1), Some((&1, &"a"))); + /// assert_eq!(map.get_key_value(&2), None); + /// ``` + #[unstable(feature = "map_get_key_value", issue = "49347")] + pub fn get_key_value(&self, k: &Q) -> Option<(&K, &V)> + where K: Borrow, + Q: Hash + Eq + { + self.search(k).map(|bucket| bucket.into_refs()) + } + /// Returns true if the map contains a value for the specified key. /// /// The key may be any borrowed form of the map's key type, but From c393db67baf3a15ec61351ffb0e3811e07b8a467 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 21 Mar 2018 17:44:21 -0700 Subject: [PATCH 616/830] Stabilize universal_impl_trait --- .../language-features/universal-impl-trait.md | 32 ------------------- src/librustc/hir/lowering.rs | 11 ------- src/librustc/lib.rs | 2 +- src/librustc_data_structures/lib.rs | 2 +- src/librustc_typeck/diagnostics.rs | 1 - src/libsyntax/feature_gate.rs | 5 ++- .../impl-trait/impl-generic-mismatch-ab.rs | 1 - .../impl-trait/impl-generic-mismatch.rs | 1 - .../compile-fail/impl-trait/where-allowed.rs | 2 +- .../run-pass/impl-trait/example-calendar.rs | 1 - src/test/run-pass/impl-trait/lifetimes.rs | 2 +- .../impl-trait/universal_hrtb_anon.rs | 2 -- .../impl-trait/universal_hrtb_named.rs | 2 -- .../universal_in_adt_in_parameters.rs | 1 - .../universal_in_impl_trait_in_parameters.rs | 1 - .../universal_in_trait_defn_parameters.rs | 2 -- .../impl-trait/universal_multiple_bounds.rs | 2 -- src/test/run-pass/in-band-lifetimes.rs | 2 +- src/test/run-pass/issue-46959.rs | 1 - src/test/rustdoc/issue-46976.rs | 1 - src/test/ui/feature-gate-universal.rs | 16 ---------- src/test/ui/feature-gate-universal.stderr | 11 ------- .../impl-trait/universal-mismatched-type.rs | 2 -- .../universal-mismatched-type.stderr | 2 +- .../impl-trait/universal-two-impl-traits.rs | 2 -- .../universal-two-impl-traits.stderr | 2 +- .../ui/impl-trait/universal_wrong_bounds.rs | 2 -- .../impl-trait/universal_wrong_bounds.stderr | 6 ++-- src/test/ui/impl_trait_projections.rs | 2 +- src/test/ui/in-band-lifetimes/E0687_where.rs | 2 +- src/test/ui/nested_impl_trait.rs | 2 +- 31 files changed, 15 insertions(+), 108 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/universal-impl-trait.md delete mode 100644 src/test/ui/feature-gate-universal.rs delete mode 100644 src/test/ui/feature-gate-universal.stderr diff --git a/src/doc/unstable-book/src/language-features/universal-impl-trait.md b/src/doc/unstable-book/src/language-features/universal-impl-trait.md deleted file mode 100644 index 6b3c5e92720d..000000000000 --- a/src/doc/unstable-book/src/language-features/universal-impl-trait.md +++ /dev/null @@ -1,32 +0,0 @@ -# `universal_impl_trait` - -The tracking issue for this feature is: [#34511]. - -[#34511]: https://github.com/rust-lang/rust/issues/34511 - --------------------- - -The `universal_impl_trait` feature extends the [`conservative_impl_trait`] -feature allowing the `impl Trait` syntax in arguments (universal -quantification). - -[`conservative_impl_trait`]: ./language-features/conservative-impl-trait.html - -## Examples - -```rust -#![feature(universal_impl_trait)] -use std::ops::Not; - -fn any_zero(values: impl IntoIterator) -> bool { - for val in values { if val == 0 { return true; } } - false -} - -fn main() { - let test1 = -5..; - let test2 = vec![1, 8, 42, -87, 60]; - assert!(any_zero(test1)); - assert!(bool::not(any_zero(test2))); -} -``` diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index ad848949f624..2ae102fbef03 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1143,17 +1143,6 @@ impl<'a> LoweringContext<'a> { ) } ImplTraitContext::Universal(def_id) => { - let has_feature = self.sess.features_untracked().universal_impl_trait; - if !t.span.allows_unstable() && !has_feature { - emit_feature_err( - &self.sess.parse_sess, - "universal_impl_trait", - t.span, - GateIssue::Language, - "`impl Trait` in argument position is experimental", - ); - } - let def_node_id = self.next_id().node_id; // Add a definition for the in-band TyParam diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index a759ce59cb64..d133352de078 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -70,7 +70,7 @@ #![feature(specialization)] #![feature(unboxed_closures)] #![feature(underscore_lifetimes)] -#![feature(universal_impl_trait)] +#![cfg_attr(stage0, feature(universal_impl_trait))] #![feature(trace_macros)] #![feature(trusted_len)] #![feature(catch_expr)] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index bf0b3726bb30..05bd3ae845fb 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -34,7 +34,7 @@ #![feature(underscore_lifetimes)] #![feature(macro_vis_matcher)] #![feature(allow_internal_unstable)] -#![feature(universal_impl_trait)] +#![cfg_attr(stage0, feature(universal_impl_trait))] #![cfg_attr(unix, feature(libc))] #![cfg_attr(test, feature(test))] diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index f5337118e30d..1f882676f61a 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4600,7 +4600,6 @@ This error indicates that there is a mismatch between generic parameters and impl Trait parameters in a trait declaration versus its impl. ```compile_fail,E0643 -#![feature(universal_impl_trait)] trait Foo { fn foo(&self, _: &impl Iterator); } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e69dace0c705..db900ed6e355 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -279,9 +279,6 @@ declare_features! ( // Allows `impl Trait` in function return types. (active, conservative_impl_trait, "1.12.0", Some(34511), None), - // Allows `impl Trait` in function arguments. - (active, universal_impl_trait, "1.23.0", Some(34511), None), - // Allows exhaustive pattern matching on types that contain uninhabited types. (active, exhaustive_patterns, "1.13.0", None, None), @@ -566,6 +563,8 @@ declare_features! ( // Copy/Clone closures (RFC 2132) (accepted, clone_closures, "1.26.0", Some(44490), None), (accepted, copy_closures, "1.26.0", Some(44490), None), + // Allows `impl Trait` in function arguments. + (accepted, universal_impl_trait, "1.26.0", Some(34511), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs b/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs index 43b47e9e915f..23549918ff1b 100644 --- a/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs +++ b/src/test/compile-fail/impl-trait/impl-generic-mismatch-ab.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] use std::fmt::Debug; trait Foo { diff --git a/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs b/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs index a95da61aa4c0..eea7ca209578 100644 --- a/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs +++ b/src/test/compile-fail/impl-trait/impl-generic-mismatch.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] use std::fmt::Debug; trait Foo { diff --git a/src/test/compile-fail/impl-trait/where-allowed.rs b/src/test/compile-fail/impl-trait/where-allowed.rs index 52c5471681df..c93bcf7f390e 100644 --- a/src/test/compile-fail/impl-trait/where-allowed.rs +++ b/src/test/compile-fail/impl-trait/where-allowed.rs @@ -10,7 +10,7 @@ //! A simple test for testing many permutations of allowedness of //! impl Trait -#![feature(conservative_impl_trait, universal_impl_trait, dyn_trait)] +#![feature(conservative_impl_trait, dyn_trait)] use std::fmt::Debug; // Allowed diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs index aca100591dde..d1e2b471d9ae 100644 --- a/src/test/run-pass/impl-trait/example-calendar.rs +++ b/src/test/run-pass/impl-trait/example-calendar.rs @@ -12,7 +12,6 @@ //[nll] compile-flags: -Znll -Zborrowck=mir #![feature(conservative_impl_trait, - universal_impl_trait, fn_traits, step_trait, unboxed_closures, diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs index fcad23926fc0..c589e23f9504 100644 --- a/src/test/run-pass/impl-trait/lifetimes.rs +++ b/src/test/run-pass/impl-trait/lifetimes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, underscore_lifetimes, universal_impl_trait)] +#![feature(conservative_impl_trait, underscore_lifetimes)] #![allow(warnings)] use std::fmt::Debug; diff --git a/src/test/run-pass/impl-trait/universal_hrtb_anon.rs b/src/test/run-pass/impl-trait/universal_hrtb_anon.rs index 48874ef41de5..9fc74757da0b 100644 --- a/src/test/run-pass/impl-trait/universal_hrtb_anon.rs +++ b/src/test/run-pass/impl-trait/universal_hrtb_anon.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] - fn hrtb(f: impl Fn(&u32) -> u32) -> u32 { f(&22) + f(&44) } diff --git a/src/test/run-pass/impl-trait/universal_hrtb_named.rs b/src/test/run-pass/impl-trait/universal_hrtb_named.rs index 95147a542005..3aefc79ebf78 100644 --- a/src/test/run-pass/impl-trait/universal_hrtb_named.rs +++ b/src/test/run-pass/impl-trait/universal_hrtb_named.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] - fn hrtb(f: impl for<'a> Fn(&'a u32) -> &'a u32) -> u32 { f(&22) + f(&44) } diff --git a/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs b/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs index d0f18575297b..57452a2e475c 100644 --- a/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs +++ b/src/test/run-pass/impl-trait/universal_in_adt_in_parameters.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] use std::fmt::Display; fn check_display_eq(iter: &Vec) { diff --git a/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs b/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs index ccf24b77a6b7..fea946f12584 100644 --- a/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs +++ b/src/test/run-pass/impl-trait/universal_in_impl_trait_in_parameters.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] use std::fmt::Display; fn check_display_eq(iter: impl IntoIterator) { diff --git a/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs b/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs index af0201b5f871..d3611e02e025 100644 --- a/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs +++ b/src/test/run-pass/impl-trait/universal_in_trait_defn_parameters.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] - use std::fmt::Debug; trait InTraitDefnParameters { diff --git a/src/test/run-pass/impl-trait/universal_multiple_bounds.rs b/src/test/run-pass/impl-trait/universal_multiple_bounds.rs index bb332c0c96cb..594207feb09a 100644 --- a/src/test/run-pass/impl-trait/universal_multiple_bounds.rs +++ b/src/test/run-pass/impl-trait/universal_multiple_bounds.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] - use std::fmt::Display; fn foo(f: impl Display + Clone) -> String { diff --git a/src/test/run-pass/in-band-lifetimes.rs b/src/test/run-pass/in-band-lifetimes.rs index 95cc3c3759e6..b5b73675ca72 100644 --- a/src/test/run-pass/in-band-lifetimes.rs +++ b/src/test/run-pass/in-band-lifetimes.rs @@ -9,7 +9,7 @@ // except according to those terms. #![allow(warnings)] -#![feature(in_band_lifetimes, universal_impl_trait, conservative_impl_trait)] +#![feature(in_band_lifetimes, conservative_impl_trait)] fn foo(x: &'x u8) -> &'x u8 { x } fn foo2(x: &'a u8, y: &u8) -> &'a u8 { x } diff --git a/src/test/run-pass/issue-46959.rs b/src/test/run-pass/issue-46959.rs index 0826f5e49238..876b8c0a1d38 100644 --- a/src/test/run-pass/issue-46959.rs +++ b/src/test/run-pass/issue-46959.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] #![feature(conservative_impl_trait)] #![deny(non_camel_case_types)] diff --git a/src/test/rustdoc/issue-46976.rs b/src/test/rustdoc/issue-46976.rs index 0df80fe3bd77..ce09f62a552d 100644 --- a/src/test/rustdoc/issue-46976.rs +++ b/src/test/rustdoc/issue-46976.rs @@ -8,5 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] pub fn ice(f: impl Fn()) {} diff --git a/src/test/ui/feature-gate-universal.rs b/src/test/ui/feature-gate-universal.rs deleted file mode 100644 index e5bdf3a42eb3..000000000000 --- a/src/test/ui/feature-gate-universal.rs +++ /dev/null @@ -1,16 +0,0 @@ -// 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. - -// gate-test-universal_impl_trait - -fn foo(x: impl std::fmt::Debug) { print!("{:?}", x); } -//~^ ERROR `impl Trait` in argument position is experimental - -fn main() {} diff --git a/src/test/ui/feature-gate-universal.stderr b/src/test/ui/feature-gate-universal.stderr deleted file mode 100644 index dc1a6b29c72c..000000000000 --- a/src/test/ui/feature-gate-universal.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: `impl Trait` in argument position is experimental (see issue #34511) - --> $DIR/feature-gate-universal.rs:13:11 - | -LL | fn foo(x: impl std::fmt::Debug) { print!("{:?}", x); } - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(universal_impl_trait)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/impl-trait/universal-mismatched-type.rs b/src/test/ui/impl-trait/universal-mismatched-type.rs index 00fc22ff0d85..6a62eb36c303 100644 --- a/src/test/ui/impl-trait/universal-mismatched-type.rs +++ b/src/test/ui/impl-trait/universal-mismatched-type.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] - use std::fmt::Debug; fn foo(x: impl Debug) -> String { diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr index 64f1aff13bdb..031db511ff30 100644 --- a/src/test/ui/impl-trait/universal-mismatched-type.stderr +++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/universal-mismatched-type.rs:16:5 + --> $DIR/universal-mismatched-type.rs:14:5 | LL | fn foo(x: impl Debug) -> String { | ------ expected `std::string::String` because of return type diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.rs b/src/test/ui/impl-trait/universal-two-impl-traits.rs index 9a4847b56062..5ecef1fee65d 100644 --- a/src/test/ui/impl-trait/universal-two-impl-traits.rs +++ b/src/test/ui/impl-trait/universal-two-impl-traits.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] - use std::fmt::Debug; fn foo(x: impl Debug, y: impl Debug) -> String { diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr index 61f52ff25fb1..ed406895fc69 100644 --- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr +++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/universal-two-impl-traits.rs:17:9 + --> $DIR/universal-two-impl-traits.rs:15:9 | LL | a = y; //~ ERROR mismatched | ^ expected type parameter, found a different type parameter diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.rs b/src/test/ui/impl-trait/universal_wrong_bounds.rs index 36d9f615c5f5..a5e948223fb1 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.rs +++ b/src/test/ui/impl-trait/universal_wrong_bounds.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(universal_impl_trait)] - use std::fmt::Display; fn foo(f: impl Display + Clone) -> String { diff --git a/src/test/ui/impl-trait/universal_wrong_bounds.stderr b/src/test/ui/impl-trait/universal_wrong_bounds.stderr index 3cc0bebe8165..02ac4707bc55 100644 --- a/src/test/ui/impl-trait/universal_wrong_bounds.stderr +++ b/src/test/ui/impl-trait/universal_wrong_bounds.stderr @@ -1,11 +1,11 @@ error[E0425]: cannot find function `wants_clone` in this scope - --> $DIR/universal_wrong_bounds.rs:18:5 + --> $DIR/universal_wrong_bounds.rs:16:5 | LL | wants_clone(f); //~ ERROR cannot find | ^^^^^^^^^^^ did you mean `wants_cone`? error[E0405]: cannot find trait `Debug` in this scope - --> $DIR/universal_wrong_bounds.rs:21:24 + --> $DIR/universal_wrong_bounds.rs:19:24 | LL | fn wants_debug(g: impl Debug) { } //~ ERROR cannot find | ^^^^^ not found in this scope @@ -15,7 +15,7 @@ LL | use std::fmt::Debug; | error[E0405]: cannot find trait `Debug` in this scope - --> $DIR/universal_wrong_bounds.rs:22:26 + --> $DIR/universal_wrong_bounds.rs:20:26 | LL | fn wants_display(g: impl Debug) { } //~ ERROR cannot find | ^^^^^ not found in this scope diff --git a/src/test/ui/impl_trait_projections.rs b/src/test/ui/impl_trait_projections.rs index f69a78b1450f..05e88bf848d4 100644 --- a/src/test/ui/impl_trait_projections.rs +++ b/src/test/ui/impl_trait_projections.rs @@ -7,7 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(dyn_trait, conservative_impl_trait, universal_impl_trait)] +#![feature(dyn_trait, conservative_impl_trait)] use std::fmt::Debug; use std::option; diff --git a/src/test/ui/in-band-lifetimes/E0687_where.rs b/src/test/ui/in-band-lifetimes/E0687_where.rs index ac6755877200..c1b268eac701 100644 --- a/src/test/ui/in-band-lifetimes/E0687_where.rs +++ b/src/test/ui/in-band-lifetimes/E0687_where.rs @@ -9,7 +9,7 @@ // except according to those terms. #![allow(warnings)] -#![feature(in_band_lifetimes, universal_impl_trait)] +#![feature(in_band_lifetimes)] fn bar(x: &F) where F: Fn(&'a u32) {} //~ ERROR must be explicitly diff --git a/src/test/ui/nested_impl_trait.rs b/src/test/ui/nested_impl_trait.rs index f6302c0f3b3e..0fb1222d7973 100644 --- a/src/test/ui/nested_impl_trait.rs +++ b/src/test/ui/nested_impl_trait.rs @@ -7,7 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, universal_impl_trait)] +#![feature(conservative_impl_trait)] use std::fmt::Debug; From bd286413443c31c99330358967fb0159de8a3589 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 19 Mar 2018 10:58:30 -0700 Subject: [PATCH 617/830] rustbuild: Disable docs on cross-compiled builds This commit disables building documentation on cross-compiled compilers, for example ARM/MIPS/PowerPC/etc. Currently I believe we're not getting much use out of these documentation artifacts and they often take 10-15 minutes total to build as it requires building rustdoc/rustbook and then also generating all the documentation, especially for the reference and the book itself. In an effort to cut down on the amount of work that we're doing on dist CI builders in light of recent timeouts this was some relatively low hanging fruit to cut which in theory won't have much impact on the ecosystem in the hopes that the documentation isn't used too heavily anyway. While initial analysis in #48827 showed only shaving 5 minutes off local builds the same 5 minute conclusion was drawn from #48826 which ended up having nearly a half-hour impact on the bots. In that sense I'm hoping that we can land this and test out what happens on CI to see how it affects timing. Note that all tier 1 platforms, Windows, Mac, and Linux, will continue to generate documentation. --- src/bootstrap/compile.rs | 11 +++++------ src/bootstrap/tool.rs | 4 ++++ src/ci/docker/dist-aarch64-linux/Dockerfile | 2 +- src/ci/docker/dist-android/Dockerfile | 3 ++- 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-i586-gnu-i586-i686-musl/Dockerfile | 3 ++- src/ci/docker/dist-i686-freebsd/Dockerfile | 2 +- src/ci/docker/dist-mips-linux/Dockerfile | 2 +- src/ci/docker/dist-mips64-linux/Dockerfile | 2 +- src/ci/docker/dist-mips64el-linux/Dockerfile | 2 +- src/ci/docker/dist-mipsel-linux/Dockerfile | 2 +- src/ci/docker/dist-powerpc-linux/Dockerfile | 2 +- src/ci/docker/dist-powerpc64-linux/Dockerfile | 2 +- src/ci/docker/dist-powerpc64le-linux/Dockerfile | 2 +- src/ci/docker/dist-s390x-linux/Dockerfile | 2 +- src/ci/docker/dist-various-1/Dockerfile | 3 ++- src/ci/docker/dist-various-2/Dockerfile | 2 +- src/ci/docker/dist-x86_64-freebsd/Dockerfile | 2 +- src/ci/docker/dist-x86_64-musl/Dockerfile | 3 ++- src/ci/docker/dist-x86_64-netbsd/Dockerfile | 2 +- 22 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index fafa44633818..a1318086af7e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -98,7 +98,7 @@ impl Step for Std { copy_musl_third_party_objects(build, target, &libdir); } - let out_dir = build.stage_out(compiler, Mode::Libstd); + let out_dir = build.cargo_out(compiler, Mode::Libstd, target); build.clear_if_dirty(&out_dir, &builder.rustc(compiler)); let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build"); std_cargo(builder, &compiler, target, &mut cargo); @@ -360,7 +360,7 @@ impl Step for Test { return; } - let out_dir = build.stage_out(compiler, Mode::Libtest); + let out_dir = build.cargo_out(compiler, Mode::Libtest, target); build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build"); test_cargo(build, &compiler, target, &mut cargo); @@ -482,10 +482,9 @@ impl Step for Rustc { compiler: builder.compiler(self.compiler.stage, build.build), target: build.build, }); - - let stage_out = builder.stage_out(compiler, Mode::Librustc); - build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target)); - build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target)); + let cargo_out = builder.cargo_out(compiler, Mode::Librustc, target); + build.clear_if_dirty(&cargo_out, &libstd_stamp(build, compiler, target)); + build.clear_if_dirty(&cargo_out, &libtest_stamp(build, compiler, target)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build"); rustc_cargo(build, &mut cargo); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d308cecb2752..669308c8dd0e 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -338,6 +338,10 @@ impl Step for Rustdoc { }; builder.ensure(compile::Rustc { compiler: build_compiler, target }); + builder.ensure(compile::Rustc { + compiler: build_compiler, + target: builder.build.build, + }); let mut cargo = prepare_tool_cargo(builder, build_compiler, diff --git a/src/ci/docker/dist-aarch64-linux/Dockerfile b/src/ci/docker/dist-aarch64-linux/Dockerfile index dbc319312aa9..cddfa557f6ae 100644 --- a/src/ci/docker/dist-aarch64-linux/Dockerfile +++ b/src/ci/docker/dist-aarch64-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_aarch64_unknown_linux_gnu=aarch64-unknown-linux-gnueabi-gcc \ ENV HOSTS=aarch64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-android/Dockerfile b/src/ci/docker/dist-android/Dockerfile index aa5da136758a..e00c23dac89b 100644 --- a/src/ci/docker/dist-android/Dockerfile +++ b/src/ci/docker/dist-android/Dockerfile @@ -26,7 +26,8 @@ ENV RUST_CONFIGURE_ARGS \ --armv7-linux-androideabi-ndk=/android/ndk/arm-14 \ --i686-linux-android-ndk=/android/ndk/x86-14 \ --aarch64-linux-android-ndk=/android/ndk/arm64-21 \ - --x86_64-linux-android-ndk=/android/ndk/x86_64-21 + --x86_64-linux-android-ndk=/android/ndk/x86_64-21 \ + --disable-docs ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-arm-linux/Dockerfile b/src/ci/docker/dist-arm-linux/Dockerfile index 89f7f85cb3b1..6ddc5c1e04ae 100644 --- a/src/ci/docker/dist-arm-linux/Dockerfile +++ b/src/ci/docker/dist-arm-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_arm_unknown_linux_gnueabi=arm-unknown-linux-gnueabi-gcc \ ENV HOSTS=arm-unknown-linux-gnueabi -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-armhf-linux/Dockerfile b/src/ci/docker/dist-armhf-linux/Dockerfile index e0c1b9a9e858..e4d4b2feeec4 100644 --- a/src/ci/docker/dist-armhf-linux/Dockerfile +++ b/src/ci/docker/dist-armhf-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_arm_unknown_linux_gnueabihf=arm-unknown-linux-gnueabihf-gcc \ ENV HOSTS=arm-unknown-linux-gnueabihf -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-armv7-linux/Dockerfile b/src/ci/docker/dist-armv7-linux/Dockerfile index e7d4f464ffcd..99fe7bd7b8f7 100644 --- a/src/ci/docker/dist-armv7-linux/Dockerfile +++ b/src/ci/docker/dist-armv7-linux/Dockerfile @@ -32,5 +32,5 @@ ENV CC_armv7_unknown_linux_gnueabihf=armv7-unknown-linux-gnueabihf-gcc \ ENV HOSTS=armv7-unknown-linux-gnueabihf -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile index 7bcc649f4aa5..e12bed3abc5a 100644 --- a/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile +++ b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile @@ -32,7 +32,8 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ --musl-root-i586=/musl-i586 \ --musl-root-i686=/musl-i686 \ - --enable-extended + --enable-extended \ + --disable-docs # Newer binutils broke things on some vms/distros (i.e., linking against # unknown relocs disabled by the following flag), so we need to go out of our diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile index 1f595ba7a290..6f6a663a3309 100644 --- a/src/ci/docker/dist-i686-freebsd/Dockerfile +++ b/src/ci/docker/dist-i686-freebsd/Dockerfile @@ -29,5 +29,5 @@ ENV \ ENV HOSTS=i686-unknown-freebsd -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-mips-linux/Dockerfile b/src/ci/docker/dist-mips-linux/Dockerfile index 37ab5bdcce55..466def1f80fb 100644 --- a/src/ci/docker/dist-mips-linux/Dockerfile +++ b/src/ci/docker/dist-mips-linux/Dockerfile @@ -22,5 +22,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mips-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-mips64-linux/Dockerfile b/src/ci/docker/dist-mips64-linux/Dockerfile index a5180780b225..2205b733e99f 100644 --- a/src/ci/docker/dist-mips64-linux/Dockerfile +++ b/src/ci/docker/dist-mips64-linux/Dockerfile @@ -21,5 +21,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mips64-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-mips64el-linux/Dockerfile b/src/ci/docker/dist-mips64el-linux/Dockerfile index d38ed24f6255..f1d9dad46ea3 100644 --- a/src/ci/docker/dist-mips64el-linux/Dockerfile +++ b/src/ci/docker/dist-mips64el-linux/Dockerfile @@ -22,5 +22,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mips64el-unknown-linux-gnuabi64 -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-mipsel-linux/Dockerfile b/src/ci/docker/dist-mipsel-linux/Dockerfile index 491c57ba6773..ee73e29c76e3 100644 --- a/src/ci/docker/dist-mipsel-linux/Dockerfile +++ b/src/ci/docker/dist-mipsel-linux/Dockerfile @@ -21,5 +21,5 @@ RUN sh /scripts/sccache.sh ENV HOSTS=mipsel-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-powerpc-linux/Dockerfile b/src/ci/docker/dist-powerpc-linux/Dockerfile index c503f2af9cda..f03aff060c10 100644 --- a/src/ci/docker/dist-powerpc-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc-linux/Dockerfile @@ -34,7 +34,7 @@ ENV \ ENV HOSTS=powerpc-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # FIXME(#36150) this will fail the bootstrap. Probably means something bad is diff --git a/src/ci/docker/dist-powerpc64-linux/Dockerfile b/src/ci/docker/dist-powerpc64-linux/Dockerfile index 4a3691777360..bb30210c0563 100644 --- a/src/ci/docker/dist-powerpc64-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64-linux/Dockerfile @@ -35,5 +35,5 @@ ENV \ ENV HOSTS=powerpc64-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-powerpc64le-linux/Dockerfile b/src/ci/docker/dist-powerpc64le-linux/Dockerfile index bf6c8b4b7121..ee9e45504835 100644 --- a/src/ci/docker/dist-powerpc64le-linux/Dockerfile +++ b/src/ci/docker/dist-powerpc64le-linux/Dockerfile @@ -32,5 +32,5 @@ ENV \ ENV HOSTS=powerpc64le-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-s390x-linux/Dockerfile b/src/ci/docker/dist-s390x-linux/Dockerfile index a2ebf590bab7..7ba6fe643c2a 100644 --- a/src/ci/docker/dist-s390x-linux/Dockerfile +++ b/src/ci/docker/dist-s390x-linux/Dockerfile @@ -34,5 +34,5 @@ ENV \ ENV HOSTS=s390x-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index a23153645cde..b398e9a3c92e 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -95,7 +95,8 @@ ENV RUST_CONFIGURE_ARGS \ --musl-root-aarch64=/musl-aarch64 \ --musl-root-mips=/musl-mips \ --musl-root-mipsel=/musl-mipsel \ - --enable-emscripten + --enable-emscripten \ + --disable-docs ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile index 4505a60e4639..e8d6c12de447 100644 --- a/src/ci/docker/dist-various-2/Dockerfile +++ b/src/ci/docker/dist-various-2/Dockerfile @@ -55,5 +55,5 @@ ENV TARGETS=$TARGETS,x86_64-sun-solaris ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnux32 ENV TARGETS=$TARGETS,x86_64-unknown-cloudabi -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --target $TARGETS diff --git a/src/ci/docker/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/dist-x86_64-freebsd/Dockerfile index dd595a192051..698b81a92e93 100644 --- a/src/ci/docker/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-freebsd/Dockerfile @@ -29,5 +29,5 @@ ENV \ ENV HOSTS=x86_64-unknown-freebsd -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/dist-x86_64-musl/Dockerfile b/src/ci/docker/dist-x86_64-musl/Dockerfile index 3a9ad178c639..06f8a2fbba83 100644 --- a/src/ci/docker/dist-x86_64-musl/Dockerfile +++ b/src/ci/docker/dist-x86_64-musl/Dockerfile @@ -31,7 +31,8 @@ RUN sh /scripts/sccache.sh ENV RUST_CONFIGURE_ARGS \ --musl-root-x86_64=/musl-x86_64 \ - --enable-extended + --enable-extended \ + --disable-docs # Newer binutils broke things on some vms/distros (i.e., linking against # unknown relocs disabled by the following flag), so we need to go out of our diff --git a/src/ci/docker/dist-x86_64-netbsd/Dockerfile b/src/ci/docker/dist-x86_64-netbsd/Dockerfile index 06298a12fc70..a17a7ebc03dd 100644 --- a/src/ci/docker/dist-x86_64-netbsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-netbsd/Dockerfile @@ -33,5 +33,5 @@ ENV \ ENV HOSTS=x86_64-unknown-netbsd -ENV RUST_CONFIGURE_ARGS --enable-extended +ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS From 7d5343a6700581e318189dcd74567b348bd7f68d Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 21 Mar 2018 21:49:22 +0100 Subject: [PATCH 618/830] implement minmax intrinsics --- src/librustc_llvm/ffi.rs | 3 +++ src/librustc_trans/builder.rs | 13 +++++++++++++ src/librustc_trans/intrinsic.rs | 2 ++ src/librustc_typeck/check/intrinsic.rs | 3 ++- src/rustllvm/RustWrapper.cpp | 9 +++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 403fe4731f11..09ff35667139 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1247,6 +1247,9 @@ extern "C" { IsNaN: bool) -> ValueRef; + pub fn LLVMRustBuildMinNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + pub fn LLVMRustBuildMaxNum(B: BuilderRef, LHS: ValueRef, LHS: ValueRef) -> ValueRef; + pub fn LLVMBuildIsNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildIsNotNull(B: BuilderRef, Val: ValueRef, Name: *const c_char) -> ValueRef; pub fn LLVMBuildPtrDiff(B: BuilderRef, diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 5e2d32b35969..b5271b25b630 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -917,6 +917,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } + pub fn minnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + self.count_insn("minnum"); + unsafe { + llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) + } + } + pub fn maxnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { + self.count_insn("maxnum"); + unsafe { + llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) + } + } + pub fn select(&self, cond: ValueRef, then_val: ValueRef, else_val: ValueRef) -> ValueRef { self.count_insn("select"); unsafe { diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 2be29c083607..5c67f8091141 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -1432,6 +1432,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, simd_and: TyUint, TyInt => and; simd_or: TyUint, TyInt => or; simd_xor: TyUint, TyInt => xor; + simd_fmax: TyFloat => maxnum; + simd_fmin: TyFloat => minnum; } span_bug!(span, "unknown SIMD intrinsic"); } diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index da37cec31cf4..377e3a891840 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -355,7 +355,8 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } "simd_add" | "simd_sub" | "simd_mul" | "simd_rem" | "simd_div" | "simd_shl" | "simd_shr" | - "simd_and" | "simd_or" | "simd_xor" => { + "simd_and" | "simd_or" | "simd_xor" | + "simd_fmin" | "simd_fmax" => { (1, vec![param(0), param(0)], param(0)) } "simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)), diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index e815d151aeba..627827105cbb 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1500,3 +1500,12 @@ LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, return wrap(unwrap(B)->CreateExactUDiv(unwrap(LHS), unwrap(RHS), Name)); } #endif + +extern "C" LLVMValueRef +LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { + return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS))); +} +extern "C" LLVMValueRef +LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { + return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS))); +} From d2cd57c8ff2116c2120da2668cee4ff2bf28315c Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 22 Mar 2018 09:49:46 +0100 Subject: [PATCH 619/830] add tests --- .../codegen/simd-intrinsic-float-minmax.rs | 40 ++++++++++++++ .../run-fail/simd-intrinsic-float-minmax.rs | 55 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 src/test/codegen/simd-intrinsic-float-minmax.rs create mode 100644 src/test/run-fail/simd-intrinsic-float-minmax.rs diff --git a/src/test/codegen/simd-intrinsic-float-minmax.rs b/src/test/codegen/simd-intrinsic-float-minmax.rs new file mode 100644 index 000000000000..bebb4d379830 --- /dev/null +++ b/src/test/codegen/simd-intrinsic-float-minmax.rs @@ -0,0 +1,40 @@ +// 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. + +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct f32x4(pub f32, pub f32, pub f32, pub f32); + +extern "platform-intrinsic" { + fn simd_fmin(x: T, y: T) -> T; + fn simd_fmax(x: T, y: T) -> T; +} + +// CHECK-LABEL: @fmin +#[no_mangle] +pub unsafe fn fmin(a: f32x4, b: f32x4) -> f32x4 { + // CHECK: call <4 x float> @llvm.minnum.v4f32 + simd_fmin(a, b) +} + +// FIXME(49261) +// // CHECK-LABEL: @fmax +// #[no_mangle] +// pub unsafe fn fmax(a: f32x4, b: f32x4) -> f32x4 { +// // CHECK: call <4 x float> @llvm.maxnum.v4f32 +// simd_fmax(a, b) +// } diff --git a/src/test/run-fail/simd-intrinsic-float-minmax.rs b/src/test/run-fail/simd-intrinsic-float-minmax.rs new file mode 100644 index 000000000000..32ee569d8fad --- /dev/null +++ b/src/test/run-fail/simd-intrinsic-float-minmax.rs @@ -0,0 +1,55 @@ +// Copyright 2015 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-emscripten + +// Test that the simd_f{min,max} intrinsics produce the correct results. + +#![feature(repr_simd, platform_intrinsics)] +#[allow(non_camel_case_types)] + +#[repr(simd)] +#[derive(Copy, Clone, PartialEq, Debug)] +struct f32x4(pub f32, pub f32, pub f32, pub f32); + +extern "platform-intrinsic" { + fn simd_fmin(x: T, y: T) -> T; + fn simd_fmax(x: T, y: T) -> T; +} + +fn main() { + let x = f32x4(1.0, 2.0, 3.0, 4.0); + let y = f32x4(2.0, 1.0, 4.0, 3.0); + let nan = ::std::f32::NAN; + let n = f32x4(nan, nan, nan, nan); + + unsafe { + let min0 = simd_fmin(x, y); + let min1 = simd_fmin(y, x); + assert_eq!(min0, min1); + let e = f32x4(1.0, 1.0, 3.0, 3.0); + assert_eq!(min0, e); + let minn = simd_fmin(x, n); + assert_eq!(minn, x); + let minn = simd_fmin(y, n); + assert_eq!(minn, y); + + // FIXME(49261) + let max0 = simd_fmax(x, y); + let max1 = simd_fmax(y, x); + assert_eq!(max0, max1); + let e = f32x4(2.0, 2.0, 4.0, 4.0); + assert_eq!(max0, e); + let maxn = simd_fmax(x, n); + assert_eq!(maxn, x); + let maxn = simd_fmax(y, n); + assert_eq!(maxn, y); + } +} From 066c2ec9baac1be5e884e48813a542de8f5d64b0 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 22 Mar 2018 14:48:58 +0100 Subject: [PATCH 620/830] require llvm 6 --- src/librustc_trans/builder.rs | 8 ++++++-- src/rustllvm/RustWrapper.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index b5271b25b630..241ee8a48283 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -920,13 +920,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { pub fn minnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { self.count_insn("minnum"); unsafe { - llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) + let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs); + bug!("LLVMRustBuildMinNum is not available in LLVM version < 6.0"); + instr } } pub fn maxnum(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef { self.count_insn("maxnum"); unsafe { - llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) + let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs); + bug!("LLVMRustBuildMaxNum is not available in LLVM version < 6.0"); + instr } } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 627827105cbb..1b35f0adda64 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -1501,6 +1501,7 @@ LLVMBuildExactUDiv(LLVMBuilderRef B, LLVMValueRef LHS, } #endif +#if LLVM_VERSION_GE(6, 0) extern "C" LLVMValueRef LLVMRustBuildMinNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { return wrap(unwrap(B)->CreateMinNum(unwrap(LHS),unwrap(RHS))); @@ -1509,3 +1510,13 @@ extern "C" LLVMValueRef LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS) { return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS),unwrap(RHS))); } +#else +extern "C" LLVMValueRef +LLVMRustBuildMinNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; +} +extern "C" LLVMValueRef +LLVMRustBuildMaxNum(LLVMBuilderRef, LLVMValueRef, LLVMValueRef) { + return nullptr; +} +#endif From 1841f40d2164c56dc286cef7a2e0d1bf091837f7 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 22 Mar 2018 16:28:11 +0100 Subject: [PATCH 621/830] properly handle the case when LLVM does not have min/maxnum --- src/librustc_trans/builder.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/builder.rs b/src/librustc_trans/builder.rs index 241ee8a48283..db803ca8209d 100644 --- a/src/librustc_trans/builder.rs +++ b/src/librustc_trans/builder.rs @@ -921,7 +921,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.count_insn("minnum"); unsafe { let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs); - bug!("LLVMRustBuildMinNum is not available in LLVM version < 6.0"); + if instr.is_null() { + bug!("LLVMRustBuildMinNum is not available in LLVM version < 6.0"); + } instr } } @@ -929,7 +931,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.count_insn("maxnum"); unsafe { let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs); - bug!("LLVMRustBuildMaxNum is not available in LLVM version < 6.0"); + if instr.is_null() { + bug!("LLVMRustBuildMaxNum is not available in LLVM version < 6.0"); + } instr } } From 48fd903eae4b6b95c76f206c3c7f648aaf4f664d Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 22 Mar 2018 18:01:35 +0100 Subject: [PATCH 622/830] set min-llvm-version 6.0, ignore-emscripten --- src/test/codegen/simd-intrinsic-float-minmax.rs | 3 +++ src/test/run-fail/simd-intrinsic-float-minmax.rs | 1 + 2 files changed, 4 insertions(+) diff --git a/src/test/codegen/simd-intrinsic-float-minmax.rs b/src/test/codegen/simd-intrinsic-float-minmax.rs index bebb4d379830..8ad3ad762c28 100644 --- a/src/test/codegen/simd-intrinsic-float-minmax.rs +++ b/src/test/codegen/simd-intrinsic-float-minmax.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-emscripten +// min-llvm-version 6.0 + // compile-flags: -C no-prepopulate-passes #![crate_type = "lib"] diff --git a/src/test/run-fail/simd-intrinsic-float-minmax.rs b/src/test/run-fail/simd-intrinsic-float-minmax.rs index 32ee569d8fad..fad8fa48bc34 100644 --- a/src/test/run-fail/simd-intrinsic-float-minmax.rs +++ b/src/test/run-fail/simd-intrinsic-float-minmax.rs @@ -9,6 +9,7 @@ // except according to those terms. // ignore-emscripten +// min-llvm-version 6.0 // Test that the simd_f{min,max} intrinsics produce the correct results. From 56aaf344c444943f3c9cefe9d88ed27b43f0a731 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 26 Mar 2018 10:18:36 +0200 Subject: [PATCH 623/830] fix tests --- src/test/codegen/simd-intrinsic-float-minmax.rs | 4 ++-- src/test/run-fail/simd-intrinsic-float-minmax.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/codegen/simd-intrinsic-float-minmax.rs b/src/test/codegen/simd-intrinsic-float-minmax.rs index 8ad3ad762c28..6663b841808f 100644 --- a/src/test/codegen/simd-intrinsic-float-minmax.rs +++ b/src/test/codegen/simd-intrinsic-float-minmax.rs @@ -35,9 +35,9 @@ pub unsafe fn fmin(a: f32x4, b: f32x4) -> f32x4 { } // FIXME(49261) -// // CHECK-LABEL: @fmax +// // C_HECK-LABEL: @fmax // #[no_mangle] // pub unsafe fn fmax(a: f32x4, b: f32x4) -> f32x4 { -// // CHECK: call <4 x float> @llvm.maxnum.v4f32 +// // C_HECK: call <4 x float> @llvm.maxnum.v4f32 // simd_fmax(a, b) // } diff --git a/src/test/run-fail/simd-intrinsic-float-minmax.rs b/src/test/run-fail/simd-intrinsic-float-minmax.rs index fad8fa48bc34..f4fb8e12250b 100644 --- a/src/test/run-fail/simd-intrinsic-float-minmax.rs +++ b/src/test/run-fail/simd-intrinsic-float-minmax.rs @@ -10,6 +10,7 @@ // ignore-emscripten // min-llvm-version 6.0 +// error-pattern: panicked // Test that the simd_f{min,max} intrinsics produce the correct results. From 0f5b52e4a8d3004ef2d69b2ec7f410d4b2c9494c Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 21 Mar 2018 18:32:44 -0700 Subject: [PATCH 624/830] Stabilize conservative_impl_trait --- src/Cargo.lock | 27 +------- .../conservative-impl-trait.md | 66 ------------------- src/libcore/tests/lib.rs | 2 +- src/librustc/diagnostics.rs | 8 --- src/librustc/hir/lowering.rs | 11 ---- src/librustc/lib.rs | 2 +- src/librustc_data_structures/lib.rs | 2 +- src/librustc_errors/lib.rs | 2 +- src/librustc_incremental/lib.rs | 2 +- src/librustc_metadata/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_trans/lib.rs | 2 +- src/librustc_trans_utils/lib.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 5 +- .../compile-fail/conservative_impl_trait.rs | 1 - .../infinite-impl-trait-issue-38064.rs | 2 - .../must_outlive_least_region_or_bound.rs | 2 - .../impl-trait/needs_least_region_or_bound.rs | 2 - src/test/compile-fail/impl-trait/no-trait.rs | 2 - .../impl-trait/type_parameters_captured.rs | 2 - .../compile-fail/impl-trait/where-allowed.rs | 2 +- src/test/compile-fail/issue-32995-2.rs | 1 - src/test/compile-fail/issue-35668.rs | 2 - src/test/compile-fail/issue-36379.rs | 2 +- .../compile-fail/private-inferred-type.rs | 1 - .../compile-fail/private-type-in-interface.rs | 1 - .../incremental/hashes/function_interfaces.rs | 1 - src/test/run-pass/conservative_impl_trait.rs | 2 - .../generator/auxiliary/xcrate-reachable.rs | 2 +- .../run-pass/generator/auxiliary/xcrate.rs | 2 +- src/test/run-pass/generator/issue-44197.rs | 2 +- src/test/run-pass/generator/iterator-count.rs | 2 +- .../run-pass/generator/xcrate-reachable.rs | 2 +- .../run-pass/impl-trait/auto-trait-leak.rs | 2 - .../run-pass/impl-trait/auxiliary/xcrate.rs | 2 - src/test/run-pass/impl-trait/equality.rs | 2 +- .../run-pass/impl-trait/example-calendar.rs | 3 +- src/test/run-pass/impl-trait/example-st.rs | 2 - src/test/run-pass/impl-trait/issue-42479.rs | 2 - src/test/run-pass/impl-trait/lifetimes.rs | 2 +- src/test/run-pass/in-band-lifetimes.rs | 2 +- src/test/run-pass/issue-36792.rs | 1 - src/test/run-pass/issue-46959.rs | 1 - src/test/rustdoc/issue-43869.rs | 2 - src/test/ui/casts-differing-anon.rs | 2 - src/test/ui/casts-differing-anon.stderr | 2 +- src/test/ui/error-codes/E0657.rs | 1 - src/test/ui/error-codes/E0657.stderr | 4 +- .../feature-gate-conservative_impl_trait.rs | 14 ---- ...eature-gate-conservative_impl_trait.stderr | 11 ---- src/test/ui/impl-trait/auto-trait-leak.rs | 2 - src/test/ui/impl-trait/auto-trait-leak.stderr | 22 +++---- src/test/ui/impl-trait/equality.rs | 2 +- ...-escape-via-bound-contravariant-closure.rs | 1 - .../region-escape-via-bound-contravariant.rs | 1 - .../ui/impl-trait/region-escape-via-bound.rs | 1 - .../impl-trait/region-escape-via-bound.stderr | 6 +- src/test/ui/impl_trait_projections.rs | 2 +- src/test/ui/issue-35869.rs | 2 - src/test/ui/issue-35869.stderr | 8 +-- src/test/ui/nested_impl_trait.rs | 2 - src/test/ui/nested_impl_trait.stderr | 12 ++-- .../ui/nll/ty-outlives/impl-trait-captures.rs | 1 - .../ty-outlives/impl-trait-captures.stderr | 4 +- .../ui/nll/ty-outlives/impl-trait-outlives.rs | 1 - .../ty-outlives/impl-trait-outlives.stderr | 8 +-- src/tools/clippy | 2 +- 68 files changed, 62 insertions(+), 240 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/conservative-impl-trait.md delete mode 100644 src/test/ui/feature-gate-conservative_impl_trait.rs delete mode 100644 src/test/ui/feature-gate-conservative_impl_trait.stderr diff --git a/src/Cargo.lock b/src/Cargo.lock index 371e505e9bed..c45f18360b9b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -271,11 +271,11 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.188" +version = "0.0.189" dependencies = [ "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "clippy-mini-macro-test 0.2.0", - "clippy_lints 0.0.188", + "clippy_lints 0.0.189", "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -289,29 +289,9 @@ dependencies = [ name = "clippy-mini-macro-test" version = "0.2.0" -[[package]] -name = "clippy_lints" -version = "0.0.188" -dependencies = [ - "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clippy_lints" version = "0.0.189" -source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1419,7 +1399,7 @@ version = "0.126.0" dependencies = [ "cargo 0.27.0", "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.189 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.189", "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2638,7 +2618,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" -"checksum clippy_lints 0.0.189 (registry+https://github.com/rust-lang/crates.io-index)" = "fef652630bbf8c5e89601220abd000f5057e8fa9db608484b5ebaad98e9bce53" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" diff --git a/src/doc/unstable-book/src/language-features/conservative-impl-trait.md b/src/doc/unstable-book/src/language-features/conservative-impl-trait.md deleted file mode 100644 index 0be6a321103f..000000000000 --- a/src/doc/unstable-book/src/language-features/conservative-impl-trait.md +++ /dev/null @@ -1,66 +0,0 @@ -# `conservative_impl_trait` - -The tracking issue for this feature is: [#34511] - -[#34511]: https://github.com/rust-lang/rust/issues/34511 - ------------------------- - -The `conservative_impl_trait` feature allows a conservative form of abstract -return types. - -Abstract return types allow a function to hide a concrete return type behind a -trait interface similar to trait objects, while still generating the same -statically dispatched code as with concrete types. - -## Examples - -```rust -#![feature(conservative_impl_trait)] - -fn even_iter() -> impl Iterator { - (0..).map(|n| n * 2) -} - -fn main() { - let first_four_even_numbers = even_iter().take(4).collect::>(); - assert_eq!(first_four_even_numbers, vec![0, 2, 4, 6]); -} -``` - -## Background - -In today's Rust, you can write function signatures like: - -````rust,ignore -fn consume_iter_static>(iter: I) { } - -fn consume_iter_dynamic(iter: Box>) { } -```` - -In both cases, the function does not depend on the exact type of the argument. -The type held is "abstract", and is assumed only to satisfy a trait bound. - -* In the `_static` version using generics, each use of the function is - specialized to a concrete, statically-known type, giving static dispatch, - inline layout, and other performance wins. -* In the `_dynamic` version using trait objects, the concrete argument type is - only known at runtime using a vtable. - -On the other hand, while you can write: - -````rust,ignore -fn produce_iter_dynamic() -> Box> { } -```` - -...but you _cannot_ write something like: - -````rust,ignore -fn produce_iter_static() -> Iterator { } -```` - -That is, in today's Rust, abstract return types can only be written using trait -objects, which can be a significant performance penalty. This RFC proposes -"unboxed abstract types" as a way of achieving signatures like -`produce_iter_static`. Like generics, unboxed abstract types guarantee static -dispatch and inline data layout. diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index e9a8113ef107..1c71669abb16 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -27,7 +27,7 @@ #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(iterator_try_fold)] #![feature(iterator_flatten)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(iter_rfind)] #![feature(iter_rfold)] #![feature(iterator_repeat_with)] diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index e22e2b557039..f95c355012a2 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1789,8 +1789,6 @@ allowed as function return types. Erroneous code example: ```compile_fail,E0562 -#![feature(conservative_impl_trait)] - fn main() { let count_to_ten: impl Iterator = 0..10; // error: `impl Trait` not allowed outside of function and inherent method @@ -1804,8 +1802,6 @@ fn main() { Make sure `impl Trait` only appears in return-type position. ``` -#![feature(conservative_impl_trait)] - fn count_to_n(n: usize) -> impl Iterator { 0..n } @@ -2081,8 +2077,6 @@ appear within the `impl Trait` itself. Erroneous code example: ```compile-fail,E0909 -#![feature(conservative_impl_trait)] - use std::cell::Cell; trait Trait<'a> { } @@ -2109,8 +2103,6 @@ type. For example, changing the return type to `impl Trait<'y> + 'x` would work: ``` -#![feature(conservative_impl_trait)] - use std::cell::Cell; trait Trait<'a> { } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 2ae102fbef03..536d682566a7 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1108,20 +1108,9 @@ impl<'a> LoweringContext<'a> { hir::TyTraitObject(bounds, lifetime_bound) } TyKind::ImplTrait(ref bounds) => { - use syntax::feature_gate::{emit_feature_err, GateIssue}; let span = t.span; match itctx { ImplTraitContext::Existential => { - let has_feature = self.sess.features_untracked().conservative_impl_trait; - if !t.span.allows_unstable() && !has_feature { - emit_feature_err( - &self.sess.parse_sess, - "conservative_impl_trait", - t.span, - GateIssue::Language, - "`impl Trait` in return position is experimental", - ); - } let def_index = self.resolver.definitions().opt_def_index(t.id).unwrap(); let hir_bounds = self.lower_bounds(bounds, itctx); let (lifetimes, lifetime_defs) = diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index d133352de078..1bb903c0627b 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -43,7 +43,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(const_fn)] #![cfg_attr(stage0, feature(copy_closures, clone_closures))] #![feature(core_intrinsics)] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 05bd3ae845fb..ff8690728713 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -28,7 +28,7 @@ #![feature(unsize)] #![feature(i128_type)] #![feature(i128)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(specialization)] #![feature(optin_builtin_traits)] #![feature(underscore_lifetimes)] diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index dcbea793ba6a..1152c9c574ec 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -17,7 +17,7 @@ #![allow(unused_attributes)] #![feature(range_contains)] #![cfg_attr(unix, feature(libc))] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(i128_type)] #![feature(optin_builtin_traits)] diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index d7ccf9d5562e..6adb950fe4ef 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -15,7 +15,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(fs_read_write)] #![feature(i128_type)] #![cfg_attr(stage0, feature(inclusive_range_syntax))] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 850996674494..902dd87c5743 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -14,7 +14,7 @@ #![deny(warnings)] #![feature(box_patterns)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(fs_read_write)] #![feature(i128_type)] #![feature(libc)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index ff35412ea5ba..750839f8b001 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -21,7 +21,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(box_patterns)] #![feature(box_syntax)] #![feature(catch_expr)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(decl_macro)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 9f654c8ab29c..38adc603628e 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -31,7 +31,7 @@ #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![cfg_attr(stage0, feature(slice_patterns))] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(optin_builtin_traits)] #![feature(inclusive_range_fields)] diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 0af5f4679345..9e4addd1ed1b 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -24,7 +24,7 @@ #![feature(i128_type)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] extern crate ar; extern crate flate2; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 5a7de6b56b50..e466ef392348 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -75,7 +75,7 @@ This API is completely unstable and subject to change. #![cfg_attr(stage0, feature(advanced_slice_patterns))] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(conservative_impl_trait)] +#![cfg_attr(stage0, feature(conservative_impl_trait))] #![cfg_attr(stage0, feature(copy_closures, clone_closures))] #![feature(crate_visibility_modifier)] #![feature(from_ref)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index db900ed6e355..1bb369b551db 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -276,9 +276,6 @@ declare_features! ( // Allows cfg(target_has_atomic = "..."). (active, cfg_target_has_atomic, "1.9.0", Some(32976), None), - // Allows `impl Trait` in function return types. - (active, conservative_impl_trait, "1.12.0", Some(34511), None), - // Allows exhaustive pattern matching on types that contain uninhabited types. (active, exhaustive_patterns, "1.13.0", None, None), @@ -565,6 +562,8 @@ declare_features! ( (accepted, copy_closures, "1.26.0", Some(44490), None), // Allows `impl Trait` in function arguments. (accepted, universal_impl_trait, "1.26.0", Some(34511), None), + // Allows `impl Trait` in function return types. + (accepted, conservative_impl_trait, "1.26.0", Some(34511), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/compile-fail/conservative_impl_trait.rs b/src/test/compile-fail/conservative_impl_trait.rs index 7fb0ec52f29f..30895bce357b 100644 --- a/src/test/compile-fail/conservative_impl_trait.rs +++ b/src/test/compile-fail/conservative_impl_trait.rs @@ -10,7 +10,6 @@ // #39872, #39553 -#![feature(conservative_impl_trait)] fn will_ice(something: &u32) -> impl Iterator { //~^ ERROR the trait bound `(): std::iter::Iterator` is not satisfied [E0277] } diff --git a/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs b/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs index abde9689bd6b..653ef1723e0b 100644 --- a/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs +++ b/src/test/compile-fail/impl-trait/infinite-impl-trait-issue-38064.rs @@ -15,8 +15,6 @@ // error-pattern:overflow evaluating the requirement `impl Quux` -#![feature(conservative_impl_trait)] - trait Quux {} fn foo() -> impl Quux { diff --git a/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs index 0eb99ca0fc3f..537fc975bcf9 100644 --- a/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/compile-fail/impl-trait/must_outlive_least_region_or_bound.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - use std::fmt::Debug; fn elided(x: &i32) -> impl Copy { x } diff --git a/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs b/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs index 2a06580fe605..6c0a0b800ce3 100644 --- a/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs +++ b/src/test/compile-fail/impl-trait/needs_least_region_or_bound.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - use std::fmt::Debug; trait MultiRegionTrait<'a, 'b> {} diff --git a/src/test/compile-fail/impl-trait/no-trait.rs b/src/test/compile-fail/impl-trait/no-trait.rs index ce61c5bf63d8..5299ba297d0a 100644 --- a/src/test/compile-fail/impl-trait/no-trait.rs +++ b/src/test/compile-fail/impl-trait/no-trait.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - fn f() -> impl 'static {} //~ ERROR at least one trait must be specified fn main() {} diff --git a/src/test/compile-fail/impl-trait/type_parameters_captured.rs b/src/test/compile-fail/impl-trait/type_parameters_captured.rs index c6ff762b9050..7c3430ab90e5 100644 --- a/src/test/compile-fail/impl-trait/type_parameters_captured.rs +++ b/src/test/compile-fail/impl-trait/type_parameters_captured.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - use std::fmt::Debug; trait Any {} diff --git a/src/test/compile-fail/impl-trait/where-allowed.rs b/src/test/compile-fail/impl-trait/where-allowed.rs index c93bcf7f390e..038eacaf1103 100644 --- a/src/test/compile-fail/impl-trait/where-allowed.rs +++ b/src/test/compile-fail/impl-trait/where-allowed.rs @@ -10,7 +10,7 @@ //! A simple test for testing many permutations of allowedness of //! impl Trait -#![feature(conservative_impl_trait, dyn_trait)] +#![feature(dyn_trait)] use std::fmt::Debug; // Allowed diff --git a/src/test/compile-fail/issue-32995-2.rs b/src/test/compile-fail/issue-32995-2.rs index 0e917ad95d95..18424fcc9e0a 100644 --- a/src/test/compile-fail/issue-32995-2.rs +++ b/src/test/compile-fail/issue-32995-2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] #![allow(unused)] fn main() { diff --git a/src/test/compile-fail/issue-35668.rs b/src/test/compile-fail/issue-35668.rs index c9323db054c8..17fd77b6df3a 100644 --- a/src/test/compile-fail/issue-35668.rs +++ b/src/test/compile-fail/issue-35668.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - fn func<'a, T>(a: &'a [T]) -> impl Iterator { a.iter().map(|a| a*a) //~^ ERROR binary operation `*` cannot be applied to type `&T` diff --git a/src/test/compile-fail/issue-36379.rs b/src/test/compile-fail/issue-36379.rs index 2f513b034c36..b20765815e0b 100644 --- a/src/test/compile-fail/issue-36379.rs +++ b/src/test/compile-fail/issue-36379.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, rustc_attrs)] +#![feature(rustc_attrs)] fn _test() -> impl Default { } diff --git a/src/test/compile-fail/private-inferred-type.rs b/src/test/compile-fail/private-inferred-type.rs index 351dc6b776b2..5af8b063c162 100644 --- a/src/test/compile-fail/private-inferred-type.rs +++ b/src/test/compile-fail/private-inferred-type.rs @@ -9,7 +9,6 @@ // except according to those terms. #![feature(associated_consts)] -#![feature(conservative_impl_trait)] #![feature(decl_macro)] #![allow(private_in_public)] diff --git a/src/test/compile-fail/private-type-in-interface.rs b/src/test/compile-fail/private-type-in-interface.rs index eb8c40a7dd5e..1842790a1405 100644 --- a/src/test/compile-fail/private-type-in-interface.rs +++ b/src/test/compile-fail/private-type-in-interface.rs @@ -10,7 +10,6 @@ // aux-build:private-inferred-type.rs -#![feature(conservative_impl_trait)] #![allow(warnings)] extern crate private_inferred_type as ext; diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index abe0586efcd7..6c4e11be1e43 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -22,7 +22,6 @@ #![allow(warnings)] -#![feature(conservative_impl_trait)] #![feature(intrinsics)] #![feature(linkage)] #![feature(rustc_attrs)] diff --git a/src/test/run-pass/conservative_impl_trait.rs b/src/test/run-pass/conservative_impl_trait.rs index 30090018e294..14e1ca612c08 100644 --- a/src/test/run-pass/conservative_impl_trait.rs +++ b/src/test/run-pass/conservative_impl_trait.rs @@ -10,8 +10,6 @@ // #39665 -#![feature(conservative_impl_trait)] - fn batches(n: &u32) -> impl Iterator { std::iter::once(n) } diff --git a/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs b/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs index a6a2a2d081e1..91e43537cc21 100644 --- a/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs +++ b/src/test/run-pass/generator/auxiliary/xcrate-reachable.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, generators, generator_trait)] +#![feature(generators, generator_trait)] use std::ops::Generator; diff --git a/src/test/run-pass/generator/auxiliary/xcrate.rs b/src/test/run-pass/generator/auxiliary/xcrate.rs index f6878e64fbf9..fcfe0b754b68 100644 --- a/src/test/run-pass/generator/auxiliary/xcrate.rs +++ b/src/test/run-pass/generator/auxiliary/xcrate.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generators, generator_trait, conservative_impl_trait)] +#![feature(generators, generator_trait)] use std::ops::Generator; diff --git a/src/test/run-pass/generator/issue-44197.rs b/src/test/run-pass/generator/issue-44197.rs index 8ce4fc6affab..272b7eb7bfdd 100644 --- a/src/test/run-pass/generator/issue-44197.rs +++ b/src/test/run-pass/generator/issue-44197.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, generators, generator_trait)] +#![feature(generators, generator_trait)] use std::ops::{ Generator, GeneratorState }; diff --git a/src/test/run-pass/generator/iterator-count.rs b/src/test/run-pass/generator/iterator-count.rs index 654b18928c07..3564ddaa8068 100644 --- a/src/test/run-pass/generator/iterator-count.rs +++ b/src/test/run-pass/generator/iterator-count.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generators, generator_trait, conservative_impl_trait)] +#![feature(generators, generator_trait)] use std::ops::{GeneratorState, Generator}; diff --git a/src/test/run-pass/generator/xcrate-reachable.rs b/src/test/run-pass/generator/xcrate-reachable.rs index 8eeb01331449..2fc39ba18691 100644 --- a/src/test/run-pass/generator/xcrate-reachable.rs +++ b/src/test/run-pass/generator/xcrate-reachable.rs @@ -10,7 +10,7 @@ // aux-build:xcrate-reachable.rs -#![feature(conservative_impl_trait, generator_trait)] +#![feature(generator_trait)] extern crate xcrate_reachable as foo; diff --git a/src/test/run-pass/impl-trait/auto-trait-leak.rs b/src/test/run-pass/impl-trait/auto-trait-leak.rs index 011d910c5a50..62fbae7b40c0 100644 --- a/src/test/run-pass/impl-trait/auto-trait-leak.rs +++ b/src/test/run-pass/impl-trait/auto-trait-leak.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - // Fast path, main can see the concrete type returned. fn before() -> impl FnMut(i32) { let mut p = Box::new(0); diff --git a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs index e4f525a98261..c27a2dd89d52 100644 --- a/src/test/run-pass/impl-trait/auxiliary/xcrate.rs +++ b/src/test/run-pass/impl-trait/auxiliary/xcrate.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - // NOTE commented out due to issue #45994 //pub fn fourway_add(a: i32) -> impl Fn(i32) -> impl Fn(i32) -> impl Fn(i32) -> i32 { // move |b| move |c| move |d| a + b + c + d diff --git a/src/test/run-pass/impl-trait/equality.rs b/src/test/run-pass/impl-trait/equality.rs index ceed454e5ad7..034d3d7c80f3 100644 --- a/src/test/run-pass/impl-trait/equality.rs +++ b/src/test/run-pass/impl-trait/equality.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, specialization)] +#![feature(specialization)] trait Foo: std::fmt::Debug + Eq {} diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs index d1e2b471d9ae..b1db20307178 100644 --- a/src/test/run-pass/impl-trait/example-calendar.rs +++ b/src/test/run-pass/impl-trait/example-calendar.rs @@ -11,8 +11,7 @@ // revisions: normal nll //[nll] compile-flags: -Znll -Zborrowck=mir -#![feature(conservative_impl_trait, - fn_traits, +#![feature(fn_traits, step_trait, unboxed_closures, copy_closures, diff --git a/src/test/run-pass/impl-trait/example-st.rs b/src/test/run-pass/impl-trait/example-st.rs index e9326ed286af..a06bde7f532d 100644 --- a/src/test/run-pass/impl-trait/example-st.rs +++ b/src/test/run-pass/impl-trait/example-st.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - struct State; type Error = (); diff --git a/src/test/run-pass/impl-trait/issue-42479.rs b/src/test/run-pass/impl-trait/issue-42479.rs index 629948a5dc4a..df7a6c130922 100644 --- a/src/test/run-pass/impl-trait/issue-42479.rs +++ b/src/test/run-pass/impl-trait/issue-42479.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - use std::iter::once; struct Foo { diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs index c589e23f9504..1b50ceefbe1a 100644 --- a/src/test/run-pass/impl-trait/lifetimes.rs +++ b/src/test/run-pass/impl-trait/lifetimes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, underscore_lifetimes)] +#![feature(underscore_lifetimes)] #![allow(warnings)] use std::fmt::Debug; diff --git a/src/test/run-pass/in-band-lifetimes.rs b/src/test/run-pass/in-band-lifetimes.rs index b5b73675ca72..6edd0d686eff 100644 --- a/src/test/run-pass/in-band-lifetimes.rs +++ b/src/test/run-pass/in-band-lifetimes.rs @@ -9,7 +9,7 @@ // except according to those terms. #![allow(warnings)] -#![feature(in_band_lifetimes, conservative_impl_trait)] +#![feature(in_band_lifetimes)] fn foo(x: &'x u8) -> &'x u8 { x } fn foo2(x: &'a u8, y: &u8) -> &'a u8 { x } diff --git a/src/test/run-pass/issue-36792.rs b/src/test/run-pass/issue-36792.rs index faf983f6ecb1..f2755ec3f846 100644 --- a/src/test/run-pass/issue-36792.rs +++ b/src/test/run-pass/issue-36792.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] fn foo() -> impl Copy { foo } diff --git a/src/test/run-pass/issue-46959.rs b/src/test/run-pass/issue-46959.rs index 876b8c0a1d38..7f050c055b0c 100644 --- a/src/test/run-pass/issue-46959.rs +++ b/src/test/run-pass/issue-46959.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] #![deny(non_camel_case_types)] #[allow(dead_code)] diff --git a/src/test/rustdoc/issue-43869.rs b/src/test/rustdoc/issue-43869.rs index 554c71500cc8..a5ed3d892ce9 100644 --- a/src/test/rustdoc/issue-43869.rs +++ b/src/test/rustdoc/issue-43869.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - pub fn g() -> impl Iterator { Some(1u8).into_iter() } diff --git a/src/test/ui/casts-differing-anon.rs b/src/test/ui/casts-differing-anon.rs index 74c8ff370f98..05a03d3b1796 100644 --- a/src/test/ui/casts-differing-anon.rs +++ b/src/test/ui/casts-differing-anon.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - use std::fmt; fn foo() -> Box { diff --git a/src/test/ui/casts-differing-anon.stderr b/src/test/ui/casts-differing-anon.stderr index acbff4f73c39..dac24af671cf 100644 --- a/src/test/ui/casts-differing-anon.stderr +++ b/src/test/ui/casts-differing-anon.stderr @@ -1,5 +1,5 @@ error[E0606]: casting `*mut impl std::fmt::Debug+?Sized` as `*mut impl std::fmt::Debug+?Sized` is invalid - --> $DIR/casts-differing-anon.rs:33:13 + --> $DIR/casts-differing-anon.rs:31:13 | LL | b_raw = f_raw as *mut _; //~ ERROR is invalid | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/error-codes/E0657.rs b/src/test/ui/error-codes/E0657.rs index 31b3acd86ef5..c23aa40ee379 100644 --- a/src/test/ui/error-codes/E0657.rs +++ b/src/test/ui/error-codes/E0657.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![allow(warnings)] -#![feature(conservative_impl_trait)] trait Id {} trait Lt<'a> {} diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr index f05291420239..737ae3a163ac 100644 --- a/src/test/ui/error-codes/E0657.stderr +++ b/src/test/ui/error-codes/E0657.stderr @@ -1,11 +1,11 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level - --> $DIR/E0657.rs:20:31 + --> $DIR/E0657.rs:19:31 | LL | -> Box Id>> | ^^ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level - --> $DIR/E0657.rs:29:35 + --> $DIR/E0657.rs:28:35 | LL | -> Box Id>> | ^^ diff --git a/src/test/ui/feature-gate-conservative_impl_trait.rs b/src/test/ui/feature-gate-conservative_impl_trait.rs deleted file mode 100644 index 7a3ae639bfc8..000000000000 --- a/src/test/ui/feature-gate-conservative_impl_trait.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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. - -fn foo() -> impl Fn() { || {} } -//~^ ERROR `impl Trait` in return position is experimental - -fn main() {} diff --git a/src/test/ui/feature-gate-conservative_impl_trait.stderr b/src/test/ui/feature-gate-conservative_impl_trait.stderr deleted file mode 100644 index 5400226450bf..000000000000 --- a/src/test/ui/feature-gate-conservative_impl_trait.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: `impl Trait` in return position is experimental (see issue #34511) - --> $DIR/feature-gate-conservative_impl_trait.rs:11:13 - | -LL | fn foo() -> impl Fn() { || {} } - | ^^^^^^^^^ - | - = help: add #![feature(conservative_impl_trait)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index 5a6aac43ec77..99a7dd5e7852 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -10,8 +10,6 @@ // ignore-tidy-linelength -#![feature(conservative_impl_trait)] - use std::cell::Cell; use std::rc::Rc; diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 71ca8675db4e..ca639f1076d3 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -1,56 +1,56 @@ error[E0277]: the trait bound `std::rc::Rc>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>` - --> $DIR/auto-trait-leak.rs:27:5 + --> $DIR/auto-trait-leak.rs:25:5 | LL | send(before()); | ^^^^ `std::rc::Rc>` cannot be sent between threads safely | = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` - = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc>]` + = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:19:5: 19:22 p:std::rc::Rc>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` note: required by `send` - --> $DIR/auto-trait-leak.rs:24:1 + --> $DIR/auto-trait-leak.rs:22:1 | LL | fn send(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::rc::Rc>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>` - --> $DIR/auto-trait-leak.rs:30:5 + --> $DIR/auto-trait-leak.rs:28:5 | LL | send(after()); | ^^^^ `std::rc::Rc>` cannot be sent between threads safely | = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` - = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:38:5: 38:22 p:std::rc::Rc>]` + = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:36:5: 36:22 p:std::rc::Rc>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` note: required by `send` - --> $DIR/auto-trait-leak.rs:24:1 + --> $DIR/auto-trait-leak.rs:22:1 | LL | fn send(_: T) {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0391]: cyclic dependency detected - --> $DIR/auto-trait-leak.rs:44:1 + --> $DIR/auto-trait-leak.rs:42:1 | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic reference | note: the cycle begins when processing `cycle1`... - --> $DIR/auto-trait-leak.rs:44:1 + --> $DIR/auto-trait-leak.rs:42:1 | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which then requires processing `cycle2::{{impl-Trait}}`... - --> $DIR/auto-trait-leak.rs:52:16 + --> $DIR/auto-trait-leak.rs:50:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which then requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:52:1 + --> $DIR/auto-trait-leak.rs:50:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which then requires processing `cycle1::{{impl-Trait}}`... - --> $DIR/auto-trait-leak.rs:44:16 + --> $DIR/auto-trait-leak.rs:42:16 | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 9d9d4cef3119..b65e477f21f9 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait, specialization)] +#![feature(specialization)] trait Foo: Copy + ToString {} diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs index f554efe90361..78ae922c7512 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant-closure.rs @@ -18,7 +18,6 @@ // run-pass #![allow(dead_code)] -#![feature(conservative_impl_trait)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs index 416bdae51784..972461c2ffd9 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound-contravariant.rs @@ -18,7 +18,6 @@ // run-pass #![allow(dead_code)] -#![feature(conservative_impl_trait)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs index 38c18ce61044..e73f15606dc5 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound.rs @@ -14,7 +14,6 @@ // See https://github.com/rust-lang/rust/issues/46541 for more details. #![allow(dead_code)] -#![feature(conservative_impl_trait)] #![feature(in_band_lifetimes)] #![feature(nll)] diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr index 5659fee9bedc..4281a4c10adf 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.stderr +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -1,11 +1,11 @@ error[E0909]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/region-escape-via-bound.rs:27:29 + --> $DIR/region-escape-via-bound.rs:26:29 | LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y> | ^^^^^^^^^^^^^^ | -note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 27:1 - --> $DIR/region-escape-via-bound.rs:27:1 +note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 26:1 + --> $DIR/region-escape-via-bound.rs:26:1 | LL | / fn foo(x: Cell<&'x u32>) -> impl Trait<'y> LL | | //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0909] diff --git a/src/test/ui/impl_trait_projections.rs b/src/test/ui/impl_trait_projections.rs index 05e88bf848d4..6a7279422710 100644 --- a/src/test/ui/impl_trait_projections.rs +++ b/src/test/ui/impl_trait_projections.rs @@ -7,7 +7,7 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(dyn_trait, conservative_impl_trait)] +#![feature(dyn_trait)] use std::fmt::Debug; use std::option; diff --git a/src/test/ui/issue-35869.rs b/src/test/ui/issue-35869.rs index 17ee62aed1b8..7bab22edcf68 100644 --- a/src/test/ui/issue-35869.rs +++ b/src/test/ui/issue-35869.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - trait Foo { fn foo(_: fn(u8) -> ()); fn bar(_: Option); diff --git a/src/test/ui/issue-35869.stderr b/src/test/ui/issue-35869.stderr index fa971c111a40..1930dd5bbcb8 100644 --- a/src/test/ui/issue-35869.stderr +++ b/src/test/ui/issue-35869.stderr @@ -1,5 +1,5 @@ error[E0053]: method `foo` has an incompatible type for trait - --> $DIR/issue-35869.rs:23:15 + --> $DIR/issue-35869.rs:21:15 | LL | fn foo(_: fn(u8) -> ()); | ------------ type in trait @@ -11,7 +11,7 @@ LL | fn foo(_: fn(u16) -> ()) {} found type `fn(fn(u16))` error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/issue-35869.rs:25:15 + --> $DIR/issue-35869.rs:23:15 | LL | fn bar(_: Option); | ---------- type in trait @@ -23,7 +23,7 @@ LL | fn bar(_: Option) {} found type `fn(std::option::Option)` error[E0053]: method `baz` has an incompatible type for trait - --> $DIR/issue-35869.rs:27:15 + --> $DIR/issue-35869.rs:25:15 | LL | fn baz(_: (u8, u16)); | --------- type in trait @@ -35,7 +35,7 @@ LL | fn baz(_: (u16, u16)) {} found type `fn((u16, u16))` error[E0053]: method `qux` has an incompatible type for trait - --> $DIR/issue-35869.rs:29:17 + --> $DIR/issue-35869.rs:27:17 | LL | fn qux() -> u8; | -- type in trait diff --git a/src/test/ui/nested_impl_trait.rs b/src/test/ui/nested_impl_trait.rs index 0fb1222d7973..be0454472dd0 100644 --- a/src/test/ui/nested_impl_trait.rs +++ b/src/test/ui/nested_impl_trait.rs @@ -7,8 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(conservative_impl_trait)] - use std::fmt::Debug; fn fine(x: impl Into) -> impl Into { x } diff --git a/src/test/ui/nested_impl_trait.stderr b/src/test/ui/nested_impl_trait.stderr index 10d767db8d32..ee53194e2b48 100644 --- a/src/test/ui/nested_impl_trait.stderr +++ b/src/test/ui/nested_impl_trait.stderr @@ -1,5 +1,5 @@ error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:16:56 + --> $DIR/nested_impl_trait.rs:14:56 | LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } | ----------^^^^^^^^^^- @@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:19:42 + --> $DIR/nested_impl_trait.rs:17:42 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | ----------^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:23:37 + --> $DIR/nested_impl_trait.rs:21:37 | LL | fn bad_in_arg_position(_: impl Into) { } | ----------^^^^^^^^^^- @@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into) { } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:28:44 + --> $DIR/nested_impl_trait.rs:26:44 | LL | fn bad(x: impl Into) -> impl Into { x } | ----------^^^^^^^^^^- @@ -35,13 +35,13 @@ LL | fn bad(x: impl Into) -> impl Into { x } | outer `impl Trait` error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/nested_impl_trait.rs:19:32 + --> $DIR/nested_impl_trait.rs:17:32 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into) {} | ^^^^^^^^^^^^^^^^^^^^^ error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/nested_impl_trait.rs:36:42 + --> $DIR/nested_impl_trait.rs:34:42 | LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into { | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs index 850cd1e7336d..571bd9fd76e8 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.rs +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.rs @@ -11,7 +11,6 @@ // compile-flags:-Znll -Zborrowck=mir -Zverbose #![allow(warnings)] -#![feature(conservative_impl_trait)] trait Foo<'a> { } diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr index bfa58bfc8074..92e4f72da3a1 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,11 +1,11 @@ warning: not reporting region error due to -Znll - --> $DIR/impl-trait-captures.rs:22:5 + --> $DIR/impl-trait-captures.rs:21:5 | LL | x | ^ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/impl-trait-captures.rs:22:5 + --> $DIR/impl-trait-captures.rs:21:5 | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { | - consider changing the type of `x` to `&ReEarlyBound(0, 'a) T` diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs index 135805a73394..2e0671f1a51e 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs +++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.rs @@ -11,7 +11,6 @@ // compile-flags:-Znll -Zborrowck=mir -Zverbose #![allow(warnings)] -#![feature(conservative_impl_trait)] use std::fmt::Debug; diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr index f29d2233e707..2b90d53774e6 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr @@ -1,17 +1,17 @@ warning: not reporting region error due to -Znll - --> $DIR/impl-trait-outlives.rs:18:35 + --> $DIR/impl-trait-outlives.rs:17:35 | LL | fn no_region<'a, T>(x: Box) -> impl Debug + 'a | ^^^^^^^^^^^^^^^ warning: not reporting region error due to -Znll - --> $DIR/impl-trait-outlives.rs:34:42 + --> $DIR/impl-trait-outlives.rs:33:42 | LL | fn wrong_region<'a, 'b, T>(x: Box) -> impl Debug + 'a | ^^^^^^^^^^^^^^^ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/impl-trait-outlives.rs:23:5 + --> $DIR/impl-trait-outlives.rs:22:5 | LL | x | ^ @@ -19,7 +19,7 @@ LL | x = help: consider adding an explicit lifetime bound `T: ReEarlyBound(0, 'a)`... error[E0309]: the parameter type `T` may not live long enough - --> $DIR/impl-trait-outlives.rs:39:5 + --> $DIR/impl-trait-outlives.rs:38:5 | LL | x | ^ diff --git a/src/tools/clippy b/src/tools/clippy index 4edd140e57cc..eafd09010815 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 4edd140e57cce900fa930e1439bab469f5bbce46 +Subproject commit eafd09010815da43302ac947afee45b0f5219e6b From 1e2458e1baf987ee67b4c48c0583dfad65f7dcd7 Mon Sep 17 00:00:00 2001 From: boats Date: Mon, 26 Mar 2018 06:25:31 -0700 Subject: [PATCH 625/830] Add is_whitespace and is_alphanumeric to str. The other methods from `UnicodeStr` are already stable inherent methods on str, but these have not been included. --- src/liballoc/str.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 14d5e96d2e73..d5ef41df0d85 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -2122,6 +2122,48 @@ impl str { unsafe { String::from_utf8_unchecked(buf) } } + /// Returns true if this `str` is entirely whitespace, and false otherwise. + /// + /// 'Whitespace' is defined according to the terms of the Unicode Derived Core + /// Property `White_Space`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!(" \t ".is_whitespace()); + /// + /// // a non-breaking space + /// assert!("\u{A0}".is_whitespace()); + /// + /// assert!(!" 越".is_whitespace()); + /// ``` + #[stable(feature = "unicode_methods_on_intrinsics", since = "1.27.0")] + #[inline] + pub fn is_whitespace(&self) -> bool { + UnicodeStr::is_whitespace(self) + } + + /// Returns true if this `str` is entirely alphanumeric, and false otherwise. + /// + /// 'Alphanumeric'-ness is defined in terms of the Unicode General Categories + /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert!("٣7৬Kو藏".is_alphanumeric()); + /// assert!(!"¾①".is_alphanumeric()); + /// ``` + #[stable(feature = "unicode_methods_on_intrinsics", since = "1.27.0")] + #[inline] + pub fn is_alphanumeric(&self) -> bool { + UnicodeStr::is_alphanumeric(self) + } + /// Checks if all characters in this string are within the ASCII range. /// /// # Examples From 7ce8191775b44d3773e28d647b5b17ec85508e16 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 16 Mar 2018 19:51:49 -0500 Subject: [PATCH 626/830] Stabilize i128_type --- src/liballoc/benches/lib.rs | 2 +- src/liballoc/lib.rs | 2 +- src/libcore/lib.rs | 2 +- src/libcore/num/mod.rs | 6 ++-- src/libcore/tests/lib.rs | 2 +- src/libproc_macro/lib.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc_apfloat/lib.rs | 2 +- src/librustc_apfloat/tests/ieee.rs | 2 +- src/librustc_const_eval/lib.rs | 2 +- src/librustc_const_math/lib.rs | 2 +- src/librustc_data_structures/lib.rs | 2 +- src/librustc_errors/lib.rs | 2 +- src/librustc_incremental/lib.rs | 2 +- src/librustc_lint/lib.rs | 2 +- src/librustc_metadata/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_resolve/lib.rs | 11 ------- src/librustc_trans/lib.rs | 2 +- src/librustc_trans_utils/lib.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/libserialize/lib.rs | 2 +- src/libstd/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 17 ++-------- src/libsyntax/lib.rs | 2 +- src/libsyntax_pos/lib.rs | 2 +- src/test/codegen/unchecked-float-casts.rs | 1 - src/test/mir-opt/lower_128bit_debug_test.rs | 1 - src/test/mir-opt/lower_128bit_test.rs | 1 - .../run-pass/float-int-invalid-const-cast.rs | 1 - src/test/run-pass/i128-ffi.rs | 2 -- src/test/run-pass/i128.rs | 2 +- src/test/run-pass/intrinsics-integer.rs | 2 +- src/test/run-pass/issue-38763.rs | 2 -- src/test/run-pass/issue-38987.rs | 1 - .../next-power-of-two-overflow-debug.rs | 2 -- .../next-power-of-two-overflow-ndebug.rs | 2 -- src/test/run-pass/saturating-float-casts.rs | 2 +- src/test/run-pass/u128-as-f32.rs | 2 +- src/test/run-pass/u128.rs | 2 +- src/test/ui/feature-gate-i128_type.rs | 18 ----------- src/test/ui/feature-gate-i128_type.stderr | 19 ----------- src/test/ui/feature-gate-i128_type2.rs | 8 ++--- src/test/ui/feature-gate-i128_type2.stderr | 32 ------------------- src/test/ui/lint-ctypes.rs | 2 +- src/test/ui/lint/type-overflow.rs | 2 -- 46 files changed, 37 insertions(+), 147 deletions(-) delete mode 100644 src/test/ui/feature-gate-i128_type.rs delete mode 100644 src/test/ui/feature-gate-i128_type.stderr diff --git a/src/liballoc/benches/lib.rs b/src/liballoc/benches/lib.rs index 2de0ffb4b261..09685d1bb40b 100644 --- a/src/liballoc/benches/lib.rs +++ b/src/liballoc/benches/lib.rs @@ -10,7 +10,7 @@ #![deny(warnings)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(rand)] #![feature(repr_simd)] #![feature(test)] diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index f914b1a93a91..19d64d8fea9e 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -97,7 +97,7 @@ #![feature(from_ref)] #![feature(fundamental)] #![feature(generic_param_attrs)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(iter_rfold)] #![feature(lang_items)] #![feature(needs_allocator)] diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 9aebe2e4ee4b..11fecde39516 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -78,7 +78,7 @@ #![feature(doc_spotlight)] #![feature(fn_must_use)] #![feature(fundamental)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(intrinsics)] #![feature(iterator_flatten)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 18e0aa453d8d..9ff42a6d4ea2 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1635,8 +1635,7 @@ impl i64 { #[lang = "i128"] impl i128 { int_impl! { i128, i128, u128, 128, -170141183460469231731687303715884105728, - 170141183460469231731687303715884105727, "#![feature(i128_type)] -#![feature(i128)] + 170141183460469231731687303715884105727, "#![feature(i128)] # fn main() { ", " # }" } @@ -3493,8 +3492,7 @@ impl u64 { #[lang = "u128"] impl u128 { - uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "#![feature(i128_type)] -#![feature(i128)] + uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "#![feature(i128)] # fn main() { ", " diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1c71669abb16..0b70f6924036 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -23,7 +23,7 @@ #![feature(fmt_internals)] #![feature(hashmap_internals)] #![feature(iterator_step_by)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(iterator_try_fold)] #![feature(iterator_flatten)] diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index d6e679bad48b..716a2cc6cbb1 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -34,7 +34,7 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(rustc_private)] #![feature(staged_api)] #![feature(lang_items)] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 1bb903c0627b..061044cdf143 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -53,7 +53,7 @@ #![feature(from_ref)] #![feature(fs_read_write)] #![feature(i128)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![cfg_attr(windows, feature(libc))] #![feature(match_default_bindings)] diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 565658804b00..2ee7bea84765 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -46,8 +46,8 @@ #![deny(warnings)] #![forbid(unsafe_code)] -#![feature(i128_type)] #![cfg_attr(stage0, feature(slice_patterns))] +#![cfg_attr(stage0, feature(i128_type))] #![feature(try_from)] // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. diff --git a/src/librustc_apfloat/tests/ieee.rs b/src/librustc_apfloat/tests/ieee.rs index ff46ee79c31d..627d79724b28 100644 --- a/src/librustc_apfloat/tests/ieee.rs +++ b/src/librustc_apfloat/tests/ieee.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #[macro_use] extern crate rustc_apfloat; diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index 2b0775e86952..2620448927d8 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -23,7 +23,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(macro_lifetime_matcher)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(from_ref)] extern crate arena; diff --git a/src/librustc_const_math/lib.rs b/src/librustc_const_math/lib.rs index 5555e727a955..a53055c7ce71 100644 --- a/src/librustc_const_math/lib.rs +++ b/src/librustc_const_math/lib.rs @@ -20,7 +20,7 @@ #![deny(warnings)] #![feature(i128)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] extern crate rustc_apfloat; diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index ff8690728713..01f91e37db84 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -26,7 +26,7 @@ #![feature(unboxed_closures)] #![feature(fn_traits)] #![feature(unsize)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(i128)] #![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(specialization)] diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 1152c9c574ec..37ae64cef572 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -18,7 +18,7 @@ #![feature(range_contains)] #![cfg_attr(unix, feature(libc))] #![cfg_attr(stage0, feature(conservative_impl_trait))] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(optin_builtin_traits)] extern crate atty; diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index 6adb950fe4ef..5a33f566e903 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -17,7 +17,7 @@ #![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(fs_read_write)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(specialization)] diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 4639f7b2d28c..d024adad9d03 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -27,7 +27,7 @@ #![cfg_attr(test, feature(test))] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(macro_vis_matcher)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 902dd87c5743..4af5ec9ae08e 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -16,7 +16,7 @@ #![feature(box_patterns)] #![cfg_attr(stage0, feature(conservative_impl_trait))] #![feature(fs_read_write)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(libc)] #![feature(macro_lifetime_matcher)] #![feature(proc_macro_internals)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 750839f8b001..a1f096b2a382 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -27,7 +27,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(decl_macro)] #![feature(dyn_trait)] #![feature(fs_read_write)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 2cb2c76c6320..01eda71e9b6c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3117,17 +3117,6 @@ impl<'a> Resolver<'a> { self.primitive_type_table.primitive_types .contains_key(&path[0].node.name) => { let prim = self.primitive_type_table.primitive_types[&path[0].node.name]; - match prim { - TyUint(UintTy::U128) | TyInt(IntTy::I128) => { - if !self.session.features_untracked().i128_type { - emit_feature_err(&self.session.parse_sess, - "i128_type", span, GateIssue::Language, - "128-bit type is unstable"); - - } - } - _ => {} - } PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1) } PathResult::Module(module) => PathResolution::new(module.def().unwrap()), diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 38adc603628e..d89d19db63e2 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -24,7 +24,7 @@ #![feature(custom_attribute)] #![feature(fs_read_write)] #![allow(unused_attributes)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(i128)] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(libc)] diff --git a/src/librustc_trans_utils/lib.rs b/src/librustc_trans_utils/lib.rs index 9e4addd1ed1b..99de124c6e1a 100644 --- a/src/librustc_trans_utils/lib.rs +++ b/src/librustc_trans_utils/lib.rs @@ -21,7 +21,7 @@ #![feature(box_syntax)] #![feature(custom_attribute)] #![allow(unused_attributes)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![cfg_attr(stage0, feature(conservative_impl_trait))] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index e466ef392348..8b3d5af3edd0 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -86,7 +86,7 @@ This API is completely unstable and subject to change. #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] #![feature(slice_patterns)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(never_type))] #[macro_use] extern crate log; diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 2e354252c157..ee9525234622 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -23,7 +23,7 @@ Core encoding and decoding interfaces. #![feature(box_syntax)] #![feature(core_intrinsics)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(specialization)] #![cfg_attr(test, feature(test))] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 0b06c5d4d656..3cc5d7b81c3a 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -270,7 +270,7 @@ #![feature(hashmap_internals)] #![feature(heap_api)] #![feature(i128)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(int_error_internals)] #![feature(integer_atomics)] #![feature(into_cow)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1bb369b551db..4e3c77d5e465 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -303,9 +303,6 @@ declare_features! ( // `extern "ptx-*" fn()` (active, abi_ptx, "1.15.0", None, None), - // The `i128` type - (active, i128_type, "1.16.0", Some(35118), None), - // The `repr(i128)` annotation for enums (active, repr128, "1.16.0", Some(35118), None), @@ -564,6 +561,8 @@ declare_features! ( (accepted, universal_impl_trait, "1.26.0", Some(34511), None), // Allows `impl Trait` in function return types. (accepted, conservative_impl_trait, "1.26.0", Some(34511), None), + // The `i128` type + (accepted, i128_type, "1.26.0", Some(35118), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1641,18 +1640,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { e.span, "yield syntax is experimental"); } - ast::ExprKind::Lit(ref lit) => { - if let ast::LitKind::Int(_, ref ty) = lit.node { - match *ty { - ast::LitIntType::Signed(ast::IntTy::I128) | - ast::LitIntType::Unsigned(ast::UintTy::U128) => { - gate_feature_post!(&self, i128_type, e.span, - "128-bit integers are not stable"); - } - _ => {} - } - } - } ast::ExprKind::Catch(_) => { gate_feature_post!(&self, catch_expr, e.span, "`catch` expression is experimental"); } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 74f1ee373ec6..2218b3966851 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -24,7 +24,7 @@ #![feature(rustc_diagnostic_macros)] #![feature(match_default_bindings)] #![feature(non_exhaustive)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(const_atomic_usize_new)] #![feature(rustc_attrs)] diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 5a7b7e9ceca5..eb345200f413 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -21,7 +21,7 @@ #![feature(const_fn)] #![feature(custom_attribute)] -#![feature(i128_type)] +#![cfg_attr(stage0, feature(i128_type))] #![feature(optin_builtin_traits)] #![allow(unused_attributes)] #![feature(specialization)] diff --git a/src/test/codegen/unchecked-float-casts.rs b/src/test/codegen/unchecked-float-casts.rs index c2fc29661709..87ebaaeec320 100644 --- a/src/test/codegen/unchecked-float-casts.rs +++ b/src/test/codegen/unchecked-float-casts.rs @@ -14,7 +14,6 @@ // -Z saturating-float-casts is not enabled. #![crate_type = "lib"] -#![feature(i128_type)] // CHECK-LABEL: @f32_to_u32 #[no_mangle] diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs index 1752445a141c..d7586b1aa4b1 100644 --- a/src/test/mir-opt/lower_128bit_debug_test.rs +++ b/src/test/mir-opt/lower_128bit_debug_test.rs @@ -15,7 +15,6 @@ // compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=yes -#![feature(i128_type)] #![feature(const_fn)] static TEST_SIGNED: i128 = const_signed(-222); diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs index 4058eaef9b0a..341682debeb3 100644 --- a/src/test/mir-opt/lower_128bit_test.rs +++ b/src/test/mir-opt/lower_128bit_test.rs @@ -15,7 +15,6 @@ // compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no -#![feature(i128_type)] #![feature(const_fn)] static TEST_SIGNED: i128 = const_signed(-222); diff --git a/src/test/run-pass/float-int-invalid-const-cast.rs b/src/test/run-pass/float-int-invalid-const-cast.rs index d44f78922c70..f84432abbfa0 100644 --- a/src/test/run-pass/float-int-invalid-const-cast.rs +++ b/src/test/run-pass/float-int-invalid-const-cast.rs @@ -10,7 +10,6 @@ // ignore-emscripten no i128 support -#![feature(i128_type)] #![deny(const_err)] use std::{f32, f64}; diff --git a/src/test/run-pass/i128-ffi.rs b/src/test/run-pass/i128-ffi.rs index d989210dd71f..edf278cbf64a 100644 --- a/src/test/run-pass/i128-ffi.rs +++ b/src/test/run-pass/i128-ffi.rs @@ -15,8 +15,6 @@ // ignore-windows // ignore-32bit -#![feature(i128_type)] - #[link(name = "rust_test_helpers", kind = "static")] extern "C" { fn identity(f: u128) -> u128; diff --git a/src/test/run-pass/i128.rs b/src/test/run-pass/i128.rs index c3e43c92590e..baf3b3399849 100644 --- a/src/test/run-pass/i128.rs +++ b/src/test/run-pass/i128.rs @@ -12,7 +12,7 @@ // compile-flags: -Z borrowck=compare -#![feature(i128_type, test)] +#![feature(test)] extern crate test; use test::black_box as b; diff --git a/src/test/run-pass/intrinsics-integer.rs b/src/test/run-pass/intrinsics-integer.rs index cdfad51e648a..7a8ff1befc7f 100644 --- a/src/test/run-pass/intrinsics-integer.rs +++ b/src/test/run-pass/intrinsics-integer.rs @@ -10,7 +10,7 @@ // ignore-emscripten no i128 support -#![feature(intrinsics, i128_type)] +#![feature(intrinsics)] mod rusti { extern "rust-intrinsic" { diff --git a/src/test/run-pass/issue-38763.rs b/src/test/run-pass/issue-38763.rs index 01cc8265a399..e038062ff9ae 100644 --- a/src/test/run-pass/issue-38763.rs +++ b/src/test/run-pass/issue-38763.rs @@ -10,8 +10,6 @@ // ignore-emscripten -#![feature(i128_type)] - #[repr(C)] pub struct Foo(i128); diff --git a/src/test/run-pass/issue-38987.rs b/src/test/run-pass/issue-38987.rs index a513476d4a33..31a3b7233d8c 100644 --- a/src/test/run-pass/issue-38987.rs +++ b/src/test/run-pass/issue-38987.rs @@ -7,7 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(i128_type)] fn main() { let _ = -0x8000_0000_0000_0000_0000_0000_0000_0000i128; diff --git a/src/test/run-pass/next-power-of-two-overflow-debug.rs b/src/test/run-pass/next-power-of-two-overflow-debug.rs index 599c6dfd31d9..2135b3f8764c 100644 --- a/src/test/run-pass/next-power-of-two-overflow-debug.rs +++ b/src/test/run-pass/next-power-of-two-overflow-debug.rs @@ -12,8 +12,6 @@ // ignore-wasm32-bare compiled with panic=abort by default // ignore-emscripten dies with an LLVM error -#![feature(i128_type)] - use std::panic; fn main() { diff --git a/src/test/run-pass/next-power-of-two-overflow-ndebug.rs b/src/test/run-pass/next-power-of-two-overflow-ndebug.rs index f2312b70be67..b05c1863d902 100644 --- a/src/test/run-pass/next-power-of-two-overflow-ndebug.rs +++ b/src/test/run-pass/next-power-of-two-overflow-ndebug.rs @@ -11,8 +11,6 @@ // compile-flags: -C debug_assertions=no // ignore-emscripten dies with an LLVM error -#![feature(i128_type)] - fn main() { for i in 129..256 { assert_eq!((i as u8).next_power_of_two(), 0); diff --git a/src/test/run-pass/saturating-float-casts.rs b/src/test/run-pass/saturating-float-casts.rs index c8fa49c62a0b..d1a0901bb3d6 100644 --- a/src/test/run-pass/saturating-float-casts.rs +++ b/src/test/run-pass/saturating-float-casts.rs @@ -11,7 +11,7 @@ // Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction. // compile-flags: -Z saturating-float-casts -#![feature(test, i128, i128_type, stmt_expr_attributes)] +#![feature(test, i128, stmt_expr_attributes)] #![deny(overflowing_literals)] extern crate test; diff --git a/src/test/run-pass/u128-as-f32.rs b/src/test/run-pass/u128-as-f32.rs index 117e520155fd..3531a961befd 100644 --- a/src/test/run-pass/u128-as-f32.rs +++ b/src/test/run-pass/u128-as-f32.rs @@ -10,7 +10,7 @@ // ignore-emscripten u128 not supported -#![feature(test, i128, i128_type)] +#![feature(test, i128)] #![deny(overflowing_literals)] extern crate test; diff --git a/src/test/run-pass/u128.rs b/src/test/run-pass/u128.rs index ebd43a860338..d649b3b74d39 100644 --- a/src/test/run-pass/u128.rs +++ b/src/test/run-pass/u128.rs @@ -12,7 +12,7 @@ // compile-flags: -Z borrowck=compare -#![feature(i128_type, test)] +#![feature(test)] extern crate test; use test::black_box as b; diff --git a/src/test/ui/feature-gate-i128_type.rs b/src/test/ui/feature-gate-i128_type.rs deleted file mode 100644 index ddb49a3e5d92..000000000000 --- a/src/test/ui/feature-gate-i128_type.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -fn test2() { - 0i128; //~ ERROR 128-bit integers are not stable -} - -fn test2_2() { - 0u128; //~ ERROR 128-bit integers are not stable -} - diff --git a/src/test/ui/feature-gate-i128_type.stderr b/src/test/ui/feature-gate-i128_type.stderr deleted file mode 100644 index eb3b29f4f559..000000000000 --- a/src/test/ui/feature-gate-i128_type.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0658]: 128-bit integers are not stable (see issue #35118) - --> $DIR/feature-gate-i128_type.rs:12:5 - | -LL | 0i128; //~ ERROR 128-bit integers are not stable - | ^^^^^ - | - = help: add #![feature(i128_type)] to the crate attributes to enable - -error[E0658]: 128-bit integers are not stable (see issue #35118) - --> $DIR/feature-gate-i128_type.rs:16:5 - | -LL | 0u128; //~ ERROR 128-bit integers are not stable - | ^^^^^ - | - = help: add #![feature(i128_type)] to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-i128_type2.rs b/src/test/ui/feature-gate-i128_type2.rs index 8a7d316ed838..cd65b9d92233 100644 --- a/src/test/ui/feature-gate-i128_type2.rs +++ b/src/test/ui/feature-gate-i128_type2.rs @@ -10,20 +10,20 @@ // gate-test-i128_type -fn test1() -> i128 { //~ ERROR 128-bit type is unstable +fn test1() -> i128 { 0 } -fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable +fn test1_2() -> u128 { 0 } fn test3() { - let x: i128 = 0; //~ ERROR 128-bit type is unstable + let x: i128 = 0; } fn test3_2() { - let x: u128 = 0; //~ ERROR 128-bit type is unstable + let x: u128 = 0; } #[repr(u128)] diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr index 23d4d6c98d90..fe4557899acd 100644 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ b/src/test/ui/feature-gate-i128_type2.stderr @@ -1,35 +1,3 @@ -error[E0658]: 128-bit type is unstable (see issue #35118) - --> $DIR/feature-gate-i128_type2.rs:13:15 - | -LL | fn test1() -> i128 { //~ ERROR 128-bit type is unstable - | ^^^^ - | - = help: add #![feature(i128_type)] to the crate attributes to enable - -error[E0658]: 128-bit type is unstable (see issue #35118) - --> $DIR/feature-gate-i128_type2.rs:17:17 - | -LL | fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable - | ^^^^ - | - = help: add #![feature(i128_type)] to the crate attributes to enable - -error[E0658]: 128-bit type is unstable (see issue #35118) - --> $DIR/feature-gate-i128_type2.rs:22:12 - | -LL | let x: i128 = 0; //~ ERROR 128-bit type is unstable - | ^^^^ - | - = help: add #![feature(i128_type)] to the crate attributes to enable - -error[E0658]: 128-bit type is unstable (see issue #35118) - --> $DIR/feature-gate-i128_type2.rs:26:12 - | -LL | let x: u128 = 0; //~ ERROR 128-bit type is unstable - | ^^^^ - | - = help: add #![feature(i128_type)] to the crate attributes to enable - error[E0658]: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:30:1 | diff --git a/src/test/ui/lint-ctypes.rs b/src/test/ui/lint-ctypes.rs index 77cb1ef0f513..85957831653e 100644 --- a/src/test/ui/lint-ctypes.rs +++ b/src/test/ui/lint-ctypes.rs @@ -9,7 +9,7 @@ // except according to those terms. #![deny(improper_ctypes)] -#![feature(libc, i128_type, repr_transparent)] +#![feature(libc, repr_transparent)] extern crate libc; diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs index 495989587e58..30e6fb2883b8 100644 --- a/src/test/ui/lint/type-overflow.rs +++ b/src/test/ui/lint/type-overflow.rs @@ -10,8 +10,6 @@ // must-compile-successfully -#![feature(i128_type)] - fn main() { let error = 255i8; //~WARNING literal out of range for i8 From 33d9d8e0c62e6eeb3c9406a251312c630c2b3596 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 16 Mar 2018 19:54:20 -0500 Subject: [PATCH 627/830] Update nightly book --- .../src/language-features/i128-type.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/i128-type.md b/src/doc/unstable-book/src/language-features/i128-type.md index a850b7644c3a..6f46469f3249 100644 --- a/src/doc/unstable-book/src/language-features/i128-type.md +++ b/src/doc/unstable-book/src/language-features/i128-type.md @@ -1,4 +1,4 @@ -# `i128_type` +# `i128` The tracking issue for this feature is: [#35118] @@ -6,20 +6,13 @@ The tracking issue for this feature is: [#35118] ------------------------ -The `i128_type` feature adds support for 128 bit signed and unsigned integer -types. +The `i128` feature adds support for `#[repr(u128)]` on `enum`s. ```rust -#![feature(i128_type)] +#![feature(i128)] -fn main() { - assert_eq!(1u128 + 1u128, 2u128); - assert_eq!(u128::min_value(), 0); - assert_eq!(u128::max_value(), 340282366920938463463374607431768211455); - - assert_eq!(1i128 - 2i128, -1i128); - assert_eq!(i128::min_value(), -170141183460469231731687303715884105728); - assert_eq!(i128::max_value(), 170141183460469231731687303715884105727); +#[repr(u128)] +enum Foo { + Bar(u64), } ``` - From db7d9ea480e16c7135c997f56b44d3c0a657cc9d Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 16 Mar 2018 20:15:56 -0500 Subject: [PATCH 628/830] Stabilize i128 feature too --- .../unstable-book/src/language-features/i128-type.md | 2 +- src/libcore/num/i128.rs | 4 ++-- src/libcore/num/mod.rs | 11 ++--------- src/librustc/lib.rs | 3 +-- src/librustc_const_math/lib.rs | 3 +-- src/librustc_data_structures/lib.rs | 3 +-- src/librustc_trans/lib.rs | 3 +-- src/libstd/lib.rs | 7 +++---- src/libsyntax/diagnostic_list.rs | 12 ++++++++---- src/test/ui/error-codes/E0658.stderr | 2 +- 10 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/i128-type.md b/src/doc/unstable-book/src/language-features/i128-type.md index 6f46469f3249..ff5fc0fdc15b 100644 --- a/src/doc/unstable-book/src/language-features/i128-type.md +++ b/src/doc/unstable-book/src/language-features/i128-type.md @@ -9,7 +9,7 @@ The tracking issue for this feature is: [#35118] The `i128` feature adds support for `#[repr(u128)]` on `enum`s. ```rust -#![feature(i128)] +#![feature(repri128)] #[repr(u128)] enum Foo { diff --git a/src/libcore/num/i128.rs b/src/libcore/num/i128.rs index 04354e2e33f9..989376d1ac2d 100644 --- a/src/libcore/num/i128.rs +++ b/src/libcore/num/i128.rs @@ -12,6 +12,6 @@ //! //! *[See also the `i128` primitive type](../../std/primitive.i128.html).* -#![unstable(feature = "i128", issue="35118")] +#![stable(feature = "i128", since = "1.26.0")] -int_module! { i128, #[unstable(feature = "i128", issue="35118")] } +int_module! { i128, #[stable(feature = "i128", since="1.26.0")] } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 9ff42a6d4ea2..66f7160827ab 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1635,10 +1635,7 @@ impl i64 { #[lang = "i128"] impl i128 { int_impl! { i128, i128, u128, 128, -170141183460469231731687303715884105728, - 170141183460469231731687303715884105727, "#![feature(i128)] -# fn main() { -", " -# }" } + 170141183460469231731687303715884105727, "", "" } } #[cfg(target_pointer_width = "16")] @@ -3492,11 +3489,7 @@ impl u64 { #[lang = "u128"] impl u128 { - uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "#![feature(i128)] - -# fn main() { -", " -# }" } + uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "", "" } } #[cfg(target_pointer_width = "16")] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 061044cdf143..e835d6192e54 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -52,8 +52,7 @@ #![feature(entry_or_default)] #![feature(from_ref)] #![feature(fs_read_write)] -#![feature(i128)] -#![cfg_attr(stage0, feature(i128_type))] +#![cfg_attr(stage0, feature(i128_type, i128))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![cfg_attr(windows, feature(libc))] #![feature(match_default_bindings)] diff --git a/src/librustc_const_math/lib.rs b/src/librustc_const_math/lib.rs index a53055c7ce71..7177e2818fbc 100644 --- a/src/librustc_const_math/lib.rs +++ b/src/librustc_const_math/lib.rs @@ -19,8 +19,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] -#![feature(i128)] -#![cfg_attr(stage0, feature(i128_type))] +#![cfg_attr(stage0, feature(i128_type, i128))] extern crate rustc_apfloat; diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 01f91e37db84..378a06dd9120 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -26,9 +26,8 @@ #![feature(unboxed_closures)] #![feature(fn_traits)] #![feature(unsize)] -#![cfg_attr(stage0, feature(i128_type))] -#![feature(i128)] #![cfg_attr(stage0, feature(conservative_impl_trait))] +#![cfg_attr(stage0, feature(i128_type, i128))] #![feature(specialization)] #![feature(optin_builtin_traits)] #![feature(underscore_lifetimes)] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index d89d19db63e2..bd33707b1c6f 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -24,8 +24,7 @@ #![feature(custom_attribute)] #![feature(fs_read_write)] #![allow(unused_attributes)] -#![cfg_attr(stage0, feature(i128_type))] -#![feature(i128)] +#![cfg_attr(stage0, feature(i128_type, i128))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(libc)] #![feature(quote)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 3cc5d7b81c3a..93996868f16c 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -269,8 +269,7 @@ #![feature(generic_param_attrs)] #![feature(hashmap_internals)] #![feature(heap_api)] -#![feature(i128)] -#![cfg_attr(stage0, feature(i128_type))] +#![cfg_attr(stage0, feature(i128_type, i128))] #![feature(int_error_internals)] #![feature(integer_atomics)] #![feature(into_cow)] @@ -435,7 +434,7 @@ pub use core::i16; pub use core::i32; #[stable(feature = "rust1", since = "1.0.0")] pub use core::i64; -#[unstable(feature = "i128", issue = "35118")] +#[stable(feature = "i128", since = "1.26.0")] pub use core::i128; #[stable(feature = "rust1", since = "1.0.0")] pub use core::usize; @@ -465,7 +464,7 @@ pub use alloc::string; pub use alloc::vec; #[stable(feature = "rust1", since = "1.0.0")] pub use std_unicode::char; -#[unstable(feature = "i128", issue = "35118")] +#[stable(feature = "i128", since = "1.26.0")] pub use core::u128; pub mod f32; diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 1f87c1b94c50..3246dc47701e 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -250,7 +250,10 @@ An unstable feature was used. Erroneous code example: ```compile_fail,E658 -let x = ::std::u128::MAX; // error: use of unstable library feature 'i128' +#[repr(u128)] // error: use of unstable library feature 'i128' +enum Foo { + Bar(u64), +} ``` If you're using a stable or a beta version of rustc, you won't be able to use @@ -261,10 +264,11 @@ If you're using a nightly version of rustc, just add the corresponding feature to be able to use it: ``` -#![feature(i128)] +#![feature(repri128)] -fn main() { - let x = ::std::u128::MAX; // ok! +#[repr(u128)] // ok! +enum Foo { + Bar(u64), } ``` "##, diff --git a/src/test/ui/error-codes/E0658.stderr b/src/test/ui/error-codes/E0658.stderr index 5be05600ee51..f4294e6b0269 100644 --- a/src/test/ui/error-codes/E0658.stderr +++ b/src/test/ui/error-codes/E0658.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature 'i128' (see issue #35118) LL | let _ = ::std::u128::MAX; //~ ERROR E0658 | ^^^^^^^^^^^^^^^^ | - = help: add #![feature(i128)] to the crate attributes to enable + = help: add #![feature(repri128)] to the crate attributes to enable error: aborting due to previous error From a89d1d0b02eba0cbfc4d232824f23bcbdd86d850 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 16 Mar 2018 20:20:06 -0500 Subject: [PATCH 629/830] Rename unstable-book chapter --- .../src/language-features/{i128-type.md => repri128.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/doc/unstable-book/src/language-features/{i128-type.md => repri128.md} (100%) diff --git a/src/doc/unstable-book/src/language-features/i128-type.md b/src/doc/unstable-book/src/language-features/repri128.md similarity index 100% rename from src/doc/unstable-book/src/language-features/i128-type.md rename to src/doc/unstable-book/src/language-features/repri128.md From a249d25625fa816ec6448d4784efd8370eb09c17 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 16 Mar 2018 20:21:35 -0500 Subject: [PATCH 630/830] Rename unstable book correctly --- .../src/language-features/{repri128.md => repr128.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename src/doc/unstable-book/src/language-features/{repri128.md => repr128.md} (65%) diff --git a/src/doc/unstable-book/src/language-features/repri128.md b/src/doc/unstable-book/src/language-features/repr128.md similarity index 65% rename from src/doc/unstable-book/src/language-features/repri128.md rename to src/doc/unstable-book/src/language-features/repr128.md index ff5fc0fdc15b..3c86d581fa72 100644 --- a/src/doc/unstable-book/src/language-features/repri128.md +++ b/src/doc/unstable-book/src/language-features/repr128.md @@ -1,4 +1,4 @@ -# `i128` +# `repri128` The tracking issue for this feature is: [#35118] @@ -6,10 +6,10 @@ The tracking issue for this feature is: [#35118] ------------------------ -The `i128` feature adds support for `#[repr(u128)]` on `enum`s. +The `repr128` feature adds support for `#[repr(u128)]` on `enum`s. ```rust -#![feature(repri128)] +#![feature(repr128)] #[repr(u128)] enum Foo { From ea89b507b37e089e87af5646042b911c84656b4a Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 16 Mar 2018 20:38:59 -0500 Subject: [PATCH 631/830] remove unneeded import --- src/librustc_resolve/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 01eda71e9b6c..b5043f24eb06 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -57,7 +57,7 @@ use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, GenericParam, Generics}; use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind}; use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path}; use syntax::ast::{QSelf, TraitItemKind, TraitRef, Ty, TyKind}; -use syntax::feature_gate::{feature_err, emit_feature_err, GateIssue}; +use syntax::feature_gate::{feature_err, GateIssue}; use syntax::parse::token; use syntax::ptr::P; From 07104692d5df1401fe0109fca800e4efe4e81a6c Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 17 Mar 2018 11:46:31 -0500 Subject: [PATCH 632/830] Fix missed i128 feature gates --- .../src/language-features/repr128.md | 2 +- src/libcore/num/mod.rs | 24 ++++++------- src/libstd/primitive_docs.rs | 4 +-- src/libsyntax/diagnostic_list.rs | 4 +-- src/test/run-pass/saturating-float-casts.rs | 2 +- src/test/run-pass/u128-as-f32.rs | 2 +- src/test/ui/feature-gate-i128_type2.rs | 34 ------------------- src/test/ui/feature-gate-i128_type2.stderr | 13 ------- 8 files changed, 19 insertions(+), 66 deletions(-) delete mode 100644 src/test/ui/feature-gate-i128_type2.rs delete mode 100644 src/test/ui/feature-gate-i128_type2.stderr diff --git a/src/doc/unstable-book/src/language-features/repr128.md b/src/doc/unstable-book/src/language-features/repr128.md index 3c86d581fa72..0858988952c1 100644 --- a/src/doc/unstable-book/src/language-features/repr128.md +++ b/src/doc/unstable-book/src/language-features/repr128.md @@ -1,4 +1,4 @@ -# `repri128` +# `repr128` The tracking issue for this feature is: [#35118] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 66f7160827ab..55186b0a3aca 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -4046,39 +4046,39 @@ macro_rules! impl_from { impl_from! { u8, u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { u8, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { u8, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { u8, u128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u8, u128, #[stable(feature = "i128", since = "1.26.0")] } impl_from! { u8, usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { u16, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { u16, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { u16, u128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u16, u128, #[stable(feature = "i128", since = "1.26.0")] } impl_from! { u32, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { u32, u128, #[unstable(feature = "i128", issue = "35118")] } -impl_from! { u64, u128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u32, u128, #[stable(feature = "i128", since = "1.26.0")] } +impl_from! { u64, u128, #[stable(feature = "i128", since = "1.26.0")] } // Signed -> Signed impl_from! { i8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { i8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { i8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { i8, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { i8, i128, #[stable(feature = "i128", since = "1.26.0")] } impl_from! { i8, isize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { i16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { i16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { i16, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { i16, i128, #[stable(feature = "i128", since = "1.26.0")] } impl_from! { i32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { i32, i128, #[unstable(feature = "i128", issue = "35118")] } -impl_from! { i64, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { i32, i128, #[stable(feature = "i128", since = "1.26.0")] } +impl_from! { i64, i128, #[stable(feature = "i128", since = "1.26.0")] } // Unsigned -> Signed impl_from! { u8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { u8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { u8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { u8, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u8, i128, #[stable(feature = "i128", since = "1.26.0")] } impl_from! { u16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } impl_from! { u16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { u16, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u16, i128, #[stable(feature = "i128", since = "1.26.0")] } impl_from! { u32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] } -impl_from! { u32, i128, #[unstable(feature = "i128", issue = "35118")] } -impl_from! { u64, i128, #[unstable(feature = "i128", issue = "35118")] } +impl_from! { u32, i128, #[stable(feature = "i128", since = "1.26.0")] } +impl_from! { u64, i128, #[stable(feature = "i128", since = "1.26.0")] } // Note: integers can only be represented with full precision in a float if // they fit in the significand, which is 24 bits in f32 and 53 bits in f64. diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index e6e6be2e4537..ce4bbfffc2e4 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -751,7 +751,7 @@ mod prim_i64 { } /// The 128-bit signed integer type. /// /// *[See also the `std::i128` module](i128/index.html).* -#[unstable(feature = "i128", issue="35118")] +#[stable(feature = "i128", since="1.26.0")] mod prim_i128 { } #[doc(primitive = "u8")] @@ -791,7 +791,7 @@ mod prim_u64 { } /// The 128-bit unsigned integer type. /// /// *[See also the `std::u128` module](u128/index.html).* -#[unstable(feature = "i128", issue="35118")] +#[stable(feature = "i128", since="1.26.0")] mod prim_u128 { } #[doc(primitive = "isize")] diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 3246dc47701e..bb7988e64bce 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -250,7 +250,7 @@ An unstable feature was used. Erroneous code example: ```compile_fail,E658 -#[repr(u128)] // error: use of unstable library feature 'i128' +#[repr(u128)] // error: use of unstable library feature 'repr128' enum Foo { Bar(u64), } @@ -264,7 +264,7 @@ If you're using a nightly version of rustc, just add the corresponding feature to be able to use it: ``` -#![feature(repri128)] +#![feature(repr128)] #[repr(u128)] // ok! enum Foo { diff --git a/src/test/run-pass/saturating-float-casts.rs b/src/test/run-pass/saturating-float-casts.rs index d1a0901bb3d6..ad3b4b172594 100644 --- a/src/test/run-pass/saturating-float-casts.rs +++ b/src/test/run-pass/saturating-float-casts.rs @@ -11,7 +11,7 @@ // Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction. // compile-flags: -Z saturating-float-casts -#![feature(test, i128, stmt_expr_attributes)] +#![feature(test, stmt_expr_attributes)] #![deny(overflowing_literals)] extern crate test; diff --git a/src/test/run-pass/u128-as-f32.rs b/src/test/run-pass/u128-as-f32.rs index 3531a961befd..2848fb2d51a6 100644 --- a/src/test/run-pass/u128-as-f32.rs +++ b/src/test/run-pass/u128-as-f32.rs @@ -10,7 +10,7 @@ // ignore-emscripten u128 not supported -#![feature(test, i128)] +#![feature(test)] #![deny(overflowing_literals)] extern crate test; diff --git a/src/test/ui/feature-gate-i128_type2.rs b/src/test/ui/feature-gate-i128_type2.rs deleted file mode 100644 index cd65b9d92233..000000000000 --- a/src/test/ui/feature-gate-i128_type2.rs +++ /dev/null @@ -1,34 +0,0 @@ -// 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. - -// gate-test-i128_type - -fn test1() -> i128 { - 0 -} - -fn test1_2() -> u128 { - 0 -} - -fn test3() { - let x: i128 = 0; -} - -fn test3_2() { - let x: u128 = 0; -} - -#[repr(u128)] -enum A { //~ ERROR 128-bit type is unstable - A(u64) -} - -fn main() {} diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr deleted file mode 100644 index fe4557899acd..000000000000 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: repr with 128-bit type is unstable (see issue #35118) - --> $DIR/feature-gate-i128_type2.rs:30:1 - | -LL | / enum A { //~ ERROR 128-bit type is unstable -LL | | A(u64) -LL | | } - | |_^ - | - = help: add #![feature(repr128)] to the crate attributes to enable - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0658`. From a7f21f1c0a57984eb9a04b39223ae0c5b1cf63fb Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 17 Mar 2018 11:55:44 -0500 Subject: [PATCH 633/830] Fix a few more --- src/libcore/num/u128.rs | 4 ++-- src/libstd/net/ip.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/u128.rs b/src/libcore/num/u128.rs index 987ac3e00073..e8c783a1bb54 100644 --- a/src/libcore/num/u128.rs +++ b/src/libcore/num/u128.rs @@ -12,5 +12,5 @@ //! //! *[See also the `u128` primitive type](../../std/primitive.u128.html).* -#![unstable(feature = "i128", issue="35118")] -uint_module! { u128, #[unstable(feature = "i128", issue="35118")] } +#![stable(feature = "i128", since = "1.26.0")] +uint_module! { u128, #[stable(feature = "i128", since="1.26.0")] } diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 0d73a6f4fd7f..36376c077910 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -1346,7 +1346,7 @@ impl FromInner for Ipv6Addr { } } -#[unstable(feature = "i128", issue = "35118")] +#[stable(feature = "i128", since = "1.26.0")] impl From for u128 { fn from(ip: Ipv6Addr) -> u128 { let ip = ip.segments(); @@ -1355,7 +1355,7 @@ impl From for u128 { ((ip[6] as u128) << 16) + (ip[7] as u128) } } -#[unstable(feature = "i128", issue = "35118")] +#[stable(feature = "i128", since = "1.26.0")] impl From for Ipv6Addr { fn from(ip: u128) -> Ipv6Addr { Ipv6Addr::new( From 463865e6957f8b698349460cb231f9d641300df0 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 17 Mar 2018 20:10:18 -0500 Subject: [PATCH 634/830] Fix a few more unstables that I missed --- src/libcore/hash/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index ab714645675a..3e1f21cafe41 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -308,7 +308,7 @@ pub trait Hasher { } /// Writes a single `u128` into this hasher. #[inline] - #[unstable(feature = "i128", issue = "35118")] + #[stable(feature = "i128", since = "1.26.0")] fn write_u128(&mut self, i: u128) { self.write(&unsafe { mem::transmute::<_, [u8; 16]>(i) }) } @@ -348,7 +348,7 @@ pub trait Hasher { } /// Writes a single `i128` into this hasher. #[inline] - #[unstable(feature = "i128", issue = "35118")] + #[stable(feature = "i128", since = "1.26.0")] fn write_i128(&mut self, i: i128) { self.write_u128(i as u128) } From 1fd964b5cb305997ba3428d94e9d72da61ca4769 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 17 Mar 2018 20:39:19 -0500 Subject: [PATCH 635/830] update test --- src/test/ui/lint/type-overflow.stderr | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index d3fcb1335e20..6f5d3d07aea2 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -1,5 +1,5 @@ warning: literal out of range for i8 - --> $DIR/type-overflow.rs:16:17 + --> $DIR/type-overflow.rs:14:17 | LL | let error = 255i8; //~WARNING literal out of range for i8 | ^^^^^ @@ -7,7 +7,7 @@ LL | let error = 255i8; //~WARNING literal out of range for i8 = note: #[warn(overflowing_literals)] on by default warning: literal out of range for i8 - --> $DIR/type-overflow.rs:21:16 + --> $DIR/type-overflow.rs:19:16 | LL | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 | ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8` @@ -15,7 +15,7 @@ LL | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8` warning: literal out of range for i64 - --> $DIR/type-overflow.rs:23:16 + --> $DIR/type-overflow.rs:21:16 | LL | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64` @@ -23,7 +23,7 @@ LL | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range fo = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64` warning: literal out of range for u32 - --> $DIR/type-overflow.rs:25:16 + --> $DIR/type-overflow.rs:23:16 | LL | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 | ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64` @@ -31,7 +31,7 @@ LL | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32` warning: literal out of range for i128 - --> $DIR/type-overflow.rs:27:22 + --> $DIR/type-overflow.rs:25:22 | LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; = help: consider using `u128` instead warning: literal out of range for i32 - --> $DIR/type-overflow.rs:30:16 + --> $DIR/type-overflow.rs:28:16 | LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 | ^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i = help: consider using `i128` instead warning: literal out of range for i8 - --> $DIR/type-overflow.rs:32:17 + --> $DIR/type-overflow.rs:30:17 | LL | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 | ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16` From afc9890309230ce8b4b312fda993980311d221c2 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 17 Mar 2018 21:08:32 -0500 Subject: [PATCH 636/830] Fix e0658 ui test --- src/test/ui/error-codes/E0658.rs | 7 +++++-- src/test/ui/error-codes/E0658.stderr | 12 +++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/test/ui/error-codes/E0658.rs b/src/test/ui/error-codes/E0658.rs index d30068eb1fe2..dcfa25e528ac 100644 --- a/src/test/ui/error-codes/E0658.rs +++ b/src/test/ui/error-codes/E0658.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn main() { - let _ = ::std::u128::MAX; //~ ERROR E0658 +#[repr(u128)] +enum Foo { //~ ERROR E0658 + Bar(u64), } + +fn main() {} diff --git a/src/test/ui/error-codes/E0658.stderr b/src/test/ui/error-codes/E0658.stderr index f4294e6b0269..b338b384a117 100644 --- a/src/test/ui/error-codes/E0658.stderr +++ b/src/test/ui/error-codes/E0658.stderr @@ -1,10 +1,12 @@ -error[E0658]: use of unstable library feature 'i128' (see issue #35118) - --> $DIR/E0658.rs:12:13 +error[E0658]: repr with 128-bit type is unstable (see issue #35118) + --> $DIR/E0658.rs:12:1 | -LL | let _ = ::std::u128::MAX; //~ ERROR E0658 - | ^^^^^^^^^^^^^^^^ +LL | / enum Foo { //~ ERROR E0658 +LL | | Bar(u64), +LL | | } + | |_^ | - = help: add #![feature(repri128)] to the crate attributes to enable + = help: add #![feature(repr128)] to the crate attributes to enable error: aborting due to previous error From ec9871818b5bcd8d1afd127f64ba5b1ed6d5c811 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 17 Mar 2018 21:19:36 -0500 Subject: [PATCH 637/830] Remove library feature test --- src/test/compile-fail/i128-feature-libs.rs | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 src/test/compile-fail/i128-feature-libs.rs diff --git a/src/test/compile-fail/i128-feature-libs.rs b/src/test/compile-fail/i128-feature-libs.rs deleted file mode 100644 index b29ac50fd377..000000000000 --- a/src/test/compile-fail/i128-feature-libs.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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 testl() { - ::std::u128::MAX; //~ ERROR use of unstable library feature 'i128' -} - -fn testl2() { - ::std::i128::MAX; //~ ERROR use of unstable library feature 'i128' -} From 66c8cdbab48fbbc9d4bb6204b4648fa101ed1026 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 20 Mar 2018 10:14:06 -0500 Subject: [PATCH 638/830] Update to master of libcompiler_builtins --- src/libcompiler_builtins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins index 266ea0740a5b..34f5d4aa3870 160000 --- a/src/libcompiler_builtins +++ b/src/libcompiler_builtins @@ -1 +1 @@ -Subproject commit 266ea0740a5bdd262a38bbd88fb55fc3d2a7a96e +Subproject commit 34f5d4aa3870afc6646dac03963d1d26891c4f60 From 6b625b334155aabebeca87c49689d38ffe8aa700 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Tue, 20 Mar 2018 20:56:53 -0500 Subject: [PATCH 639/830] did i get it right now? --- src/libcompiler_builtins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins index 34f5d4aa3870..263a703b1035 160000 --- a/src/libcompiler_builtins +++ b/src/libcompiler_builtins @@ -1 +1 @@ -Subproject commit 34f5d4aa3870afc6646dac03963d1d26891c4f60 +Subproject commit 263a703b10351d8930e48045b4fd09768991b867 From 140bf949bf65bb0479dbe31bd3474d5546ef59e1 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 24 Mar 2018 18:19:33 -0500 Subject: [PATCH 640/830] fix last two tidy --- src/libcore/num/mod.rs | 8 +------- src/libstd/num.rs | 7 +------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 55186b0a3aca..a5ba0bcdf7e6 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -97,14 +97,8 @@ nonzero_integers! { NonZeroU16(u16); NonZeroI16(i16); NonZeroU32(u32); NonZeroI32(i32); NonZeroU64(u64); NonZeroI64(i64); - NonZeroUsize(usize); NonZeroIsize(isize); -} - -nonzero_integers! { - // Change this to `#[unstable(feature = "i128", issue = "35118")]` - // if other NonZero* integer types are stabilizied before 128-bit integers - #[unstable(feature = "nonzero", issue = "49137")] NonZeroU128(u128); NonZeroI128(i128); + NonZeroUsize(usize); NonZeroIsize(isize); } /// Provides intentionally-wrapped arithmetic on `T`. diff --git a/src/libstd/num.rs b/src/libstd/num.rs index 6f537fd5c50e..547b8c7c925d 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -24,14 +24,9 @@ pub use core::num::Wrapping; #[unstable(feature = "nonzero", issue = "49137")] pub use core::num::{ NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, - NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize, + NonZeroU64, NonZeroI64, NonZeroU128, NonZeroI128, NonZeroUsize, NonZeroIsize, }; -// Change this to `#[unstable(feature = "i128", issue = "35118")]` -// if other NonZero* integer types are stabilizied before 128-bit integers -#[unstable(feature = "nonzero", issue = "49137")] -pub use core::num::{NonZeroU128, NonZeroI128}; - #[cfg(test)] use fmt; #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; From 5fc7e0a2ba84c44caebc5801f454663bafad2ca8 Mon Sep 17 00:00:00 2001 From: boats Date: Mon, 26 Mar 2018 07:41:45 -0700 Subject: [PATCH 641/830] Remove unnecessary trait import. --- src/librustdoc/test.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 3ce8bd4ebb4c..8ab9ca451871 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -406,8 +406,6 @@ pub fn make_test(s: &str, // FIXME(aburka): use a real parser to deal with multiline attributes fn partition_source(s: &str) -> (String, String) { - use std_unicode::str::UnicodeStr; - let mut after_header = false; let mut before = String::new(); let mut after = String::new(); From bda718fd255237167f08198b0fc80ab0d484d58e Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 26 Mar 2018 16:26:03 +0200 Subject: [PATCH 642/830] Allow niche-filling dataful variants to be represented as a ScalarPair --- src/librustc/ty/layout.rs | 19 +++++++++++++++---- src/test/codegen/function-arguments.rs | 6 ++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 029dd6f1fb46..5f9c305d92f0 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1517,10 +1517,21 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let offset = st[i].fields.offset(field_index) + offset; let size = st[i].size; - let abi = if offset.bytes() == 0 && niche.value.size(dl) == size { - Abi::Scalar(niche.clone()) - } else { - Abi::Aggregate { sized: true } + let abi = match st[i].abi { + Abi::Scalar(_) => Abi::Scalar(niche.clone()), + Abi::ScalarPair(ref first, ref second) => { + // We need to use scalar_unit to reset the + // valid range to the maximal one for that + // primitive, because only the niche is + // guaranteed to be initialised, not the + // other primitive. + if offset.bytes() == 0 { + Abi::ScalarPair(niche.clone(), scalar_unit(second.value)) + } else { + Abi::ScalarPair(scalar_unit(first.value), niche.clone()) + } + } + _ => Abi::Aggregate { sized: true }, }; return Ok(tcx.intern_layout(LayoutDetails { diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs index 0e98d3f9050a..de302c69056f 100644 --- a/src/test/codegen/function-arguments.rs +++ b/src/test/codegen/function-arguments.rs @@ -133,6 +133,12 @@ pub fn trait_borrow(_: &Drop) { pub fn trait_box(_: Box) { } +// CHECK: { i8*, i8* } @trait_option(i8* noalias %x.0, i8* %x.1) +#[no_mangle] +pub fn trait_option(x: Option>) -> Option> { + x +} + // CHECK: { [0 x i16]*, [[USIZE]] } @return_slice([0 x i16]* noalias nonnull readonly %x.0, [[USIZE]] %x.1) #[no_mangle] pub fn return_slice(x: &[u16]) -> &[u16] { From 816c1b191cbea4f4949bc584c2324e81caa6e34b Mon Sep 17 00:00:00 2001 From: matthew Date: Thu, 22 Mar 2018 08:57:26 -0700 Subject: [PATCH 643/830] Check for known but incorrect attributes - Change nested_visit_map so it will recusively check functions - Add visit_stmt and visit_expr for impl Visitor for CheckAttrVisitor and check for incorrect inline and repr attributes on staements and expressions - Add regression test for isssue #43988 --- src/librustc/hir/check_attr.rs | 91 +++++++++++++++++++++++++--- src/test/compile-fail/issue-43988.rs | 36 +++++++++++ 2 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 src/test/compile-fail/issue-43988.rs diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 9b2647ad4db2..6e1b7dc86a29 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -14,6 +14,7 @@ //! conflicts between multiple such attributes attached to the same //! item. +use syntax_pos::Span; use ty::TyCtxt; use hir; @@ -27,6 +28,8 @@ enum Target { Enum, Const, ForeignMod, + Expression, + Statement, Other, } @@ -62,7 +65,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { let mut has_wasm_import_module = false; for attr in &item.attrs { if attr.check_name("inline") { - self.check_inline(attr, item, target) + self.check_inline(attr, &item.span, target) } else if attr.check_name("wasm_import_module") { has_wasm_import_module = true; if attr.value_str().is_none() { @@ -99,13 +102,13 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } /// Check if an `#[inline]` is applied to a function. - fn check_inline(&self, attr: &hir::Attribute, item: &hir::Item, target: Target) { + fn check_inline(&self, attr: &hir::Attribute, span: &Span, target: Target) { if target != Target::Fn { struct_span_err!(self.tcx.sess, attr.span, E0518, "attribute should be applied to function") - .span_label(item.span, "not a function") + .span_label(*span, "not a function") .emit(); } } @@ -196,10 +199,12 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } _ => continue, }; - struct_span_err!(self.tcx.sess, hint.span, E0517, - "attribute should be applied to {}", allowed_targets) - .span_label(item.span, format!("not {} {}", article, allowed_targets)) - .emit(); + self.emit_repr_error( + hint.span, + item.span, + &format!("attribute should be applied to {}", allowed_targets), + &format!("not {} {}", article, allowed_targets), + ) } // Just point at all repr hints if there are any incompatibilities. @@ -221,17 +226,85 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { "conflicting representation hints"); } } + + fn emit_repr_error( + &self, + hint_span: Span, + label_span: Span, + hint_message: &str, + label_message: &str, + ) { + struct_span_err!(self.tcx.sess, hint_span, E0517, "{}", hint_message) + .span_label(label_span, label_message) + .emit(); + } + + fn check_stmt_attributes(&self, stmt: &hir::Stmt) { + // When checking statements ignore expressions, they will be checked later + if let hir::Stmt_::StmtDecl(_, _) = stmt.node { + for attr in stmt.node.attrs() { + if attr.check_name("inline") { + self.check_inline(attr, &stmt.span, Target::Statement); + } + if attr.check_name("repr") { + self.emit_repr_error( + attr.span, + stmt.span, + &format!("attribute should not be applied to statements"), + &format!("not a struct, enum or union"), + ); + } + } + } + } + + fn check_expr_attributes(&self, expr: &hir::Expr) { + use hir::Expr_::*; + match expr.node { + // Assignments, Calls and Structs were handled by Items and Statements + ExprCall(..) | + ExprAssign(..) | + ExprMethodCall(..) | + ExprStruct(..) => return, + _ => (), + } + + for attr in expr.attrs.iter() { + if attr.check_name("inline") { + self.check_inline(attr, &expr.span, Target::Expression); + } + if attr.check_name("repr") { + self.emit_repr_error( + attr.span, + expr.span, + &format!("attribute should not be applied to an expression"), + &format!("not a struct, enum or union"), + ); + } + } + } } impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> { - NestedVisitorMap::None + NestedVisitorMap::OnlyBodies(&self.tcx.hir) } fn visit_item(&mut self, item: &'tcx hir::Item) { let target = Target::from_item(item); self.check_attributes(item, target); - intravisit::walk_item(self, item); + intravisit::walk_item(self, item) + } + + + fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt) { + self.check_stmt_attributes(stmt); + intravisit::walk_stmt(self, stmt) + } + + fn visit_expr(&mut self, expr: &'tcx hir::Expr) { + self.check_expr_attributes(expr); + intravisit::walk_expr(self, expr) } } diff --git a/src/test/compile-fail/issue-43988.rs b/src/test/compile-fail/issue-43988.rs new file mode 100644 index 000000000000..78237e31ba06 --- /dev/null +++ b/src/test/compile-fail/issue-43988.rs @@ -0,0 +1,36 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + + #[inline] + let _a = 4; + //~^^ ERROR attribute should be applied to function + + + #[inline(XYZ)] + let _b = 4; + //~^^ ERROR attribute should be applied to function + + #[repr(nothing)] + let _x = 0; + //~^^ ERROR attribute should not be applied to statements + + + #[repr(something_not_real)] + loop { + () + }; + //~^^^^ ERROR attribute should not be applied to an expression + + #[repr] + let _y = "123"; + //~^^ ERROR attribute should not be applied to statements +} From 3908b2e4438e89a4f9503a8fa3e378ecc127df45 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 14 Mar 2018 15:27:06 +0100 Subject: [PATCH 644/830] Introduce a TargetTriple enum to support absolute target paths --- src/librustc/session/config.rs | 22 +++++--- src/librustc/session/mod.rs | 7 +-- src/librustc_back/target/mod.rs | 89 +++++++++++++++++++++++--------- src/librustc_metadata/creader.rs | 12 +++-- src/librustc_metadata/locator.rs | 10 ++-- src/librustc_metadata/schema.rs | 3 +- src/librustc_trans/abi.rs | 2 +- src/librustc_trans/back/link.rs | 7 +-- src/librustc_trans/back/write.rs | 4 +- src/librustc_trans/base.rs | 3 +- src/librustdoc/core.rs | 6 ++- src/librustdoc/lib.rs | 9 +++- 12 files changed, 118 insertions(+), 56 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d24da1ff7c8e..092b84e3ffea 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -21,7 +21,7 @@ use session::search_paths::SearchPaths; use ich::StableHashingContext; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; -use rustc_back::target::Target; +use rustc_back::target::{Target, TargetTriple}; use rustc_data_structures::stable_hasher::ToStableHashKey; use lint; use middle::cstore; @@ -367,7 +367,7 @@ top_level_options!( libs: Vec<(String, Option, Option)> [TRACKED], maybe_sysroot: Option [TRACKED], - target_triple: String [TRACKED], + target_triple: TargetTriple [TRACKED], test: bool [TRACKED], error_format: ErrorOutputType [UNTRACKED], @@ -567,7 +567,7 @@ pub fn basic_options() -> Options { output_types: OutputTypes(BTreeMap::new()), search_paths: SearchPaths::new(), maybe_sysroot: None, - target_triple: host_triple().to_string(), + target_triple: TargetTriple::from_triple(host_triple()), test: false, incremental: None, debugging_opts: basic_debugging_options(), @@ -1903,9 +1903,15 @@ pub fn build_session_options_and_crate_config( let cg = cg; let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m)); - let target = matches - .opt_str("target") - .unwrap_or(host_triple().to_string()); + let target_triple = if let Some(target) = matches.opt_str("target") { + if target.ends_with(".json") { + TargetTriple::TargetPath(PathBuf::from(target)) + } else { + TargetTriple::TargetTriple(target) + } + } else { + TargetTriple::from_triple(host_triple()) + }; let opt_level = { if matches.opt_present("O") { if cg.opt_level.is_some() { @@ -2113,7 +2119,7 @@ pub fn build_session_options_and_crate_config( output_types: OutputTypes(output_types), search_paths, maybe_sysroot: sysroot_opt, - target_triple: target, + target_triple, test, incremental, debugging_opts, @@ -2264,6 +2270,7 @@ mod dep_tracking { Passes, Sanitizer}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; + use rustc_back::target::TargetTriple; pub trait DepTrackingHash { fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType); @@ -2323,6 +2330,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(Sanitizer); impl_dep_tracking_hash_via_hash!(Option); impl_dep_tracking_hash_via_hash!(Edition); + impl_dep_tracking_hash_via_hash!(TargetTriple); impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 556255e06ed0..77cf50a8341e 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -42,7 +42,7 @@ use syntax::feature_gate::AttributeType; use syntax_pos::{MultiSpan, Span}; use rustc_back::{LinkerFlavor, PanicStrategy}; -use rustc_back::target::Target; +use rustc_back::target::{Target, TargetTriple}; use rustc_data_structures::flock; use jobserver::Client; @@ -707,7 +707,7 @@ impl Session { pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch { filesearch::FileSearch::new( self.sysroot(), - &self.opts.target_triple, + self.opts.target_triple.triple(), &self.opts.search_paths, kind, ) @@ -1085,7 +1085,8 @@ pub fn build_session_( span_diagnostic: errors::Handler, codemap: Lrc, ) -> Session { - let host = match Target::search(config::host_triple()) { + let host_triple = TargetTriple::from_triple(config::host_triple()); + let host = match Target::search(&host_triple) { Ok(t) => t, Err(e) => { span_diagnostic diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index f53eeb86a9c5..ca73a755784e 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -47,6 +47,8 @@ use serialize::json::{Json, ToJson}; use std::collections::BTreeMap; use std::default::Default; +use std::fmt; +use std::path::{Path, PathBuf}; use syntax::abi::{Abi, lookup as lookup_abi}; use {LinkerFlavor, PanicStrategy, RelroLevel}; @@ -824,11 +826,10 @@ impl Target { /// /// The error string could come from any of the APIs called, including /// filesystem access and JSON decoding. - pub fn search(target: &str) -> Result { + pub fn search(target_triple: &TargetTriple) -> Result { use std::env; use std::ffi::OsString; use std::fs; - use std::path::{Path, PathBuf}; use serialize::json; fn load_file(path: &Path) -> Result { @@ -838,35 +839,40 @@ impl Target { Target::from_json(obj) } - if let Ok(t) = load_specific(target) { - return Ok(t) - } + match target_triple { + &TargetTriple::TargetTriple(ref target_triple) => { + // check if triple is in list of supported targets + if let Ok(t) = load_specific(target_triple) { + return Ok(t) + } - let path = Path::new(target); + // search for a file named `target_triple`.json in RUST_TARGET_PATH + let path = { + let mut target = target_triple.to_string(); + target.push_str(".json"); + PathBuf::from(target) + }; - if path.is_file() { - return load_file(&path); - } + let target_path = env::var_os("RUST_TARGET_PATH") + .unwrap_or(OsString::new()); - let path = { - let mut target = target.to_string(); - target.push_str(".json"); - PathBuf::from(target) - }; + // FIXME 16351: add a sane default search path? - let target_path = env::var_os("RUST_TARGET_PATH") - .unwrap_or(OsString::new()); - - // FIXME 16351: add a sane default search path? - - for dir in env::split_paths(&target_path) { - let p = dir.join(&path); - if p.is_file() { - return load_file(&p); + for dir in env::split_paths(&target_path) { + let p = dir.join(&path); + if p.is_file() { + return load_file(&p); + } + } + Err(format!("Could not find specification for target {:?}", target_triple)) + } + &TargetTriple::TargetPath(ref target_path) => { + if target_path.is_file() { + return load_file(&target_path); + } + Err(format!("Target path {:?} is not a valid file", target_path)) } } - - Err(format!("Could not find specification for target {:?}", target)) } } @@ -1014,3 +1020,36 @@ fn maybe_jemalloc() -> Option { None } } + +/// Either a target triple string or a path to a JSON file. +#[derive(PartialEq, Clone, Debug, Hash, RustcEncodable, RustcDecodable)] +pub enum TargetTriple { + TargetTriple(String), + TargetPath(PathBuf), +} + +impl TargetTriple { + /// Creates a target target from the passed target triple string. + pub fn from_triple(triple: &str) -> Self { + TargetTriple::TargetTriple(triple.to_string()) + } + + /// Returns a string triple for this target. + /// + /// If this target is a path, the file name (without extension) is returned. + pub fn triple(&self) -> &str { + match self { + &TargetTriple::TargetTriple(ref triple) => triple, + &TargetTriple::TargetPath(ref path) => { + path.file_stem().expect("target path must not be empty").to_str() + .expect("target path must be valid unicode") + } + } + } +} + +impl fmt::Display for TargetTriple { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.triple()) + } +} diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index baaf57c89089..616fbc6cac5a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -22,6 +22,7 @@ use rustc::middle::cstore::DepKind; use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_back::PanicStrategy; +use rustc_back::target::TargetTriple; use rustc::session::search_paths::PathKind; use rustc::middle; use rustc::middle::cstore::{validate_crate_name, ExternCrate}; @@ -295,7 +296,7 @@ impl<'a> CrateLoader<'a> { let mut proc_macro_locator = locator::Context { target: &self.sess.host, - triple: config::host_triple(), + triple: &TargetTriple::from_triple(config::host_triple()), filesearch: self.sess.host_filesearch(path_kind), rejected_via_hash: vec![], rejected_via_triple: vec![], @@ -339,7 +340,7 @@ impl<'a> CrateLoader<'a> { // don't want to match a host crate against an equivalent target one // already loaded. let root = library.metadata.get_root(); - if locate_ctxt.triple == self.sess.opts.target_triple { + if locate_ctxt.triple == &self.sess.opts.target_triple { let mut result = LoadResult::Loaded(library); self.cstore.iter_crate_data(|cnum, data| { if data.name() == root.name && root.hash == data.hash() { @@ -426,8 +427,9 @@ impl<'a> CrateLoader<'a> { fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol) -> ExtensionCrate { info!("read extension crate `extern crate {} as {}`", orig_name, rename); - let target_triple = &self.sess.opts.target_triple[..]; - let is_cross = target_triple != config::host_triple(); + let target_triple = &self.sess.opts.target_triple; + let host_triple = TargetTriple::from_triple(config::host_triple()); + let is_cross = target_triple != &host_triple; let mut target_only = false; let mut locate_ctxt = locator::Context { sess: self.sess, @@ -437,7 +439,7 @@ impl<'a> CrateLoader<'a> { hash: None, filesearch: self.sess.host_filesearch(PathKind::Crate), target: &self.sess.host, - triple: config::host_triple(), + triple: &host_triple, root: &None, rejected_via_hash: vec![], rejected_via_triple: vec![], diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index c56674bd6c5a..41e10b4755d0 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -233,7 +233,7 @@ use rustc::util::nodemap::FxHashMap; use errors::DiagnosticBuilder; use syntax::symbol::Symbol; use syntax_pos::Span; -use rustc_back::target::Target; +use rustc_back::target::{Target, TargetTriple}; use std::cmp; use std::fmt; @@ -258,7 +258,7 @@ pub struct Context<'a> { pub hash: Option<&'a Svh>, // points to either self.sess.target.target or self.sess.host, must match triple pub target: &'a Target, - pub triple: &'a str, + pub triple: &'a TargetTriple, pub filesearch: FileSearch<'a>, pub root: &'a Option, pub rejected_via_hash: Vec, @@ -394,7 +394,7 @@ impl<'a> Context<'a> { add); if (self.ident == "std" || self.ident == "core") - && self.triple != config::host_triple() { + && self.triple != &TargetTriple::from_triple(config::host_triple()) { err.note(&format!("the `{}` target may not be installed", self.triple)); } err.span_label(self.span, "can't find crate"); @@ -698,13 +698,13 @@ impl<'a> Context<'a> { } } - if root.triple != self.triple { + if &root.triple != self.triple { info!("Rejecting via crate triple: expected {} got {}", self.triple, root.triple); self.rejected_via_triple.push(CrateMismatch { path: libpath.to_path_buf(), - got: root.triple, + got: format!("{}", root.triple), }); return None; } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 983279452970..d04a4001c502 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -22,6 +22,7 @@ use rustc::mir; use rustc::session::CrateDisambiguator; use rustc::ty::{self, Ty, ReprOptions}; use rustc_back::PanicStrategy; +use rustc_back::target::TargetTriple; use rustc_serialize as serialize; use syntax::{ast, attr}; @@ -186,7 +187,7 @@ pub enum LazyState { #[derive(RustcEncodable, RustcDecodable)] pub struct CrateRoot { pub name: Symbol, - pub triple: String, + pub triple: TargetTriple, pub hash: hir::svh::Svh, pub disambiguator: CrateDisambiguator, pub panic_strategy: PanicStrategy, diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 44c18c371a40..9adcdf56e86f 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -950,7 +950,7 @@ impl<'a, 'tcx> FnType<'tcx> { "s390x" => cabi_s390x::compute_abi_info(cx, self), "asmjs" => cabi_asmjs::compute_abi_info(cx, self), "wasm32" => { - if cx.sess().opts.target_triple.contains("emscripten") { + if cx.sess().opts.target_triple.triple().contains("emscripten") { cabi_asmjs::compute_abi_info(cx, self) } else { cabi_wasm32::compute_abi_info(cx, self) diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 542cdc5baad3..c4dbbff45936 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -31,6 +31,7 @@ use rustc::util::fs::fix_windows_verbatim_for_gcc; use rustc::hir::def_id::CrateNum; use tempdir::TempDir; use rustc_back::{PanicStrategy, RelroLevel}; +use rustc_back::target::TargetTriple; use context::get_reloc_model; use llvm; @@ -81,7 +82,7 @@ pub fn get_linker(sess: &Session) -> (PathBuf, Command) { } }; - let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple, "link.exe"); + let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe"); let linker_path = sess.opts.cg.linker.as_ref().map(|s| &**s) .or(sess.target.target.options.linker.as_ref().map(|s| s.as_ref())) @@ -812,7 +813,7 @@ fn link_natively(sess: &Session, } } - if sess.opts.target_triple == "wasm32-unknown-unknown" { + if sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown") { wasm::rewrite_imports(&out_filename, &trans.crate_info.wasm_imports); wasm::add_custom_sections(&out_filename, &trans.crate_info.wasm_custom_sections); @@ -1090,7 +1091,7 @@ fn link_args(cmd: &mut Linker, // addl_lib_search_paths if sess.opts.cg.rpath { let sysroot = sess.sysroot(); - let target_triple = &sess.opts.target_triple; + let target_triple = sess.opts.target_triple.triple(); let mut get_install_prefix_lib_path = || { let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX"); let tlib = filesearch::relative_target_lib_path(sysroot, target_triple); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 3e7422557e9b..adf5e4a8a713 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -848,7 +848,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext, "rustc.embedded.module\0".as_ptr() as *const _, ); llvm::LLVMSetInitializer(llglobal, llconst); - let section = if cgcx.opts.target_triple.contains("-ios") { + let section = if cgcx.opts.target_triple.triple().contains("-ios") { "__LLVM,__bitcode\0" } else { ".llvmbc\0" @@ -863,7 +863,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext, "rustc.embedded.cmdline\0".as_ptr() as *const _, ); llvm::LLVMSetInitializer(llglobal, llconst); - let section = if cgcx.opts.target_triple.contains("-ios") { + let section = if cgcx.opts.target_triple.triple().contains("-ios") { "__LLVM,__cmdline\0" } else { ".llvmcmd\0" diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 56eece9f31e7..0ce26f2295e4 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -73,6 +73,7 @@ use type_of::LayoutLlvmExt; use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet}; use CrateInfo; use rustc_data_structures::sync::Lrc; +use rustc_back::target::TargetTriple; use std::any::Any; use std::collections::BTreeMap; @@ -1079,7 +1080,7 @@ impl CrateInfo { let load_wasm_items = tcx.sess.crate_types.borrow() .iter() .any(|c| *c != config::CrateTypeRlib) && - tcx.sess.opts.target_triple == "wasm32-unknown-unknown"; + tcx.sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown"); if load_wasm_items { info!("attempting to load all wasm sections"); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1e0fafc8d9df..0bf3a8f368dc 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -22,6 +22,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_resolve as resolve; use rustc_metadata::creader::CrateLoader; use rustc_metadata::cstore::CStore; +use rustc_back::target::TargetTriple; use syntax::ast::NodeId; use syntax::codemap; @@ -116,7 +117,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: config::Externs, input: Input, - triple: Option, + triple: Option, maybe_sysroot: Option, allow_warnings: bool, crate_name: Option, @@ -131,6 +132,7 @@ pub fn run_core(search_paths: SearchPaths, let warning_lint = lint::builtin::WARNINGS.name_lower(); + let host_triple = TargetTriple::from_triple(config::host_triple()); let sessopts = config::Options { maybe_sysroot, search_paths, @@ -138,7 +140,7 @@ pub fn run_core(search_paths: SearchPaths, lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] }, lint_cap: Some(lint::Allow), externs, - target_triple: triple.unwrap_or(config::host_triple().to_string()), + target_triple: triple.unwrap_or(host_triple), // Ensure that rustdoc works even if rustc is feature-staged unstable_features: UnstableFeatures::Allow, actually_rustdoc: true, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bec25a98227a..0339a58d5821 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -64,6 +64,7 @@ use std::sync::mpsc::channel; use externalfiles::ExternalHtml; use rustc::session::search_paths::SearchPaths; use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs}; +use rustc_back::target::TargetTriple; #[macro_use] pub mod externalfiles; @@ -542,7 +543,13 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { paths.add_path(s, ErrorOutputType::default()); } let cfgs = matches.opt_strs("cfg"); - let triple = matches.opt_str("target"); + let triple = matches.opt_str("target").map(|target| { + if target.ends_with(".json") { + TargetTriple::TargetPath(PathBuf::from(target)) + } else { + TargetTriple::TargetTriple(target) + } + }); let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); let crate_name = matches.opt_str("crate-name"); let crate_version = matches.opt_str("crate-version"); From 7b49190d3cd98d9e3bc901993861f80269eb4155 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Sat, 24 Mar 2018 20:14:59 +0100 Subject: [PATCH 645/830] Canonicalize paths --- src/librustc/session/config.rs | 10 ++++++++-- src/librustc_back/target/mod.rs | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 092b84e3ffea..92da47b9d436 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -47,7 +47,7 @@ use std::hash::Hasher; use std::collections::hash_map::DefaultHasher; use std::collections::HashSet; use std::iter::FromIterator; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; pub struct Config { pub target: Target, @@ -1905,7 +1905,13 @@ pub fn build_session_options_and_crate_config( let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m)); let target_triple = if let Some(target) = matches.opt_str("target") { if target.ends_with(".json") { - TargetTriple::TargetPath(PathBuf::from(target)) + let path = Path::new(&target); + match TargetTriple::from_path(&path) { + Ok(triple) => triple, + Err(_) => { + early_error(error_format, &format!("target file {:?} does not exist", path)) + } + } } else { TargetTriple::TargetTriple(target) } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index ca73a755784e..3216aae89184 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -47,7 +47,7 @@ use serialize::json::{Json, ToJson}; use std::collections::BTreeMap; use std::default::Default; -use std::fmt; +use std::{fmt, io}; use std::path::{Path, PathBuf}; use syntax::abi::{Abi, lookup as lookup_abi}; @@ -1029,11 +1029,17 @@ pub enum TargetTriple { } impl TargetTriple { - /// Creates a target target from the passed target triple string. + /// Creates a target triple from the passed target triple string. pub fn from_triple(triple: &str) -> Self { TargetTriple::TargetTriple(triple.to_string()) } + /// Creates a target triple from the passed target path. + pub fn from_path(path: &Path) -> Result { + let canonicalized_path = path.canonicalize()?; + Ok(TargetTriple::TargetPath(canonicalized_path)) + } + /// Returns a string triple for this target. /// /// If this target is a path, the file name (without extension) is returned. From b889f98fba63dfcce68902c3a8c330fdea16a33b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Mon, 26 Mar 2018 19:01:26 +0200 Subject: [PATCH 646/830] Add a hash when a TargetPath is displayed --- src/librustc_back/target/mod.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 3216aae89184..507243a58a5f 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -1052,10 +1052,29 @@ impl TargetTriple { } } } + + /// Returns an extended string triple for this target. + /// + /// If this target is a path, a hash of the path is appended to the triple returned + /// by `triple()`. + pub fn debug_triple(&self) -> String { + use std::hash::{Hash, Hasher}; + use std::collections::hash_map::DefaultHasher; + + let triple = self.triple(); + if let &TargetTriple::TargetPath(ref path) = self { + let mut hasher = DefaultHasher::new(); + path.hash(&mut hasher); + let hash = hasher.finish(); + format!("{}-{}", triple, hash) + } else { + triple.to_owned() + } + } } impl fmt::Display for TargetTriple { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.triple()) + write!(f, "{}", self.debug_triple()) } } From faebcc108768210cda97a74f0407cd7b3c3348c9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 15 Mar 2018 10:58:02 -0700 Subject: [PATCH 647/830] rustbuild: Fail the build if we build Cargo twice This commit updates the `ToolBuild` step to stream Cargo's JSON messages, parse them, and record all libraries built. If we build anything twice (aka Cargo) it'll most likely happen due to dependencies being recompiled which is caught by this check. --- src/Cargo.lock | 379 +++++++++++++------------ src/bootstrap/compile.rs | 121 ++++---- src/bootstrap/lib.rs | 5 + src/bootstrap/tool.rs | 75 ++++- src/librustc/Cargo.toml | 1 + src/tools/cargo | 2 +- src/tools/rls | 2 +- src/tools/unstable-book-gen/Cargo.toml | 4 + 8 files changed, 349 insertions(+), 240 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index c45f18360b9b..c4707707be08 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -22,7 +22,7 @@ dependencies = [ "alloc 0.0.0", "alloc_system 0.0.0", "build_helper 0.1.0", - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.0.0", ] @@ -67,7 +67,7 @@ name = "atty" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -79,7 +79,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -89,8 +89,8 @@ name = "backtrace-sys" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -117,16 +117,16 @@ name = "bootstrap" version = "0.0.0" dependencies = [ "build_helper 0.1.0", - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -144,8 +144,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "build-manifest" version = "0.1.0" dependencies = [ - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -173,36 +173,35 @@ dependencies = [ "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "git2-curl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -214,9 +213,9 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -226,9 +225,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -237,7 +236,7 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -279,10 +278,10 @@ dependencies = [ "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -299,10 +298,10 @@ dependencies = [ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -313,7 +312,7 @@ name = "cmake" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -329,14 +328,14 @@ name = "commoncrypto-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "compiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -345,16 +344,16 @@ name = "compiletest" version = "0.0.0" dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -366,13 +365,13 @@ dependencies = [ "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -393,7 +392,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -401,7 +400,7 @@ name = "core-foundation-sys" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -410,9 +409,9 @@ version = "0.16.0" dependencies = [ "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -470,11 +469,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl-sys 0.4.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.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -483,8 +482,8 @@ name = "curl-sys" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -552,13 +551,13 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -606,7 +605,7 @@ version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -623,7 +622,7 @@ name = "flate2" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -654,7 +653,7 @@ name = "fs2" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -684,12 +683,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "git2" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -697,12 +697,12 @@ dependencies = [ [[package]] name = "git2-curl" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "curl 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -720,7 +720,7 @@ dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -736,9 +736,9 @@ dependencies = [ "log 0.3.9 (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.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -789,7 +789,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -838,15 +838,15 @@ dependencies = [ [[package]] name = "itoa" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jobserver" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -863,9 +863,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -883,9 +883,9 @@ version = "0.31.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.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -914,7 +914,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.39" +version = "0.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -922,10 +922,10 @@ name = "libgit2-sys" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "curl-sys 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (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.18 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -938,7 +938,7 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -949,8 +949,8 @@ name = "libz-sys" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -988,9 +988,9 @@ name = "lzma-sys" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1006,7 +1006,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1015,12 +1015,12 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1030,7 +1030,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1043,8 +1043,8 @@ name = "miniz-sys" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1052,7 +1052,7 @@ name = "miow" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1064,7 +1064,7 @@ dependencies = [ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "compiletest_rs 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1088,7 +1088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1096,7 +1096,7 @@ name = "num-integer" version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1105,7 +1105,7 @@ version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1113,12 +1113,12 @@ name = "num-traits" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1126,7 +1126,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1142,7 +1142,7 @@ dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.27 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1156,8 +1156,8 @@ name = "openssl-sys" version = "0.9.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1202,7 +1202,7 @@ name = "parking_lot_core" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1245,7 +1245,7 @@ dependencies = [ name = "profiler_builtins" version = "0.0.0" dependencies = [ - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -1287,7 +1287,7 @@ version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1310,7 +1310,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1330,7 +1330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1358,19 +1358,19 @@ version = "0.1.0" [[package]] name = "regex" -version = "0.2.7" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.5.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1386,11 +1386,10 @@ version = "0.1.0" [[package]] name = "remove_dir_all" -version = "0.3.0" +version = "0.5.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)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1400,7 +1399,7 @@ dependencies = [ "cargo 0.27.0", "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "clippy_lints 0.0.189", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1417,9 +1416,9 @@ dependencies = [ "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustfmt-nightly 0.4.1", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1448,8 +1447,8 @@ 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.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1463,8 +1462,8 @@ version = "0.4.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)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1495,7 +1494,7 @@ dependencies = [ "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", - "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc_macro 0.0.0", @@ -1507,6 +1506,7 @@ dependencies = [ "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1686,7 +1686,7 @@ version = "0.0.0" dependencies = [ "ar 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "arena 0.0.0", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -1756,8 +1756,8 @@ version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "build_helper 0.1.0", - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", ] @@ -1907,11 +1907,11 @@ name = "rustc_trans" version = "0.0.0" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -1930,7 +1930,7 @@ dependencies = [ "serialize 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", - "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1981,7 +1981,7 @@ name = "rustdoc" version = "0.0.0" dependencies = [ "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2002,17 +2002,17 @@ dependencies = [ "cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "derive-new 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-syntax 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2052,7 +2052,7 @@ version = "0.9.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)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2062,23 +2062,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.29" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.29" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.12.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.20.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2090,18 +2090,18 @@ name = "serde_ignored" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2125,11 +2125,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "socket2" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2251,7 +2251,7 @@ name = "syntex_errors" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (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)", @@ -2273,7 +2273,7 @@ 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.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (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)", @@ -2288,18 +2288,18 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (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.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2337,7 +2337,7 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2371,9 +2371,9 @@ dependencies = [ name = "tidy" version = "0.1.0" dependencies = [ - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2381,7 +2381,7 @@ name = "time" version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2399,7 +2399,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2410,7 +2410,7 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2469,6 +2469,7 @@ dependencies = [ name = "unstable-book-gen" version = "0.1.0" dependencies = [ + "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "tidy 0.1.0", ] @@ -2495,7 +2496,7 @@ name = "url_serde" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2583,7 +2584,7 @@ name = "xattr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2614,7 +2615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b" "checksum cargo_metadata 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5caae26de3704081ef638f87f05a6891b04f2b7d5ce9429a3de21095528ae22" -"checksum cc 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fedf677519ac9e865c4ff43ef8f930773b37ed6e6ea61b6b83b400a7b5787f49" +"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" @@ -2638,7 +2639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ena 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f8b449f3b18c89d2dbe40548d2ee4fa58ea0a08b761992da6ecb9788e4688834" "checksum endian-type 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" "checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" -"checksum env_logger 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0628f04f7c26ebccf40d7fc2c1cf92236c05ec88cf2132641cc956812312f0f" +"checksum env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0561146661ae44c579e993456bc76d11ce1e0c7d745e57b2fa7146b6e49fa2ad" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" @@ -2652,8 +2653,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9" -"checksum git2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4813cd7ad02e53275e6e51aaaf21c30f9ef500b579ad7a54a92f6091a7ac296" -"checksum git2-curl 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "27245f4c3a65ab19fd1ab5b52659bd60ed0ce8d0d129202c4737044d1d21db29" +"checksum git2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f41c0035c37ec11ed3f1e1946a76070b0c740393687e9a9c7612f6a709036b3" +"checksum git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f6b1b467957403d168f0039e0c46fa6a1220efa2adaef25d5b267b5fe024" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum globset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1e96ab92362c06811385ae9a34d2698e8a1160745e0c78fbb434a44c8de3fabc" "checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc" @@ -2665,8 +2666,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum ignore 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "245bea0ba52531a3739cb8ba99f8689eda13d7faf8c36b6a73ce4421aab42588" "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394" -"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" -"checksum jobserver 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2abd9fd3242accb0e2e30986f2cf30cda3e19eec5cc6d584b218ce2b1c0e3c" +"checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" +"checksum jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "60af5f849e1981434e4a31d3d782c4774ae9b434ce55b101a96ecfd09147e8be" "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483" "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -2674,7 +2675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" -"checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" = "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff" +"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b" "checksum libgit2-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1ecbd6428006c321c29b6c8a895f0d90152f1cf4fd8faab69fc436a3d9594f63" "checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75" "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16" @@ -2694,7 +2695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" "checksum num-iter 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "4b226df12c5a59b63569dd57fafb926d91b385dfce33d8074a412411b689d593" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -"checksum num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3c2bd9b9d21e48e956b763c9f37134dc62d9e95da6edb3f672cacb6caf3cd3" +"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" "checksum openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1636c9f1d78af9cbcc50e523bfff4a30274108aad5e86761afd4d31e4e184fa7" @@ -2719,9 +2720,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a62bf8bb734ab90b7f234b681b01af396e5d39b028906c210dc04fa1d5e9e5b3" -"checksum regex-syntax 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48d7391e7e90e06eaf3aefbe4652464153ecfec64806f3bf77ffc59638a63e77" -"checksum remove_dir_all 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b5d2f806b0fcdabd98acd380dc8daef485e22bcb7cddc811d1337967f2528cf5" +"checksum regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "aec3f58d903a7d2a9dc2bf0e41a746f4530e0cab6b615494e058f67a3ef947fb" +"checksum regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b2550876c31dc914696a6c2e01cbce8afba79a93c8ae979d2fe051c0230b3756" +"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24" "checksum rls-analysis 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4b9a3a3f2345854e39768e6425d1c893855da217183d1c0b3ff6f1664b6b6d" "checksum rls-blacklist 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56fb7b8e4850b988fbcf277fbdb1eff36879070d02fc1ca243b559273866973d" "checksum rls-data 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bea04462e94b5512a78499837eecb7db182ff082144cd1b4bc32ef5d43de6510" @@ -2742,15 +2743,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4763b773978e495252615e814d2ad04773b2c1f85421c7913869a537f35cb406" -"checksum serde_derive 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "8ab31f00ae5574bb643c196d5e302961c122da1c768604c6d16a35c5d551948a" -"checksum serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc848d073be32cd982380c06587ea1d433bc1a4c4a111de07ec2286a3ddade8" +"checksum serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "800fdb0a894572994f3970035a8a5f65d8ec2cd40e6cdf7d8cd9001d7b30648e" +"checksum serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "90f1f8f7784452461db5b73dc5097c18f21011fbcc6d1178f1897bfa8e1cb4bd" +"checksum serde_derive_internals 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f9525ada08124ee1a9b8b1e6f3bf035ffff6fc0c96d56ddda98d4506d3533e4" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" -"checksum serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57781ed845b8e742fc2bf306aba8e3b408fe8c366b900e3769fbc39f49eb8b39" +"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74" "checksum shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5cc96481d54583947bfe88bf30c23d53f883c6cd0145368b69989d97b84ef8" "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" -"checksum socket2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78e4c1cde1adbc6bc4c394da2e7727c916b9b7d0b53d6984c890c65c1f4e6437" +"checksum socket2 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "71ebbe82fcdd697244ba7fe6e05e63b5c45910c3927e28469a04947494ff48d8" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" @@ -2761,7 +2762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syntex_pos 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "955ef4b16af4c468e4680d1497f873ff288f557d338180649e18f915af5e15ac" "checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde" "checksum tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1605d3388ceb50252952ffebab4b5dc43017ead7e4481b175961c283bb951195" -"checksum tempdir 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f73eebdb68c14bcb24aef74ea96079830e7fa7b31a6106e42ea7ee887c1e134e" +"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index a1318086af7e..9f33935b6e93 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -16,6 +16,7 @@ //! compiler. This module is also responsible for assembling the sysroot as it //! goes along from the output of the previous stage. +use std::borrow::Cow; use std::env; use std::fs::{self, File}; use std::io::BufReader; @@ -996,24 +997,6 @@ fn stderr_isatty() -> bool { pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: bool) -> Vec { - // Instruct Cargo to give us json messages on stdout, critically leaving - // stderr as piped so we can get those pretty colors. - cargo.arg("--message-format").arg("json") - .stdout(Stdio::piped()); - - if stderr_isatty() && build.ci_env == CiEnv::None { - // since we pass message-format=json to cargo, we need to tell the rustc - // wrapper to give us colored output if necessary. This is because we - // only want Cargo's JSON output, not rustcs. - cargo.env("RUSTC_COLOR", "1"); - } - - build.verbose(&format!("running: {:?}", cargo)); - let mut child = match cargo.spawn() { - Ok(child) => child, - Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cargo, e), - }; - // `target_root_dir` looks like $dir/$target/release let target_root_dir = stamp.parent().unwrap(); // `target_deps_dir` looks like $dir/$target/release/deps @@ -1028,46 +1011,33 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo // files we need to probe for later. let mut deps = Vec::new(); let mut toplevel = Vec::new(); - let stdout = BufReader::new(child.stdout.take().unwrap()); - for line in stdout.lines() { - let line = t!(line); - let json: serde_json::Value = if line.starts_with("{") { - t!(serde_json::from_str(&line)) - } else { - // If this was informational, just print it out and continue - println!("{}", line); - continue + let ok = stream_cargo(build, cargo, &mut |msg| { + let filenames = match msg { + CargoMessage::CompilerArtifact { filenames, .. } => filenames, + _ => return, }; - if json["reason"].as_str() != Some("compiler-artifact") { - if build.config.rustc_error_format.as_ref().map_or(false, |e| e == "json") { - // most likely not a cargo message, so let's send it out as well - println!("{}", line); - } - continue - } - for filename in json["filenames"].as_array().unwrap() { - let filename = filename.as_str().unwrap(); + for filename in filenames { // Skip files like executables if !filename.ends_with(".rlib") && !filename.ends_with(".lib") && !is_dylib(&filename) && !(is_check && filename.ends_with(".rmeta")) { - continue + return; } - let filename = Path::new(filename); + let filename = Path::new(&*filename); // If this was an output file in the "host dir" we don't actually // worry about it, it's not relevant for us. if filename.starts_with(&host_root_dir) { - continue; + return; } // If this was output in the `deps` dir then this is a precise file // name (hash included) so we start tracking it. if filename.starts_with(&target_deps_dir) { deps.push(filename.to_path_buf()); - continue; + return; } // Otherwise this was a "top level artifact" which right now doesn't @@ -1088,15 +1058,10 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo toplevel.push((file_stem, extension, expected_len)); } - } + }); - // Make sure Cargo actually succeeded after we read all of its stdout. - let status = t!(child.wait()); - if !status.success() { - panic!("command did not execute successfully: {:?}\n\ - expected success, got: {}", - cargo, - status); + if !ok { + panic!("cargo must succeed"); } // Ok now we need to actually find all the files listed in `toplevel`. We've @@ -1167,3 +1132,63 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo t!(t!(File::create(stamp)).write_all(&new_contents)); deps } + +pub fn stream_cargo( + build: &Build, + cargo: &mut Command, + cb: &mut FnMut(CargoMessage), +) -> bool { + // Instruct Cargo to give us json messages on stdout, critically leaving + // stderr as piped so we can get those pretty colors. + cargo.arg("--message-format").arg("json") + .stdout(Stdio::piped()); + + if stderr_isatty() && build.ci_env == CiEnv::None { + // since we pass message-format=json to cargo, we need to tell the rustc + // wrapper to give us colored output if necessary. This is because we + // only want Cargo's JSON output, not rustcs. + cargo.env("RUSTC_COLOR", "1"); + } + + build.verbose(&format!("running: {:?}", cargo)); + let mut child = match cargo.spawn() { + Ok(child) => child, + Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cargo, e), + }; + + // Spawn Cargo slurping up its JSON output. We'll start building up the + // `deps` array of all files it generated along with a `toplevel` array of + // files we need to probe for later. + let stdout = BufReader::new(child.stdout.take().unwrap()); + for line in stdout.lines() { + let line = t!(line); + match serde_json::from_str::(&line) { + Ok(msg) => cb(msg), + // If this was informational, just print it out and continue + Err(_) => println!("{}", line) + } + } + + // Make sure Cargo actually succeeded after we read all of its stdout. + let status = t!(child.wait()); + if !status.success() { + println!("command did not execute successfully: {:?}\n\ + expected success, got: {}", + cargo, + status); + } + status.success() +} + +#[derive(Deserialize)] +#[serde(tag = "reason", rename_all = "kebab-case")] +pub enum CargoMessage<'a> { + CompilerArtifact { + package_id: Cow<'a, str>, + features: Vec>, + filenames: Vec>, + }, + BuildScriptExecuted { + package_id: Cow<'a, str>, + } +} diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index b2c8ac24d72d..833faf3618d6 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -254,6 +254,10 @@ pub struct Build { ci_env: CiEnv, delayed_failures: RefCell>, prerelease_version: Cell>, + tool_artifacts: RefCell, + HashMap)> + >>, } #[derive(Debug)] @@ -353,6 +357,7 @@ impl Build { ci_env: CiEnv::current(), delayed_failures: RefCell::new(Vec::new()), prerelease_version: Cell::new(None), + tool_artifacts: Default::default(), } } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 669308c8dd0e..2bb46cc5171d 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -117,7 +117,80 @@ impl Step for ToolBuild { let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); println!("Building stage{} tool {} ({})", compiler.stage, tool, target); - let is_expected = build.try_run(&mut cargo); + let mut duplicates = Vec::new(); + let is_expected = compile::stream_cargo(build, &mut cargo, &mut |msg| { + // Only care about big things like the RLS/Cargo for now + if tool != "rls" && tool != "cargo" { + return + } + let (id, features, filenames) = match msg { + compile::CargoMessage::CompilerArtifact { + package_id, + features, + filenames + } => { + (package_id, features, filenames) + } + _ => return, + }; + let features = features.iter().map(|s| s.to_string()).collect::>(); + + for path in filenames { + let val = (tool, PathBuf::from(&*path), features.clone()); + // we're only interested in deduplicating rlibs for now + if val.1.extension().and_then(|s| s.to_str()) != Some("rlib") { + continue + } + + // Don't worry about libs that turn out to be host dependencies + // or build scripts, we only care about target dependencies that + // are in `deps`. + if let Some(maybe_target) = val.1 + .parent() // chop off file name + .and_then(|p| p.parent()) // chop off `deps` + .and_then(|p| p.parent()) // chop off `release` + .and_then(|p| p.file_name()) + .and_then(|p| p.to_str()) + { + if maybe_target != &*target { + continue + } + } + + let mut artifacts = build.tool_artifacts.borrow_mut(); + let prev_artifacts = artifacts + .entry(target) + .or_insert_with(Default::default); + if let Some(prev) = prev_artifacts.get(&*id) { + if prev.1 != val.1 { + duplicates.push(( + id.to_string(), + val, + prev.clone(), + )); + } + return + } + prev_artifacts.insert(id.to_string(), val); + } + }); + + if is_expected && duplicates.len() != 0 { + println!("duplicate artfacts found when compiling a tool, this \ + typically means that something was recompiled because \ + a transitive dependency has different features activated \ + than in a previous build:\n"); + for (id, cur, prev) in duplicates { + println!(" {}", id); + println!(" `{}` enabled features {:?} at {:?}", + cur.0, cur.2, cur.1); + println!(" `{}` enabled features {:?} at {:?}", + prev.0, prev.2, prev.1); + } + println!(""); + panic!("tools should not compile multiple copies of the same crate"); + } + build.save_toolstate(tool, if is_expected { ToolState::TestFail } else { diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 7e84a69dd791..2aae0f24d484 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -56,3 +56,4 @@ byteorder = { version = "1.1", features = ["i128"]} # later crate stop compiling. If you can remove this and everything # compiles, then please feel free to do so! flate2 = "1.0" +tempdir = "0.3" diff --git a/src/tools/cargo b/src/tools/cargo index d10ec661b064..311a5eda6f90 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d10ec661b06420654bbc4ed0ccd32295698aa1dc +Subproject commit 311a5eda6f90d660bb23e97c8ee77090519b9eda diff --git a/src/tools/rls b/src/tools/rls index 974c515493f2..f5a0c91a3936 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 974c515493f212a21a55b7370c25bcc231f33535 +Subproject commit f5a0c91a39368395b1c1ad322e04be7b6074bc65 diff --git a/src/tools/unstable-book-gen/Cargo.toml b/src/tools/unstable-book-gen/Cargo.toml index 4751a5e41510..2839f93f8e27 100644 --- a/src/tools/unstable-book-gen/Cargo.toml +++ b/src/tools/unstable-book-gen/Cargo.toml @@ -7,3 +7,7 @@ license = "MIT/Apache-2.0" [dependencies] tidy = { path = "../tidy" } + +# not actually needed but required for now to unify the feature selection of +# `num-traits` between this and `rustbook` +num-traits = "0.2" From a637dd00c8536d86cfbe59d8a3881e29b3e55eeb Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 26 Mar 2018 02:47:04 +0300 Subject: [PATCH 648/830] Fix pretty-printing for raw identifiers --- src/librustc/hir/print.rs | 8 ++++++-- src/libsyntax/parse/token.rs | 9 ++++++++- src/libsyntax/print/pprust.rs | 6 +++++- src/test/run-pass/rfc-2151-raw-identifiers/attr.rs | 2 -- src/test/run-pass/rfc-2151-raw-identifiers/basic.rs | 2 -- src/test/run-pass/rfc-2151-raw-identifiers/items.rs | 2 -- src/test/run-pass/rfc-2151-raw-identifiers/macros.rs | 2 -- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 3d38c0c8ed9e..ff501f30c891 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -13,7 +13,7 @@ pub use self::AnnNode::*; use syntax::abi::Abi; use syntax::ast; use syntax::codemap::{CodeMap, Spanned}; -use syntax::parse::ParseSess; +use syntax::parse::{token, ParseSess}; use syntax::parse::lexer::comments; use syntax::print::pp::{self, Breaks}; use syntax::print::pp::Breaks::{Consistent, Inconsistent}; @@ -1561,7 +1561,11 @@ impl<'a> State<'a> { } pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { - self.s.word(&name.as_str())?; + if token::is_raw_guess(ast::Ident::with_empty_ctxt(name)) { + self.s.word(&format!("r#{}", name))?; + } else { + self.s.word(&name.as_str())?; + } self.ann.post(self, NodeName(&name)) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 7798a7a77ee6..e2dfca5d10a3 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -142,6 +142,13 @@ pub fn is_path_segment_keyword(id: ast::Ident) -> bool { id.name == keywords::DollarCrate.name() } +// We see this identifier in a normal identifier position, like variable name or a type. +// How was it written originally? Did it use the raw form? Let's try to guess. +pub fn is_raw_guess(ident: ast::Ident) -> bool { + ident.name != keywords::Invalid.name() && + is_reserved_ident(ident) && !is_path_segment_keyword(ident) +} + // Returns true for reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. pub fn is_special_ident(id: ast::Ident) -> bool { @@ -236,7 +243,7 @@ impl Token { /// Recovers a `Token` from an `ast::Ident`. This creates a raw identifier if necessary. pub fn from_ast_ident(ident: ast::Ident) -> Token { - Ident(ident, is_reserved_ident(ident) && !is_path_segment_keyword(ident)) + Ident(ident, is_raw_guess(ident)) } /// Returns `true` if the token starts with '>'. diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 50577a26abf4..ae045fc095a5 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2373,7 +2373,11 @@ impl<'a> State<'a> { } pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> { - self.s.word(&ident.name.as_str())?; + if token::is_raw_guess(ident) { + self.s.word(&format!("r#{}", ident))?; + } else { + self.s.word(&ident.name.as_str())?; + } self.ann.post(self, NodeIdent(&ident)) } diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs index 3566babaf4cb..6cea75cf1d11 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/attr.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty - #![feature(raw_identifiers)] use std::mem; diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs index bd1f52a9b24e..5d495c4e9e55 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/basic.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty - #![feature(raw_identifiers)] fn r#fn(r#match: u32) -> u32 { diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs index 5fdc13df8dcb..256bd263d38d 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/items.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/items.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty - #![feature(raw_identifiers)] #[derive(Debug, PartialEq, Eq)] diff --git a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs index 82d44c57e181..4bd16ded52fb 100644 --- a/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs +++ b/src/test/run-pass/rfc-2151-raw-identifiers/macros.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty - #![feature(decl_macro)] #![feature(raw_identifiers)] From c08902b084081867ee437d621e605d231d2ba109 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 15:21:36 +0000 Subject: [PATCH 649/830] Prevent deprecation warning for items deprecated in the future --- src/librustc/middle/stability.rs | 36 ++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 29c8ac046b81..652920f95c3c 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -559,9 +559,41 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { + fn deprecation_in_effect(since: Option<&str>, rustc: Option<&str>) -> bool { + fn parse_version(ver: &str) -> Vec { + // We ignore non-integer components of the version (e.g. "nightly"). + ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() + } + + if since.is_none() || rustc.is_none() { + // By default, a deprecation warning applies to + // the current version of the compiler. + true + } else { + let since: Vec = parse_version(since.unwrap()); + let rustc: Vec = parse_version(rustc.unwrap()); + // We simply treat invalid `since` attributes as relating to a previous + // Rust version, thus always displaying the warning. + if since.len() != 3 { + return true; + } + since <= rustc + } + } + + // If the deprecation is scheduled for a future Rust + // version, then we should display no warning message. + let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since { + let since = sym.as_str(); + !deprecation_in_effect(Some(since.as_ref()), option_env!("CFG_RELEASE")) + } else { + false + }; + let parent_def_id = self.hir.local_def_id(self.hir.get_parent(id)); - let skip = self.lookup_deprecation_entry(parent_def_id) - .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); + let skip = deprecated_in_future_version || + self.lookup_deprecation_entry(parent_def_id) + .map_or(false, |parent_depr| parent_depr.same_origin(&depr_entry)); if !skip { lint_deprecated(def_id, id, depr_entry.attr.note); } From ecaf1f57eaeca759528f1ef99017a7ee4763e307 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 15:51:11 +0000 Subject: [PATCH 650/830] Add future deprecation warning to rustdoc --- src/librustc/middle/stability.rs | 48 +++++++++++++++++--------------- src/librustdoc/html/render.rs | 22 ++++++++++++--- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 652920f95c3c..d1202b59e04f 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -470,6 +470,30 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor()); } +/// Check whether an item marked with `deprecated(since="X")` is currently +/// deprecated (i.e. whether X is not greater than the current rustc version). +pub fn deprecation_in_effect(since: &str) -> bool { + fn parse_version(ver: &str) -> Vec { + // We ignore non-integer components of the version (e.g. "nightly"). + ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() + } + + if let Some(rustc) = option_env!("CFG_RELEASE") { + let since: Vec = parse_version(since); + let rustc: Vec = parse_version(rustc); + // We simply treat invalid `since` attributes as relating to a previous + // Rust version, thus always displaying the warning. + if since.len() != 3 { + return true; + } + since <= rustc + } else { + // By default, a deprecation warning applies to + // the current version of the compiler. + true + } +} + struct Checker<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, } @@ -559,33 +583,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // Deprecated attributes apply in-crate and cross-crate. if let Some(id) = id { if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) { - fn deprecation_in_effect(since: Option<&str>, rustc: Option<&str>) -> bool { - fn parse_version(ver: &str) -> Vec { - // We ignore non-integer components of the version (e.g. "nightly"). - ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect() - } - - if since.is_none() || rustc.is_none() { - // By default, a deprecation warning applies to - // the current version of the compiler. - true - } else { - let since: Vec = parse_version(since.unwrap()); - let rustc: Vec = parse_version(rustc.unwrap()); - // We simply treat invalid `since` attributes as relating to a previous - // Rust version, thus always displaying the warning. - if since.len() != 3 { - return true; - } - since <= rustc - } - } - // If the deprecation is scheduled for a future Rust // version, then we should display no warning message. let deprecated_in_future_version = if let Some(sym) = depr_entry.attr.since { let since = sym.as_str(); - !deprecation_in_effect(Some(since.as_ref()), option_env!("CFG_RELEASE")) + !deprecation_in_effect(since.as_ref()) } else { false }; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 678e1762a551..5c7825f2dd62 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2108,9 +2108,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec{}", text)) }; @@ -2160,7 +2166,15 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec{}", text)) } From 101e17df96f528bba1ea661751edc65175bc9e3c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Mar 2018 17:02:04 +0000 Subject: [PATCH 651/830] Add tests for items deprecated in the future --- src/test/compile-fail/deprecation-lint.rs | 8 ++++++++ src/test/rustdoc/deprecated-future.rs | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/test/rustdoc/deprecated-future.rs diff --git a/src/test/compile-fail/deprecation-lint.rs b/src/test/compile-fail/deprecation-lint.rs index a058234a6492..93eb6b6b1154 100644 --- a/src/test/compile-fail/deprecation-lint.rs +++ b/src/test/compile-fail/deprecation-lint.rs @@ -180,6 +180,11 @@ mod this_crate { #[deprecated(since = "1.0.0", note = "text")] pub fn deprecated_text() {} + #[deprecated(since = "99.99.99", note = "text")] + pub fn deprecated_future() {} + #[deprecated(since = "99.99.99", note = "text")] + pub fn deprecated_future_text() {} + pub struct MethodTester; impl MethodTester { @@ -266,6 +271,9 @@ mod this_crate { ::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text ::trait_deprecated_text(&foo); //~ ERROR use of deprecated item 'this_crate::Trait::trait_deprecated_text': text + deprecated_future(); // Fine; no error. + deprecated_future_text(); // Fine; no error. + let _ = DeprecatedStruct { //~^ ERROR use of deprecated item 'this_crate::DeprecatedStruct': text i: 0 //~ ERROR use of deprecated item 'this_crate::DeprecatedStruct::i': text diff --git a/src/test/rustdoc/deprecated-future.rs b/src/test/rustdoc/deprecated-future.rs new file mode 100644 index 000000000000..6ba54039ed3f --- /dev/null +++ b/src/test/rustdoc/deprecated-future.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(deprecated)] + +// @has deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \ +// 'This will be deprecated in 99.99.99: effectively never' +#[deprecated(since = "99.99.99", note = "effectively never")] +pub struct S; From 9c7b69e17909ceb090a1c4b8882a4e0924a2a755 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 26 Mar 2018 22:24:03 +0100 Subject: [PATCH 652/830] Remove mentions of unstable sort_by_cached key from stable documentation --- src/liballoc/slice.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 2b4ce9fe49c8..68f2313843c3 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1306,10 +1306,6 @@ impl [T] { /// This sort is stable (i.e. does not reorder equal elements) and `O(m n log(m n))` /// worst-case, where the key function is `O(m)`. /// - /// For expensive key functions (e.g. functions that are not simple property accesses or - /// basic operations), [`sort_by_cached_key`](#method.sort_by_cached_key) is likely to be - /// significantly faster, as it does not recompute element keys. - /// /// When applicable, unstable sorting is preferred because it is generally faster than stable /// sorting and it doesn't allocate auxiliary memory. /// See [`sort_unstable_by_key`](#method.sort_unstable_by_key). @@ -1496,10 +1492,6 @@ impl [T] { /// randomization to avoid degenerate cases, but with a fixed seed to always provide /// deterministic behavior. /// - /// Due to its key calling strategy, [`sort_unstable_by_key`](#method.sort_unstable_by_key) - /// is likely to be slower than [`sort_by_cached_key`](#method.sort_by_cached_key) in - /// cases where the key function is expensive. - /// /// # Examples /// /// ``` From 2178ef8b220daec3228f6f4dae60787e506fa089 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 23 Mar 2018 13:36:08 +0100 Subject: [PATCH 653/830] TryFrom for integers: use From instead for truely-infallible impls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is precendent in C for having a minimum pointer size, but I don’t feel confident enough about the future to mandate a maximum. --- src/libcore/num/mod.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index a5ba0bcdf7e6..fa535e0e6283 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3804,14 +3804,11 @@ mod ptr_try_from_impls { try_from_both_bounded!(isize, i8); try_from_unbounded!(isize, i16, i32, i64, i128); - rev!(try_from_unbounded, usize, u16); rev!(try_from_upper_bounded, usize, u32, u64, u128); rev!(try_from_lower_bounded, usize, i8, i16); rev!(try_from_both_bounded, usize, i32, i64, i128); - rev!(try_from_unbounded, isize, u8); rev!(try_from_upper_bounded, isize, u16, u32, u64, u128); - rev!(try_from_unbounded, isize, i16); rev!(try_from_both_bounded, isize, i32, i64, i128); } @@ -3830,14 +3827,14 @@ mod ptr_try_from_impls { try_from_both_bounded!(isize, i8, i16); try_from_unbounded!(isize, i32, i64, i128); - rev!(try_from_unbounded, usize, u16, u32); + rev!(try_from_unbounded, usize, u32); rev!(try_from_upper_bounded, usize, u64, u128); rev!(try_from_lower_bounded, usize, i8, i16, i32); rev!(try_from_both_bounded, usize, i64, i128); - rev!(try_from_unbounded, isize, u8, u16); + rev!(try_from_unbounded, isize, u16); rev!(try_from_upper_bounded, isize, u32, u64, u128); - rev!(try_from_unbounded, isize, i16, i32); + rev!(try_from_unbounded, isize, i32); rev!(try_from_both_bounded, isize, i64, i128); } @@ -3856,14 +3853,14 @@ mod ptr_try_from_impls { try_from_both_bounded!(isize, i8, i16, i32); try_from_unbounded!(isize, i64, i128); - rev!(try_from_unbounded, usize, u16, u32, u64); + rev!(try_from_unbounded, usize, u32, u64); rev!(try_from_upper_bounded, usize, u128); rev!(try_from_lower_bounded, usize, i8, i16, i32, i64); rev!(try_from_both_bounded, usize, i128); - rev!(try_from_unbounded, isize, u8, u16, u32); + rev!(try_from_unbounded, isize, u16, u32); rev!(try_from_upper_bounded, isize, u64, u128); - rev!(try_from_unbounded, isize, i16, i32, i64); + rev!(try_from_unbounded, isize, i32, i64); rev!(try_from_both_bounded, isize, i128); } @@ -4074,6 +4071,20 @@ impl_from! { u32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] impl_from! { u32, i128, #[stable(feature = "i128", since = "1.26.0")] } impl_from! { u64, i128, #[stable(feature = "i128", since = "1.26.0")] } +// The C99 standard defines bounds on INTPTR_MIN, INTPTR_MAX, and UINTPTR_MAX +// which imply that pointer-sized integers must be at least 16 bits: +// https://port70.net/~nsz/c/c99/n1256.html#7.18.2.4 +impl_from! { u16, usize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] } +impl_from! { u8, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] } +impl_from! { i16, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] } + +// RISC-V defines the possibility of a 128-bit address space (RV128). + +// CHERI proposes 256-bit “capabilities”. Unclear if this would be relevant to usize/isize. +// https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/20171017a-cheri-poster.pdf +// http://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf + + // Note: integers can only be represented with full precision in a float if // they fit in the significand, which is 24 bits in f32 and 53 bits in f64. // Lossy float conversions are not implemented at this time. From 9fd399feb149bb7b58f21c54fc8c9358fea487a2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 23 Mar 2018 13:42:43 +0100 Subject: [PATCH 654/830] =?UTF-8?q?Don=E2=80=99t=20use=20`type=20Error=20?= =?UTF-8?q?=3D=20!`=20for=20target-dependant=20TryFrom=20impls.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, expose apparently-fallible conversions in cases where the implementation happens to be infallible for a given target. Having an associated type / return type in a public API change based on the target is a portability hazard. --- src/libcore/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index fa535e0e6283..2da5718a358d 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3681,7 +3681,7 @@ macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( #[unstable(feature = "try_from", issue = "33417")] impl TryFrom<$source> for $target { - type Error = !; + type Error = TryFromIntError; #[inline] fn try_from(value: $source) -> Result { From e53a2a72743810e05f58c61c9d8a4c89b712ad2e Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 23 Mar 2018 13:52:54 +0100 Subject: [PATCH 655/830] Stabilize the TryFrom and TryInto traits Tracking issue: https://github.com/rust-lang/rust/issues/33417 --- src/libcore/array.rs | 6 +++--- src/libcore/char.rs | 6 +++--- src/libcore/convert.rs | 12 ++++++++---- src/libcore/num/mod.rs | 14 +++++++------- src/libcore/tests/lib.rs | 1 - src/librustc_apfloat/lib.rs | 2 +- src/libstd/error.rs | 6 +++--- src/libstd/lib.rs | 1 - src/libstd_unicode/char.rs | 2 +- src/libstd_unicode/lib.rs | 1 - src/test/ui/e0119/conflict-with-std.rs | 2 -- src/test/ui/e0119/conflict-with-std.stderr | 6 +++--- 12 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 3d24f8902bd8..87144c27c9e1 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -59,7 +59,7 @@ unsafe impl> FixedSizeArray for A { } /// The error type returned when a conversion from a slice to an array fails. -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] #[derive(Debug, Copy, Clone)] pub struct TryFromSliceError(()); @@ -148,7 +148,7 @@ macro_rules! array_impls { } } - #[unstable(feature = "try_from", issue = "33417")] + #[stable(feature = "try_from", since = "1.26.0")] impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] { type Error = TryFromSliceError; @@ -162,7 +162,7 @@ macro_rules! array_impls { } } - #[unstable(feature = "try_from", issue = "33417")] + #[stable(feature = "try_from", since = "1.26.0")] impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] { type Error = TryFromSliceError; diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 1638f9710f59..bbeebf52a73c 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -265,7 +265,7 @@ impl FromStr for char { } -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl TryFrom for char { type Error = CharTryFromError; @@ -280,11 +280,11 @@ impl TryFrom for char { } /// The error type returned when a conversion from u32 to char fails. -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct CharTryFromError(()); -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl fmt::Display for CharTryFromError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "converted integer out of range for `char`".fmt(f) diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index 7324df95bc5d..637213957848 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -322,22 +322,26 @@ pub trait From: Sized { /// /// [`TryFrom`]: trait.TryFrom.html /// [`Into`]: trait.Into.html -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] pub trait TryInto: Sized { /// The type returned in the event of a conversion error. + #[stable(feature = "try_from", since = "1.26.0")] type Error; /// Performs the conversion. + #[stable(feature = "try_from", since = "1.26.0")] fn try_into(self) -> Result; } /// Attempt to construct `Self` via a conversion. -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] pub trait TryFrom: Sized { /// The type returned in the event of a conversion error. + #[stable(feature = "try_from", since = "1.26.0")] type Error; /// Performs the conversion. + #[stable(feature = "try_from", since = "1.26.0")] fn try_from(value: T) -> Result; } @@ -405,7 +409,7 @@ impl From for T { // TryFrom implies TryInto -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl TryInto for T where U: TryFrom { type Error = U::Error; @@ -417,7 +421,7 @@ impl TryInto for T where U: TryFrom // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl TryFrom for T where T: From { type Error = !; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 2da5718a358d..8f7e8d0c8ab7 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3647,7 +3647,7 @@ macro_rules! from_str_radix_int_impl { from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 } /// The error type returned when a checked integral type conversion fails. -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] #[derive(Debug, Copy, Clone)] pub struct TryFromIntError(()); @@ -3662,14 +3662,14 @@ impl TryFromIntError { } } -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl fmt::Display for TryFromIntError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { self.__description().fmt(fmt) } } -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl From for TryFromIntError { fn from(never: !) -> TryFromIntError { never @@ -3679,7 +3679,7 @@ impl From for TryFromIntError { // no possible bounds violation macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( - #[unstable(feature = "try_from", issue = "33417")] + #[stable(feature = "try_from", since = "1.26.0")] impl TryFrom<$source> for $target { type Error = TryFromIntError; @@ -3694,7 +3694,7 @@ macro_rules! try_from_unbounded { // only negative bounds macro_rules! try_from_lower_bounded { ($source:ty, $($target:ty),*) => {$( - #[unstable(feature = "try_from", issue = "33417")] + #[stable(feature = "try_from", since = "1.26.0")] impl TryFrom<$source> for $target { type Error = TryFromIntError; @@ -3713,7 +3713,7 @@ macro_rules! try_from_lower_bounded { // unsigned to signed (only positive bound) macro_rules! try_from_upper_bounded { ($source:ty, $($target:ty),*) => {$( - #[unstable(feature = "try_from", issue = "33417")] + #[stable(feature = "try_from", since = "1.26.0")] impl TryFrom<$source> for $target { type Error = TryFromIntError; @@ -3732,7 +3732,7 @@ macro_rules! try_from_upper_bounded { // all other cases macro_rules! try_from_both_bounded { ($source:ty, $($target:ty),*) => {$( - #[unstable(feature = "try_from", issue = "33417")] + #[stable(feature = "try_from", since = "1.26.0")] impl TryFrom<$source> for $target { type Error = TryFromIntError; diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 0b70f6924036..1a68f04532d2 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -43,7 +43,6 @@ #![feature(step_trait)] #![feature(test)] #![feature(trusted_len)] -#![feature(try_from)] #![feature(try_trait)] #![feature(exact_chunks)] #![feature(atomic_nand)] diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 2ee7bea84765..6f08fcf70259 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -48,7 +48,7 @@ #![cfg_attr(stage0, feature(slice_patterns))] #![cfg_attr(stage0, feature(i128_type))] -#![feature(try_from)] +#![cfg_attr(stage0, feature(try_from))] // See librustc_cratesio_shim/Cargo.toml for a comment explaining this. #[allow(unused_extern_crates)] diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 79bb6af168fa..3d0c96585b55 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -275,14 +275,14 @@ impl Error for num::ParseIntError { } } -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl Error for num::TryFromIntError { fn description(&self) -> &str { self.__description() } } -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl Error for array::TryFromSliceError { fn description(&self) -> &str { self.__description() @@ -356,7 +356,7 @@ impl Error for cell::BorrowMutError { } } -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] impl Error for char::CharTryFromError { fn description(&self) -> &str { "converted integer out of range for `char`" diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 93996868f16c..15a22443b6af 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -310,7 +310,6 @@ #![feature(test, rustc_private)] #![feature(thread_local)] #![feature(toowned_clone_into)] -#![feature(try_from)] #![feature(try_reserve)] #![feature(unboxed_closures)] #![feature(unicode)] diff --git a/src/libstd_unicode/char.rs b/src/libstd_unicode/char.rs index de8b46d5f1b0..33e47ade8cb9 100644 --- a/src/libstd_unicode/char.rs +++ b/src/libstd_unicode/char.rs @@ -42,7 +42,7 @@ pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode}; pub use core::char::ParseCharError; // unstable re-exports -#[unstable(feature = "try_from", issue = "33417")] +#[stable(feature = "try_from", since = "1.26.0")] pub use core::char::CharTryFromError; #[unstable(feature = "decode_utf8", issue = "33906")] pub use core::char::{DecodeUtf8, decode_utf8}; diff --git a/src/libstd_unicode/lib.rs b/src/libstd_unicode/lib.rs index f155b62e3cc7..c22ea1671fa5 100644 --- a/src/libstd_unicode/lib.rs +++ b/src/libstd_unicode/lib.rs @@ -39,7 +39,6 @@ #![feature(lang_items)] #![feature(non_exhaustive)] #![feature(staged_api)] -#![feature(try_from)] #![feature(unboxed_closures)] mod bool_trie; diff --git a/src/test/ui/e0119/conflict-with-std.rs b/src/test/ui/e0119/conflict-with-std.rs index ed9033ad53d5..a9f747d09ec2 100644 --- a/src/test/ui/e0119/conflict-with-std.rs +++ b/src/test/ui/e0119/conflict-with-std.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(try_from)] - use std::marker::PhantomData; use std::convert::{TryFrom, AsRef}; diff --git a/src/test/ui/e0119/conflict-with-std.stderr b/src/test/ui/e0119/conflict-with-std.stderr index e8b2c84c0df0..417ff1de3f81 100644 --- a/src/test/ui/e0119/conflict-with-std.stderr +++ b/src/test/ui/e0119/conflict-with-std.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `std::convert::AsRef` for type `std::boxed::Box`: - --> $DIR/conflict-with-std.rs:17:1 + --> $DIR/conflict-with-std.rs:15:1 | LL | impl AsRef for Box { //~ ERROR conflicting implementations | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | impl AsRef for Box { //~ ERROR conflicting implementations where T: ?Sized; error[E0119]: conflicting implementations of trait `std::convert::From` for type `S`: - --> $DIR/conflict-with-std.rs:24:1 + --> $DIR/conflict-with-std.rs:22:1 | LL | impl From for S { //~ ERROR conflicting implementations | ^^^^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | impl From for S { //~ ERROR conflicting implementations - impl std::convert::From for T; error[E0119]: conflicting implementations of trait `std::convert::TryFrom` for type `X`: - --> $DIR/conflict-with-std.rs:31:1 + --> $DIR/conflict-with-std.rs:29:1 | LL | impl TryFrom for X { //~ ERROR conflicting implementations | ^^^^^^^^^^^^^^^^^^^^^ From 09008cc23ff6395c2c928f3690e07d7389d08ebc Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 26 Mar 2018 11:17:31 +0200 Subject: [PATCH 656/830] Add TryFrom and TryInto to the prelude --- src/libcore/prelude/v1.rs | 3 +++ src/libstd/prelude/v1.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index d43496c387cb..2c8e27abac9c 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -39,6 +39,9 @@ pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From}; +#[stable(feature = "try_from", since = "1.26.0")] +#[doc(no_inline)] +pub use convert::{TryFrom, TryInto}; #[stable(feature = "core_prelude", since = "1.4.0")] #[doc(no_inline)] pub use default::Default; diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index feedd4e1abe5..d5b7c68a3fa8 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -35,6 +35,8 @@ #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use convert::{AsRef, AsMut, Into, From}; +#[stable(feature = "try_from", since = "1.26.0")] +#[doc(no_inline)] pub use convert::{TryFrom, TryInto}; #[stable(feature = "rust1", since = "1.0.0")] #[doc(no_inline)] pub use default::Default; #[stable(feature = "rust1", since = "1.0.0")] From 604bbee84cbd0ef5064bfd6b40c384268b1b38c0 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 27 Mar 2018 00:45:28 +0300 Subject: [PATCH 657/830] libsyntax: Remove obsolete.rs --- src/libsyntax/parse/mod.rs | 1 - src/libsyntax/parse/obsolete.rs | 67 --------------------------------- src/libsyntax/parse/parser.rs | 6 --- 3 files changed, 74 deletions(-) delete mode 100644 src/libsyntax/parse/obsolete.rs diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 7b39db16ac2c..1483691a1eae 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -40,7 +40,6 @@ pub mod attr; pub mod common; pub mod classify; -pub mod obsolete; /// Info about a parsing session. pub struct ParseSess { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs deleted file mode 100644 index 49a697edf416..000000000000 --- a/src/libsyntax/parse/obsolete.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2012-2014 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. - -//! Support for parsing unsupported, old syntaxes, for the purpose of reporting errors. Parsing of -//! these syntaxes is tested by compile-test/obsolete-syntax.rs. -//! -//! Obsolete syntax that becomes too hard to parse can be removed. - -use syntax_pos::Span; -use parse::parser; - -/// The specific types of unsupported syntax -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub enum ObsoleteSyntax { - // Nothing here at the moment -} - -pub trait ParserObsoleteMethods { - /// Reports an obsolete syntax non-fatal error. - fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax); - fn report(&mut self, - sp: Span, - kind: ObsoleteSyntax, - kind_str: &str, - desc: &str, - error: bool); -} - -impl<'a> ParserObsoleteMethods for parser::Parser<'a> { - /// Reports an obsolete syntax non-fatal error. - #[allow(unused_variables)] - #[allow(unreachable_code)] - fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) { - let (kind_str, desc, error) = match kind { - // Nothing here at the moment - }; - - self.report(sp, kind, kind_str, desc, error); - } - - fn report(&mut self, - sp: Span, - kind: ObsoleteSyntax, - kind_str: &str, - desc: &str, - error: bool) { - let mut err = if error { - self.diagnostic().struct_span_err(sp, &format!("obsolete syntax: {}", kind_str)) - } else { - self.diagnostic().struct_span_warn(sp, &format!("obsolete syntax: {}", kind_str)) - }; - - if !self.obsolete_set.contains(&kind) && - (error || self.sess.span_diagnostic.flags.can_emit_warnings) { - 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 98e2528d30f2..b4b21285d3b2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -48,7 +48,6 @@ use parse::{self, classify, token}; use parse::common::SeqSep; use parse::lexer::TokenAndSpan; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; -use parse::obsolete::ObsoleteSyntax; use parse::{new_sub_parser_from_file, ParseSess, Directory, DirectoryOwnership}; use util::parser::{AssocOp, Fixity}; use print::pprust; @@ -59,7 +58,6 @@ use symbol::{Symbol, keywords}; use util::ThinVec; use std::cmp; -use std::collections::HashSet; use std::mem; use std::path::{self, Path, PathBuf}; use std::slice; @@ -229,9 +227,6 @@ pub struct Parser<'a> { /// the previous token kind prev_token_kind: PrevTokenKind, pub restrictions: Restrictions, - /// The set of seen errors about obsolete syntax. Used to suppress - /// extra detail when the same error is seen twice - pub obsolete_set: HashSet, /// Used to determine the path to externally loaded source files pub directory: Directory, /// Whether to parse sub-modules in other files. @@ -555,7 +550,6 @@ impl<'a> Parser<'a> { meta_var_span: None, prev_token_kind: PrevTokenKind::Other, restrictions: Restrictions::empty(), - obsolete_set: HashSet::new(), recurse_into_file_modules, directory: Directory { path: PathBuf::new(), From 0f1c649827108e11313376d2ea6cec7c9e8feb7c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 26 Mar 2018 16:20:11 -0700 Subject: [PATCH 658/830] Fix diagnostic colors on Windows 10 console. This updates termcolor to pick up BurntSushi/ripgrep#867. Fixes #49322. --- src/Cargo.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index c4707707be08..ad745d29e15e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -202,7 +202,7 @@ dependencies = [ "shell-escape 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -558,7 +558,7 @@ dependencies = [ "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1543,7 +1543,7 @@ dependencies = [ "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-ap-syntax_pos 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1721,7 +1721,7 @@ dependencies = [ "rustc_data_structures 0.0.0", "serialize 0.0.0", "syntax_pos 0.0.0", - "termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2326,7 +2326,7 @@ dependencies = [ [[package]] name = "termcolor" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2765,7 +2765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" -"checksum termcolor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "56c456352e44f9f91f774ddeeed27c1ec60a2455ed66d692059acfb1d731bda1" +"checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" From 04f6692aaf78809c041ba6145bde2dcbeec9725e Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Mon, 26 Mar 2018 23:24:31 +0100 Subject: [PATCH 659/830] Implement `shrink_to` method on collections --- src/liballoc/binary_heap.rs | 25 +++++++++++++++++++ src/liballoc/string.rs | 28 +++++++++++++++++++++ src/liballoc/vec.rs | 27 +++++++++++++++++++- src/liballoc/vec_deque.rs | 35 +++++++++++++++++++++++++- src/libstd/collections/hash/map.rs | 40 ++++++++++++++++++++++++++++++ src/libstd/collections/hash/set.rs | 28 +++++++++++++++++++++ src/libstd/ffi/os_str.rs | 30 ++++++++++++++++++++++ src/libstd/lib.rs | 1 + src/libstd/sys/redox/os_str.rs | 5 ++++ src/libstd/sys/unix/os_str.rs | 5 ++++ src/libstd/sys/wasm/os_str.rs | 5 ++++ src/libstd/sys/windows/os_str.rs | 5 ++++ src/libstd/sys_common/wtf8.rs | 5 ++++ 13 files changed, 237 insertions(+), 2 deletions(-) diff --git a/src/liballoc/binary_heap.rs b/src/liballoc/binary_heap.rs index 8aaac5d6e08a..f6a666b599b0 100644 --- a/src/liballoc/binary_heap.rs +++ b/src/liballoc/binary_heap.rs @@ -509,6 +509,31 @@ impl BinaryHeap { self.data.shrink_to_fit(); } + /// Discards capacity with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::BinaryHeap; + /// let mut heap: BinaryHeap = BinaryHeap::with_capacity(100); + /// + /// assert!(heap.capacity() >= 100); + /// heap.shrink_to(10); + /// assert!(heap.capacity() >= 10); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.data.shrink_to(min_capacity) + } + /// Removes the greatest item from the binary heap and returns it, or `None` if it /// is empty. /// diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index e253122ffd6b..2bb60a50679e 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1015,6 +1015,34 @@ impl String { self.vec.shrink_to_fit() } + /// Shrinks the capacity of this `String` with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// let mut s = String::from("foo"); + /// + /// s.reserve(100); + /// assert!(s.capacity() >= 100); + /// + /// s.shrink_to(10); + /// assert!(s.capacity() >= 10); + /// s.shrink_to(0); + /// assert!(s.capacity() >= 3); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.vec.shrink_to(min_capacity) + } + /// Appends the given [`char`] to the end of this `String`. /// /// [`char`]: ../../std/primitive.char.html diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 953f95876be1..c9c6cf1cb669 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -66,7 +66,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use core::cmp::Ordering; +use core::cmp::{self, Ordering}; use core::fmt; use core::hash::{self, Hash}; use core::intrinsics::{arith_offset, assume}; @@ -586,6 +586,31 @@ impl Vec { self.buf.shrink_to_fit(self.len); } + /// Shrinks the capacity of the vector with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// let mut vec = Vec::with_capacity(10); + /// vec.extend([1, 2, 3].iter().cloned()); + /// assert_eq!(vec.capacity(), 10); + /// vec.shrink_to(4); + /// assert!(vec.capacity() >= 4); + /// vec.shrink_to(0); + /// assert!(vec.capacity() >= 3); + /// ``` + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.buf.shrink_to_fit(cmp::max(self.len, min_capacity)); + } + /// Converts the vector into [`Box<[T]>`][owned slice]. /// /// Note that this will drop any excess capacity. diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index 0658777f0a0e..be6e8d0f22f0 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -676,9 +676,42 @@ impl VecDeque { /// ``` #[stable(feature = "deque_extras_15", since = "1.5.0")] pub fn shrink_to_fit(&mut self) { + self.shrink_to(0); + } + + /// Shrinks the capacity of the `VecDeque` with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::VecDeque; + /// + /// let mut buf = VecDeque::with_capacity(15); + /// buf.extend(0..4); + /// assert_eq!(buf.capacity(), 15); + /// buf.shrink_to(6); + /// assert!(buf.capacity() >= 6); + /// buf.shrink_to(0); + /// assert!(buf.capacity() >= 4); + /// ``` + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity"); + // +1 since the ringbuffer always leaves one space empty // len + 1 can't overflow for an existing, well-formed ringbuffer. - let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); + let target_cap = cmp::max( + cmp::max(min_capacity, self.len()) + 1, + MINIMUM_CAPACITY + 1 + ).next_power_of_two(); + if target_cap < self.cap() { // There are three cases of interest: // All elements are out of desired bounds diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index b18b38ec3024..169d365c0ac5 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -910,6 +910,46 @@ impl HashMap } } + /// Shrinks the capacity of the map with a lower limit. It will drop + /// down no lower than the supplied limit while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::HashMap; + /// + /// let mut map: HashMap = HashMap::with_capacity(100); + /// map.insert(1, 2); + /// map.insert(3, 4); + /// assert!(map.capacity() >= 100); + /// map.shrink_to(10); + /// assert!(map.capacity() >= 10); + /// map.shrink_to(0); + /// assert!(map.capacity() >= 2); + /// ``` + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + assert!(self.capacity() >= min_capacity, "Tried to shrink to a larger capacity"); + + let new_raw_cap = self.resize_policy.raw_capacity(max(self.len(), min_capacity)); + if self.raw_capacity() != new_raw_cap { + let old_table = replace(&mut self.table, RawTable::new(new_raw_cap)); + let old_size = old_table.size(); + + // Shrink the table. Naive algorithm for resizing: + for (h, k, v) in old_table.into_iter() { + self.insert_hashed_nocheck(h, k, v); + } + + debug_assert_eq!(self.table.size(), old_size); + } + } + /// Insert a pre-hashed key-value pair, without first checking /// that there's enough room in the buckets. Returns a reference to the /// newly insert value. diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 9e63ba2717a6..855563a5cb8d 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -292,6 +292,34 @@ impl HashSet self.map.shrink_to_fit() } + /// Shrinks the capacity of the set with a lower limit. It will drop + /// down no lower than the supplied limit while maintaining the internal rules + /// and possibly leaving some space in accordance with the resize policy. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::collections::HashSet; + /// + /// let mut set = HashSet::with_capacity(100); + /// set.insert(1); + /// set.insert(2); + /// assert!(set.capacity() >= 100); + /// set.shrink_to(10); + /// assert!(set.capacity() >= 10); + /// set.shrink_to(0); + /// assert!(set.capacity() >= 2); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.map.shrink_to(min_capacity) + } + /// An iterator visiting all elements in arbitrary order. /// The iterator element type is `&'a T`. /// diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 3959e8533be5..7520121a8c29 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -295,6 +295,36 @@ impl OsString { self.inner.shrink_to_fit() } + /// Shrinks the capacity of the `OsString` with a lower bound. + /// + /// The capacity will remain at least as large as both the length + /// and the supplied value. + /// + /// Panics if the current capacity is smaller than the supplied + /// minimum capacity. + /// + /// # Examples + /// + /// ``` + /// #![feature(shrink_to)] + /// use std::ffi::OsString; + /// + /// let mut s = OsString::from("foo"); + /// + /// s.reserve(100); + /// assert!(s.capacity() >= 100); + /// + /// s.shrink_to(10); + /// assert!(s.capacity() >= 10); + /// s.shrink_to(0); + /// assert!(s.capacity() >= 3); + /// ``` + #[inline] + #[unstable(feature = "shrink_to", reason = "new API", issue="0")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + /// Converts this `OsString` into a boxed [`OsStr`]. /// /// [`OsStr`]: struct.OsStr.html diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 0b06c5d4d656..edecf309d16f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -299,6 +299,7 @@ #![feature(raw)] #![feature(rustc_attrs)] #![feature(stdsimd)] +#![feature(shrink_to)] #![feature(slice_bytes)] #![feature(slice_concat_ext)] #![feature(slice_internals)] diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs index 655bfdb91670..da27787babb9 100644 --- a/src/libstd/sys/redox/os_str.rs +++ b/src/libstd/sys/redox/os_str.rs @@ -104,6 +104,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + pub fn as_slice(&self) -> &Slice { unsafe { mem::transmute(&*self.inner) } } diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs index e03493879986..e43bc6da5f1f 100644 --- a/src/libstd/sys/unix/os_str.rs +++ b/src/libstd/sys/unix/os_str.rs @@ -104,6 +104,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + pub fn as_slice(&self) -> &Slice { unsafe { mem::transmute(&*self.inner) } } diff --git a/src/libstd/sys/wasm/os_str.rs b/src/libstd/sys/wasm/os_str.rs index 543c22ebe18a..84f560af69be 100644 --- a/src/libstd/sys/wasm/os_str.rs +++ b/src/libstd/sys/wasm/os_str.rs @@ -104,6 +104,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + pub fn as_slice(&self) -> &Slice { unsafe { mem::transmute(&*self.inner) } } diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs index 414c9c5418e4..bcc66b9954b8 100644 --- a/src/libstd/sys/windows/os_str.rs +++ b/src/libstd/sys/windows/os_str.rs @@ -113,6 +113,11 @@ impl Buf { self.inner.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } + #[inline] pub fn into_box(self) -> Box { unsafe { mem::transmute(self.inner.into_box()) } diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs index 78b2bb5fe6e2..dda4e1bab3b4 100644 --- a/src/libstd/sys_common/wtf8.rs +++ b/src/libstd/sys_common/wtf8.rs @@ -253,6 +253,11 @@ impl Wtf8Buf { self.bytes.shrink_to_fit() } + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.bytes.shrink_to(min_capacity) + } + /// Returns the number of bytes that this string buffer can hold without reallocating. #[inline] pub fn capacity(&self) -> usize { From 554dd3e350721a7064932719ec925d1a1b5eb552 Mon Sep 17 00:00:00 2001 From: Alexis Hunt Date: Mon, 26 Mar 2018 21:18:50 -0400 Subject: [PATCH 660/830] Add missing '?' to format grammar. --- src/liballoc/fmt.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index a092bfb3b0a8..c69c2cd98c8c 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -324,7 +324,7 @@ //! sign := '+' | '-' //! width := count //! precision := count | '*' -//! type := identifier | '' +//! type := identifier | '?' | '' //! count := parameter | integer //! parameter := argument '$' //! ``` @@ -514,17 +514,17 @@ pub use core::fmt::rt; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{Formatter, Result, Write}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{Octal, Binary}; +pub use core::fmt::{Binary, Octal}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{Display, Debug}; +pub use core::fmt::{Debug, Display}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{LowerHex, UpperHex, Pointer}; +pub use core::fmt::{LowerHex, Pointer, UpperHex}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{LowerExp, UpperExp}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::Error; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::fmt::{ArgumentV1, Arguments, write}; +pub use core::fmt::{write, ArgumentV1, Arguments}; #[stable(feature = "rust1", since = "1.0.0")] pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; @@ -561,7 +561,8 @@ use string; pub fn format(args: Arguments) -> string::String { let capacity = args.estimated_capacity(); let mut output = string::String::with_capacity(capacity); - output.write_fmt(args) - .expect("a formatting trait implementation returned an error"); + output + .write_fmt(args) + .expect("a formatting trait implementation returned an error"); output } From 27164faaef69853e2c1adcc0ccd6e70780b6da0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Mon, 12 Feb 2018 01:17:32 -0500 Subject: [PATCH 661/830] Move some implementations of Clone and Copy to libcore Add implementations of `Clone` and `Copy` for some primitive types to libcore so that they show up in the documentation. The concerned types are the following: * All primitive signed and unsigned integer types (`usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `i8`, `i16`, `i32`, `i64`, `i128`); * All primitive floating point types (`f32`, `f64`) * `bool` * `char` * `!` * Raw pointers (`*const T` and `*mut T`) * Shared references (`&'a T`) These types already implemented `Clone` and `Copy`, but the implementation was provided by the compiler. The compiler no longer provides these implementations and instead tries to look them up as normal trait implementations. The goal of this change is to make the implementations appear in the generated documentation. For `Copy` specifically, the compiler would reject an attempt to write an `impl` for the primitive types listed above with error `E0206`; this error no longer occurs for these types, but it will still occur for the other types that used to raise that error. The trait implementations are guarded with `#[cfg(not(stage0))]` because they are invalid according to the stage0 compiler. When the stage0 compiler is updated to a revision that includes this change, the attribute will have to be removed, otherwise the stage0 build will fail because the types mentioned above no longer implement `Clone` or `Copy`. For type variants that are variadic, such as tuples and function pointers, and for array types, the `Clone` and `Copy` implementations are still provided by the compiler, because the language is not expressive enough yet to be able to write the appropriate implementations in Rust. The initial plan was to add `impl` blocks guarded by `#[cfg(dox)]` to make them apply only when generating documentation, without having to touch the compiler. However, rustdoc's usage of the compiler still rejected those `impl` blocks. This is a [breaking-change] for users of `#![no_core]`, because they will now have to supply their own implementations of `Clone` and `Copy` for the primitive types listed above. The easiest way to do that is to simply copy the implementations from `src/libcore/clone.rs` and `src/libcore/marker.rs`. Fixes #25893 --- src/libcore/clone.rs | 60 ++++++++++++++++++ src/libcore/marker.rs | 40 ++++++++++++ src/librustc/traits/select.rs | 12 ++-- src/librustc/ty/util.rs | 7 +++ src/librustc_typeck/diagnostics.rs | 8 +-- .../atomic-lock-free/atomic_lock_free.rs | 2 + src/test/run-make-fulldeps/simd-ffi/simd.rs | 3 + src/test/ui/coherence-impls-copy.rs | 8 ++- src/test/ui/coherence-impls-copy.stderr | 62 +++++++++++++------ src/test/ui/error-codes/E0206.rs | 4 +- src/test/ui/error-codes/E0206.stderr | 4 +- 11 files changed, 178 insertions(+), 32 deletions(-) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index d25f498b99ef..5c83dd79bd7f 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -135,3 +135,63 @@ pub struct AssertParamIsClone { _field: ::marker::PhantomData reason = "deriving hack, should not be public", issue = "0")] pub struct AssertParamIsCopy { _field: ::marker::PhantomData } + +/// Implementations of `Clone` for primitive types. +/// +/// Implementations that cannot be described in Rust +/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc. +#[cfg(not(stage0))] +mod impls { + + use super::Clone; + + macro_rules! impl_clone { + ($($t:ty)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl Clone for $t { + fn clone(&self) -> Self { + *self + } + } + )* + } + } + + impl_clone! { + usize u8 u16 u32 u64 u128 + isize i8 i16 i32 i64 i128 + f32 f64 + bool char + } + + #[stable(feature = "never_type", since = "1.26.0")] + impl Clone for ! { + fn clone(&self) -> Self { + *self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Clone for *const T { + fn clone(&self) -> Self { + *self + } + } + + #[stable(feature = "rust1", since = "1.0.0")] + impl Clone for *mut T { + fn clone(&self) -> Self { + *self + } + } + + // Shared references can be cloned, but mutable references *cannot*! + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized> Clone for &'a T { + fn clone(&self) -> Self { + *self + } + } + +} diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 7d0174a178ab..008cb15131d8 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -593,3 +593,43 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {} /// This trait is automatically implemented for almost every type. #[unstable(feature = "pin", issue = "49150")] pub unsafe auto trait Unpin {} + +/// Implementations of `Copy` for primitive types. +/// +/// Implementations that cannot be described in Rust +/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc. +#[cfg(not(stage0))] +mod copy_impls { + + use super::Copy; + + macro_rules! impl_copy { + ($($t:ty)*) => { + $( + #[stable(feature = "rust1", since = "1.0.0")] + impl Copy for $t {} + )* + } + } + + impl_copy! { + usize u8 u16 u32 u64 u128 + isize i8 i16 i32 i64 i128 + f32 f64 + bool char + } + + #[stable(feature = "never_type", since = "1.26.0")] + impl Copy for ! {} + + #[stable(feature = "rust1", since = "1.0.0")] + impl Copy for *const T {} + + #[stable(feature = "rust1", since = "1.0.0")] + impl Copy for *mut T {} + + // Shared references can be copied, but mutable references *cannot*! + #[stable(feature = "rust1", since = "1.0.0")] + impl<'a, T: ?Sized> Copy for &'a T {} + +} diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 11daa96134c5..8a585d6ac146 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2061,13 +2061,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { match self_ty.sty { ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) | - ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | - ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar | - ty::TyRawPtr(..) | ty::TyError | ty::TyNever | - ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => { + ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyError => { Where(ty::Binder(Vec::new())) } + ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | + ty::TyChar | ty::TyRawPtr(..) | ty::TyNever | + ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => { + // Implementations provided in libcore + None + } + ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) | ty::TyGenerator(..) | ty::TyGeneratorWitness(..) | ty::TyForeign(..) | ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => { diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index afe977d10baa..22f851a908b2 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -197,7 +197,14 @@ impl<'tcx> ty::ParamEnv<'tcx> { // FIXME: (@jroesch) float this code up tcx.infer_ctxt().enter(|infcx| { let (adt, substs) = match self_type.sty { + // These types used to have a builtin impl. + // Now libcore provides that impl. + ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) | + ty::TyChar | ty::TyRawPtr(..) | ty::TyNever | + ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => return Ok(()), + ty::TyAdt(adt, substs) => (adt, substs), + _ => return Err(CopyImplementationError::NotAnAdt), }; diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 1f882676f61a..691e0ffb6a5d 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1918,16 +1918,16 @@ differs from the behavior for `&T`, which is always `Copy`). E0206: r##" You can only implement `Copy` for a struct or enum. Both of the following -examples will fail, because neither `i32` (primitive type) nor `&'static Bar` -(reference to `Bar`) is a struct or enum: +examples will fail, because neither `[u8; 256]` nor `&'static mut Bar` +(mutable reference to `Bar`) is a struct or enum: ```compile_fail,E0206 -type Foo = i32; +type Foo = [u8; 256]; impl Copy for Foo { } // error #[derive(Copy, Clone)] struct Bar; -impl Copy for &'static Bar { } // error +impl Copy for &'static mut Bar { } // error ``` "##, diff --git a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs index b41e8e9226b3..54f888b3796a 100644 --- a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs +++ b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs @@ -23,6 +23,8 @@ trait Copy {} #[lang = "freeze"] trait Freeze {} +impl Copy for *mut T {} + #[cfg(target_has_atomic = "8")] pub unsafe fn atomic_u8(x: *mut u8) { atomic_xadd(x, 1); diff --git a/src/test/run-make-fulldeps/simd-ffi/simd.rs b/src/test/run-make-fulldeps/simd-ffi/simd.rs index 94b91c711cce..21411a35e3c3 100644 --- a/src/test/run-make-fulldeps/simd-ffi/simd.rs +++ b/src/test/run-make-fulldeps/simd-ffi/simd.rs @@ -75,6 +75,9 @@ pub trait Sized { } #[lang = "copy"] pub trait Copy { } +impl Copy for f32 {} +impl Copy for i32 {} + pub mod marker { pub use Copy; } diff --git a/src/test/ui/coherence-impls-copy.rs b/src/test/ui/coherence-impls-copy.rs index 51f43d27c34d..f48790d1f403 100644 --- a/src/test/ui/coherence-impls-copy.rs +++ b/src/test/ui/coherence-impls-copy.rs @@ -12,6 +12,10 @@ use std::marker::Copy; +impl Copy for i32 {} +//~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `i32`: +//~| ERROR only traits defined in the current crate can be implemented for arbitrary types + enum TestE { A } @@ -35,14 +39,14 @@ impl Copy for (MyType, MyType) {} //~| ERROR only traits defined in the current crate can be implemented for arbitrary types impl Copy for &'static NotSync {} -//~^ ERROR the trait `Copy` may not be implemented for this type +//~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `&NotSync`: impl Copy for [MyType] {} //~^ ERROR the trait `Copy` may not be implemented for this type //~| ERROR only traits defined in the current crate can be implemented for arbitrary types impl Copy for &'static [NotSync] {} -//~^ ERROR the trait `Copy` may not be implemented for this type +//~^ ERROR conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`: //~| ERROR only traits defined in the current crate can be implemented for arbitrary types fn main() { diff --git a/src/test/ui/coherence-impls-copy.stderr b/src/test/ui/coherence-impls-copy.stderr index 5f9b0c62df2b..24e7e85b1a96 100644 --- a/src/test/ui/coherence-impls-copy.stderr +++ b/src/test/ui/coherence-impls-copy.stderr @@ -1,35 +1,61 @@ +error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `i32`: + --> $DIR/coherence-impls-copy.rs:15:1 + | +LL | impl Copy for i32 {} + | ^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl std::marker::Copy for i32; + +error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`: + --> $DIR/coherence-impls-copy.rs:41:1 + | +LL | impl Copy for &'static NotSync {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl<'a, T> std::marker::Copy for &'a T + where T: ?Sized; + +error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]`: + --> $DIR/coherence-impls-copy.rs:48:1 + | +LL | impl Copy for &'static [NotSync] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl<'a, T> std::marker::Copy for &'a T + where T: ?Sized; + error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:29:15 + --> $DIR/coherence-impls-copy.rs:33:15 | LL | impl Copy for &'static mut MyType {} | ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:33:15 + --> $DIR/coherence-impls-copy.rs:37:15 | LL | impl Copy for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^ type is not a structure or enumeration error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:37:15 - | -LL | impl Copy for &'static NotSync {} - | ^^^^^^^^^^^^^^^^ type is not a structure or enumeration - -error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:40:15 + --> $DIR/coherence-impls-copy.rs:44:15 | LL | impl Copy for [MyType] {} | ^^^^^^^^ type is not a structure or enumeration -error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:44:15 +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/coherence-impls-copy.rs:15:1 | -LL | impl Copy for &'static [NotSync] {} - | ^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration +LL | impl Copy for i32 {} + | ^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate + | + = note: the impl does not reference any types defined in this crate + = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impls-copy.rs:33:1 + --> $DIR/coherence-impls-copy.rs:37:1 | LL | impl Copy for (MyType, MyType) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate @@ -38,7 +64,7 @@ LL | impl Copy for (MyType, MyType) {} = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impls-copy.rs:40:1 + --> $DIR/coherence-impls-copy.rs:44:1 | LL | impl Copy for [MyType] {} | ^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate @@ -47,7 +73,7 @@ LL | impl Copy for [MyType] {} = note: define and implement a trait or new type instead error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-impls-copy.rs:44:1 + --> $DIR/coherence-impls-copy.rs:48:1 | LL | impl Copy for &'static [NotSync] {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate @@ -55,7 +81,7 @@ LL | impl Copy for &'static [NotSync] {} = note: the impl does not reference any types defined in this crate = note: define and implement a trait or new type instead -error: aborting due to 8 previous errors +error: aborting due to 10 previous errors -Some errors occurred: E0117, E0206. +Some errors occurred: E0117, E0119, E0206. For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/error-codes/E0206.rs b/src/test/ui/error-codes/E0206.rs index da0370b301b5..9b3d1b351ddd 100644 --- a/src/test/ui/error-codes/E0206.rs +++ b/src/test/ui/error-codes/E0206.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -type Foo = i32; +type Foo = [u8; 256]; impl Copy for Foo { } //~^ ERROR the trait `Copy` may not be implemented for this type @@ -17,7 +17,7 @@ impl Copy for Foo { } #[derive(Copy, Clone)] struct Bar; -impl Copy for &'static Bar { } +impl Copy for &'static mut Bar { } //~^ ERROR the trait `Copy` may not be implemented for this type fn main() { diff --git a/src/test/ui/error-codes/E0206.stderr b/src/test/ui/error-codes/E0206.stderr index bbc0da2248f6..f2c23b0767af 100644 --- a/src/test/ui/error-codes/E0206.stderr +++ b/src/test/ui/error-codes/E0206.stderr @@ -7,8 +7,8 @@ LL | impl Copy for Foo { } error[E0206]: the trait `Copy` may not be implemented for this type --> $DIR/E0206.rs:20:15 | -LL | impl Copy for &'static Bar { } - | ^^^^^^^^^^^^ type is not a structure or enumeration +LL | impl Copy for &'static mut Bar { } + | ^^^^^^^^^^^^^^^^ type is not a structure or enumeration error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/E0206.rs:13:1 From 48825bcb23e752c0072a66450ae38d9865ee718e Mon Sep 17 00:00:00 2001 From: matthew Date: Mon, 26 Mar 2018 19:41:19 -0700 Subject: [PATCH 662/830] Remove an unnecessary/incorrect match in the expression check function --- src/librustc/hir/check_attr.rs | 14 ++------------ src/test/compile-fail/issue-43988.rs | 12 +++++++++--- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 6e1b7dc86a29..ecf8960c237d 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { self.emit_repr_error( attr.span, stmt.span, - &format!("attribute should not be applied to statements"), + &format!("attribute should not be applied a statement"), &format!("not a struct, enum or union"), ); } @@ -259,16 +259,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { } fn check_expr_attributes(&self, expr: &hir::Expr) { - use hir::Expr_::*; - match expr.node { - // Assignments, Calls and Structs were handled by Items and Statements - ExprCall(..) | - ExprAssign(..) | - ExprMethodCall(..) | - ExprStruct(..) => return, - _ => (), - } - for attr in expr.attrs.iter() { if attr.check_name("inline") { self.check_inline(attr, &expr.span, Target::Expression); @@ -278,7 +268,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { attr.span, expr.span, &format!("attribute should not be applied to an expression"), - &format!("not a struct, enum or union"), + &format!("not defining a struct, enum or union"), ); } } diff --git a/src/test/compile-fail/issue-43988.rs b/src/test/compile-fail/issue-43988.rs index 78237e31ba06..c03cd67fef99 100644 --- a/src/test/compile-fail/issue-43988.rs +++ b/src/test/compile-fail/issue-43988.rs @@ -21,8 +21,7 @@ fn main() { #[repr(nothing)] let _x = 0; - //~^^ ERROR attribute should not be applied to statements - + //~^^ ERROR attribute should not be applied a statement #[repr(something_not_real)] loop { @@ -32,5 +31,12 @@ fn main() { #[repr] let _y = "123"; - //~^^ ERROR attribute should not be applied to statements + //~^^ ERROR attribute should not be applied a statement + + + fn foo() {} + + #[inline(ABC)] + foo(); + //~^^ ERROR attribute should be applied to function } From f48c043154aeed1af44e6be66b17122fafacda51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Mon, 12 Feb 2018 02:31:26 -0500 Subject: [PATCH 663/830] Document builtin implementations of Clone and Copy There are types that implement `Clone` and `Copy` but are not mentioned in the documentation, because the implementations are provided by the compiler. They are types of variants that cannot be fully covered by trait implementations in Rust code, because the language is not expressive enough. --- src/libcore/clone.rs | 22 +++++++++++++++++----- src/libcore/marker.rs | 21 ++++++++++++++++----- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index 5c83dd79bd7f..b6a5948e6456 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -63,11 +63,6 @@ /// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d /// implementation of [`clone`] calls [`clone`] on each field. /// -/// ## Closures -/// -/// Closure types automatically implement `Clone` if they capture no value from the environment -/// or if all such captured values implement `Clone` themselves. -/// /// ## How can I implement `Clone`? /// /// Types that are [`Copy`] should have a trivial implementation of `Clone`. More formally: @@ -92,6 +87,23 @@ /// fn clone(&self) -> Stats { *self } /// } /// ``` +/// +/// ## Additional implementors +/// +/// In addition to the [implementors listed below][impls], +/// the following types also implement `Clone`: +/// +/// * Function item types (i.e. the distinct types defined for each function) +/// * Function pointer types (e.g. `fn() -> i32`) +/// * Array types, for all sizes, if the item type also implements `Clone` (e.g. `[i32; 123456]`) +/// * Tuple types, if each component also implements `Clone` (e.g. `()`, `(i32, bool)`) +/// * Closure types, if they capture no value from the environment +/// or if all such captured values implement `Clone` themselves. +/// Note that variables captured by shared reference always implement `Clone` +/// (even if the referent doesn't), +/// while variables captured by mutable reference never implement `Clone`. +/// +/// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "clone"] pub trait Clone : Sized { diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 008cb15131d8..885aabe08069 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -166,11 +166,6 @@ pub trait Unsize { /// are allowed to access `x` after the assignment. Under the hood, both a copy and a move /// can result in bits being copied in memory, although this is sometimes optimized away. /// -/// ## Closures -/// -/// Closure types automatically implement `Copy` if they capture no value from the environment -/// or if all such captured values implement `Copy` themselves. -/// /// ## How can I implement `Copy`? /// /// There are two ways to implement `Copy` on your type. The simplest is to use `derive`: @@ -265,6 +260,21 @@ pub trait Unsize { /// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to /// avoid a breaking API change. /// +/// ## Additional implementors +/// +/// In addition to the [implementors listed below][impls], +/// the following types also implement `Copy`: +/// +/// * Function item types (i.e. the distinct types defined for each function) +/// * Function pointer types (e.g. `fn() -> i32`) +/// * Array types, for all sizes, if the item type also implements `Copy` (e.g. `[i32; 123456]`) +/// * Tuple types, if each component also implements `Copy` (e.g. `()`, `(i32, bool)`) +/// * Closure types, if they capture no value from the environment +/// or if all such captured values implement `Copy` themselves. +/// Note that variables captured by shared reference always implement `Copy` +/// (even if the referent doesn't), +/// while variables captured by mutable reference never implement `Copy`. +/// /// [`Vec`]: ../../std/vec/struct.Vec.html /// [`String`]: ../../std/string/struct.String.html /// [`Drop`]: ../../std/ops/trait.Drop.html @@ -272,6 +282,7 @@ pub trait Unsize { /// [`Clone`]: ../clone/trait.Clone.html /// [`String`]: ../../std/string/struct.String.html /// [`i32`]: ../../std/primitive.i32.html +/// [impls]: #implementors #[stable(feature = "rust1", since = "1.0.0")] #[lang = "copy"] pub trait Copy : Clone { From afa7f5bc8ac79503bb99a20a1dd19365318f504f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Sat, 10 Mar 2018 17:43:44 -0500 Subject: [PATCH 664/830] Add #[inline] to Clone impls for primitive types --- src/libcore/clone.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs index b6a5948e6456..f8e8c69621ae 100644 --- a/src/libcore/clone.rs +++ b/src/libcore/clone.rs @@ -162,6 +162,7 @@ mod impls { $( #[stable(feature = "rust1", since = "1.0.0")] impl Clone for $t { + #[inline] fn clone(&self) -> Self { *self } @@ -179,6 +180,7 @@ mod impls { #[stable(feature = "never_type", since = "1.26.0")] impl Clone for ! { + #[inline] fn clone(&self) -> Self { *self } @@ -186,6 +188,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for *const T { + #[inline] fn clone(&self) -> Self { *self } @@ -193,6 +196,7 @@ mod impls { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for *mut T { + #[inline] fn clone(&self) -> Self { *self } @@ -201,6 +205,7 @@ mod impls { // Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: ?Sized> Clone for &'a T { + #[inline] fn clone(&self) -> Self { *self } From d032a4b079e9605bd95919db59c817422e0fdba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Sat, 10 Mar 2018 19:04:40 -0500 Subject: [PATCH 665/830] Strengthen the repeat-trusted-len test Simply checking for the presence of `llvm.memset` is too brittle because this instrinsic can be used for seemingly trivial operations, such as zero-initializing a `RawVec`. --- src/test/codegen/repeat-trusted-len.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs index 43872f15d51e..8b3294281e96 100644 --- a/src/test/codegen/repeat-trusted-len.rs +++ b/src/test/codegen/repeat-trusted-len.rs @@ -15,9 +15,14 @@ use std::iter; +// CHECK: @helper([[USIZE:i[0-9]+]] %arg0) +#[no_mangle] +pub fn helper(_: usize) { +} + // CHECK-LABEL: @repeat_take_collect #[no_mangle] pub fn repeat_take_collect() -> Vec { -// CHECK: call void @llvm.memset.p0i8 +// CHECK: call void @llvm.memset.p0i8.[[USIZE]](i8* {{(nonnull )?}}%{{[0-9]+}}, i8 42, [[USIZE]] 100000, i32 1, i1 false) iter::repeat(42).take(100000).collect() } From 87c08f9926b7078489a93cedd1c9f10df1bdf2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francis=20Gagn=C3=A9?= Date: Mon, 26 Mar 2018 21:59:35 -0400 Subject: [PATCH 666/830] Update liblibc submodule to the 0.2.40 release --- src/liblibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liblibc b/src/liblibc index ed04152aacf5..a7e78a78e17c 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit ed04152aacf5b4798f78ff13396f3c04c0a77144 +Subproject commit a7e78a78e17c8776d7780008ccb3ce541ec64ae9 From 6b3202a2bfd33f435d3266f2583c0f5d3356251d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 27 Mar 2018 08:31:05 +0200 Subject: [PATCH 667/830] Trim discriminants to their final type size --- src/librustc_mir/hair/pattern/mod.rs | 35 +++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index eb87d5b044b4..7359b1ed1021 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -851,13 +851,36 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ty::TyAdt(adt_def, substs) if adt_def.is_enum() => { match cv.val { ConstVal::Value(val) => { - let discr = const_discr( + let discr_val = const_discr( self.tcx, self.param_env, instance, val, cv.ty - ).unwrap(); - let variant_index = adt_def - .discriminants(self.tcx) - .position(|var| var.val == discr) - .unwrap(); + ).expect("const_discr failed"); + let layout = self + .tcx + .layout_of(self.param_env.and(cv.ty)) + .expect("layout of enum not available"); + let variant_index = match layout.variants { + ty::layout::Variants::Single { index } => index, + ty::layout::Variants::Tagged { ref discr, .. } => { + // raw discriminants for enums are isize or bigger during + // their computation, but later shrunk to the smallest possible + // representation + let size = discr.value.size(self.tcx).bits(); + let amt = 128 - size; + adt_def + .discriminants(self.tcx) + .position(|var| ((var.val << amt) >> amt) == discr_val) + .unwrap_or_else(|| { + bug!("discriminant {} not found in {:#?}", + discr_val, + adt_def + .discriminants(self.tcx) + .collect::>(), + ); + }) + } + ty::layout::Variants::NicheFilling { dataful_variant, .. } => + dataful_variant, + }; let subpatterns = adt_subpatterns( adt_def.variants[variant_index].fields.len(), Some(variant_index), From 837d6c70233715a0ae8e15c703d40e3046a2f36a Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 26 Mar 2018 22:48:12 +0200 Subject: [PATCH 668/830] Remove TryFrom impls that might become conditionally-infallible with a portability lint https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243 --- src/libcore/iter/range.rs | 74 +++++++++++++++++++- src/libcore/num/mod.rs | 70 +++---------------- src/libcore/tests/num/mod.rs | 127 ----------------------------------- src/libstd/io/cursor.rs | 20 +++++- 4 files changed, 100 insertions(+), 191 deletions(-) diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 8d1080bb876e..72b48b565719 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -91,7 +91,7 @@ macro_rules! step_impl_unsigned { #[inline] #[allow(unreachable_patterns)] fn add_usize(&self, n: usize) -> Option { - match <$t>::try_from(n) { + match <$t>::private_try_from(n) { Ok(n_as_t) => self.checked_add(n_as_t), Err(_) => None, } @@ -123,7 +123,7 @@ macro_rules! step_impl_signed { #[inline] #[allow(unreachable_patterns)] fn add_usize(&self, n: usize) -> Option { - match <$unsigned>::try_from(n) { + match <$unsigned>::private_try_from(n) { Ok(n_as_unsigned) => { // Wrapping in unsigned space handles cases like // `-120_i8.add_usize(200) == Some(80_i8)`, @@ -461,3 +461,73 @@ impl DoubleEndedIterator for ops::RangeInclusive { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ops::RangeInclusive {} + +/// Compensate removal of some impls per +/// https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243 +trait PrivateTryFromUsize: Sized { + fn private_try_from(n: usize) -> Result; +} + +impl PrivateTryFromUsize for T where T: TryFrom { + #[inline] + fn private_try_from(n: usize) -> Result { + T::try_from(n).map_err(|_| ()) + } +} + +// no possible bounds violation +macro_rules! try_from_unbounded { + ($($target:ty),*) => {$( + impl PrivateTryFromUsize for $target { + #[inline] + fn private_try_from(value: usize) -> Result { + Ok(value as $target) + } + } + )*} +} + +// unsigned to signed (only positive bound) +macro_rules! try_from_upper_bounded { + ($($target:ty),*) => {$( + impl PrivateTryFromUsize for $target { + #[inline] + fn private_try_from(u: usize) -> Result<$target, ()> { + if u > (<$target>::max_value() as usize) { + Err(()) + } else { + Ok(u as $target) + } + } + } + )*} +} + + +#[cfg(target_pointer_width = "16")] +mod ptr_try_from_impls { + use super::PrivateTryFromUsize; + + try_from_unbounded!(u16, u32, u64, u128); + try_from_unbounded!(i32, i64, i128); +} + +#[cfg(target_pointer_width = "32")] +mod ptr_try_from_impls { + use super::PrivateTryFromUsize; + + try_from_upper_bounded!(u16); + try_from_unbounded!(u32, u64, u128); + try_from_upper_bounded!(i32); + try_from_unbounded!(i64, i128); +} + +#[cfg(target_pointer_width = "64")] +mod ptr_try_from_impls { + use super::PrivateTryFromUsize; + + try_from_upper_bounded!(u16, u32); + try_from_unbounded!(u64, u128); + try_from_upper_bounded!(i32, i64); + try_from_unbounded!(i128); +} diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 8f7e8d0c8ab7..ee041e1e4f1d 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3676,21 +3676,6 @@ impl From for TryFromIntError { } } -// no possible bounds violation -macro_rules! try_from_unbounded { - ($source:ty, $($target:ty),*) => {$( - #[stable(feature = "try_from", since = "1.26.0")] - impl TryFrom<$source> for $target { - type Error = TryFromIntError; - - #[inline] - fn try_from(value: $source) -> Result { - Ok(value as $target) - } - } - )*} -} - // only negative bounds macro_rules! try_from_lower_bounded { ($source:ty, $($target:ty),*) => {$( @@ -3789,27 +3774,20 @@ try_from_both_bounded!(i128, u64, u32, u16, u8); try_from_upper_bounded!(usize, isize); try_from_lower_bounded!(isize, usize); +try_from_upper_bounded!(usize, u8); +try_from_upper_bounded!(usize, i8, i16); +try_from_both_bounded!(isize, u8); +try_from_both_bounded!(isize, i8); + #[cfg(target_pointer_width = "16")] mod ptr_try_from_impls { use super::TryFromIntError; use convert::TryFrom; - try_from_upper_bounded!(usize, u8); - try_from_unbounded!(usize, u16, u32, u64, u128); - try_from_upper_bounded!(usize, i8, i16); - try_from_unbounded!(usize, i32, i64, i128); - - try_from_both_bounded!(isize, u8); + // Fallible across platfoms, only implementation differs try_from_lower_bounded!(isize, u16, u32, u64, u128); - try_from_both_bounded!(isize, i8); - try_from_unbounded!(isize, i16, i32, i64, i128); - - rev!(try_from_upper_bounded, usize, u32, u64, u128); rev!(try_from_lower_bounded, usize, i8, i16); rev!(try_from_both_bounded, usize, i32, i64, i128); - - rev!(try_from_upper_bounded, isize, u16, u32, u64, u128); - rev!(try_from_both_bounded, isize, i32, i64, i128); } #[cfg(target_pointer_width = "32")] @@ -3817,25 +3795,11 @@ mod ptr_try_from_impls { use super::TryFromIntError; use convert::TryFrom; - try_from_upper_bounded!(usize, u8, u16); - try_from_unbounded!(usize, u32, u64, u128); - try_from_upper_bounded!(usize, i8, i16, i32); - try_from_unbounded!(usize, i64, i128); - - try_from_both_bounded!(isize, u8, u16); + // Fallible across platfoms, only implementation differs + try_from_both_bounded!(isize, u16); try_from_lower_bounded!(isize, u32, u64, u128); - try_from_both_bounded!(isize, i8, i16); - try_from_unbounded!(isize, i32, i64, i128); - - rev!(try_from_unbounded, usize, u32); - rev!(try_from_upper_bounded, usize, u64, u128); rev!(try_from_lower_bounded, usize, i8, i16, i32); rev!(try_from_both_bounded, usize, i64, i128); - - rev!(try_from_unbounded, isize, u16); - rev!(try_from_upper_bounded, isize, u32, u64, u128); - rev!(try_from_unbounded, isize, i32); - rev!(try_from_both_bounded, isize, i64, i128); } #[cfg(target_pointer_width = "64")] @@ -3843,25 +3807,11 @@ mod ptr_try_from_impls { use super::TryFromIntError; use convert::TryFrom; - try_from_upper_bounded!(usize, u8, u16, u32); - try_from_unbounded!(usize, u64, u128); - try_from_upper_bounded!(usize, i8, i16, i32, i64); - try_from_unbounded!(usize, i128); - - try_from_both_bounded!(isize, u8, u16, u32); + // Fallible across platfoms, only implementation differs + try_from_both_bounded!(isize, u16, u32); try_from_lower_bounded!(isize, u64, u128); - try_from_both_bounded!(isize, i8, i16, i32); - try_from_unbounded!(isize, i64, i128); - - rev!(try_from_unbounded, usize, u32, u64); - rev!(try_from_upper_bounded, usize, u128); rev!(try_from_lower_bounded, usize, i8, i16, i32, i64); rev!(try_from_both_bounded, usize, i128); - - rev!(try_from_unbounded, isize, u16, u32); - rev!(try_from_upper_bounded, isize, u64, u128); - rev!(try_from_unbounded, isize, i32, i64); - rev!(try_from_both_bounded, isize, i128); } #[doc(hidden)] diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index 587dcbe6d678..c7edb55b378c 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -37,15 +37,6 @@ mod flt2dec; mod dec2flt; mod bignum; - -/// Adds the attribute to all items in the block. -macro_rules! cfg_block { - ($(#[$attr:meta]{$($it:item)*})*) => {$($( - #[$attr] - $it - )*)*} -} - /// Groups items that assume the pointer width is either 16/32/64, and has to be altered if /// support for larger/smaller pointer widths are added in the future. macro_rules! assume_usize_width { @@ -318,42 +309,6 @@ assume_usize_width! { test_impl_try_from_always_ok! { test_try_u16usize, u16, usize } test_impl_try_from_always_ok! { test_try_i16isize, i16, isize } - - test_impl_try_from_always_ok! { test_try_usizeu64, usize, u64 } - test_impl_try_from_always_ok! { test_try_usizeu128, usize, u128 } - test_impl_try_from_always_ok! { test_try_usizei128, usize, i128 } - - test_impl_try_from_always_ok! { test_try_isizei64, isize, i64 } - test_impl_try_from_always_ok! { test_try_isizei128, isize, i128 } - - cfg_block!( - #[cfg(target_pointer_width = "16")] { - test_impl_try_from_always_ok! { test_try_usizeu16, usize, u16 } - test_impl_try_from_always_ok! { test_try_isizei16, isize, i16 } - test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 } - test_impl_try_from_always_ok! { test_try_usizei32, usize, i32 } - test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 } - test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 } - } - - #[cfg(target_pointer_width = "32")] { - test_impl_try_from_always_ok! { test_try_u16isize, u16, isize } - test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 } - test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 } - test_impl_try_from_always_ok! { test_try_u32usize, u32, usize } - test_impl_try_from_always_ok! { test_try_i32isize, i32, isize } - test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 } - } - - #[cfg(target_pointer_width = "64")] { - test_impl_try_from_always_ok! { test_try_u16isize, u16, isize } - test_impl_try_from_always_ok! { test_try_u32usize, u32, usize } - test_impl_try_from_always_ok! { test_try_u32isize, u32, isize } - test_impl_try_from_always_ok! { test_try_i32isize, i32, isize } - test_impl_try_from_always_ok! { test_try_u64usize, u64, usize } - test_impl_try_from_always_ok! { test_try_i64isize, i64, isize } - } - ); } /// Conversions where max of $source can be represented as $target, @@ -402,24 +357,6 @@ assume_usize_width! { test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu64, isize, u64 } test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu128, isize, u128 } test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeusize, isize, usize } - - cfg_block!( - #[cfg(target_pointer_width = "16")] { - test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu16, isize, u16 } - test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 } - } - - #[cfg(target_pointer_width = "32")] { - test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 } - - test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize } - } - - #[cfg(target_pointer_width = "64")] { - test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize } - test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64usize, i64, usize } - } - ); } /// Conversions where max of $source can not be represented as $target, @@ -461,29 +398,9 @@ test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i64, u128, i64 } test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i128, u128, i128 } assume_usize_width! { - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64isize, u64, isize } - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128isize, u128, isize } - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei8, usize, i8 } test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei16, usize, i16 } test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizeisize, usize, isize } - - cfg_block!( - #[cfg(target_pointer_width = "16")] { - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16isize, u16, isize } - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize } - } - - #[cfg(target_pointer_width = "32")] { - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize } - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 } - } - - #[cfg(target_pointer_width = "64")] { - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 } - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei64, usize, i64 } - } - ); } /// Conversions where min/max of $source can not be represented as $target. @@ -543,34 +460,6 @@ test_impl_try_from_same_sign_err! { test_try_i128i64, i128, i64 } assume_usize_width! { test_impl_try_from_same_sign_err! { test_try_usizeu8, usize, u8 } - test_impl_try_from_same_sign_err! { test_try_u128usize, u128, usize } - test_impl_try_from_same_sign_err! { test_try_i128isize, i128, isize } - - cfg_block!( - #[cfg(target_pointer_width = "16")] { - test_impl_try_from_same_sign_err! { test_try_u32usize, u32, usize } - test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize } - - test_impl_try_from_same_sign_err! { test_try_i32isize, i32, isize } - test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize } - } - - #[cfg(target_pointer_width = "32")] { - test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize } - test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 } - - test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize } - test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 } - } - - #[cfg(target_pointer_width = "64")] { - test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 } - test_impl_try_from_same_sign_err! { test_try_usizeu32, usize, u32 } - - test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 } - test_impl_try_from_same_sign_err! { test_try_isizei32, isize, i32 } - } - ); } /// Conversions where neither the min nor the max of $source can be represented by @@ -615,22 +504,6 @@ test_impl_try_from_signed_to_unsigned_err! { test_try_i128u64, i128, u64 } assume_usize_width! { test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 } test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize } - - cfg_block! { - #[cfg(target_pointer_width = "16")] { - test_impl_try_from_signed_to_unsigned_err! { test_try_i32usize, i32, usize } - test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize } - } - #[cfg(target_pointer_width = "32")] { - test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize } - - test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 } - } - #[cfg(target_pointer_width = "64")] { - test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 } - test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu32, isize, u32 } - } - } } macro_rules! test_float { diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs index 76bcb5fedc94..2673f3ccfa3a 100644 --- a/src/libstd/io/cursor.rs +++ b/src/libstd/io/cursor.rs @@ -10,7 +10,6 @@ use io::prelude::*; -use core::convert::TryInto; use cmp; use io::{self, Initializer, SeekFrom, Error, ErrorKind}; @@ -260,9 +259,26 @@ fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result Result { + if n <= (::max_value() as u64) { + Ok(n as usize) + } else { + Err(()) + } +} + +#[cfg(any(target_pointer_width = "64"))] +fn try_into(n: u64) -> Result { + Ok(n as usize) +} + // Resizing write implementation fn vec_write(pos_mut: &mut u64, vec: &mut Vec, buf: &[u8]) -> io::Result { - let pos: usize = (*pos_mut).try_into().map_err(|_| { + let pos: usize = try_into(*pos_mut).map_err(|_| { Error::new(ErrorKind::InvalidInput, "cursor position exceeds maximum possible vector length") })?; From 96ef2f8ab9bbea24b71c7441ee534407949848db Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 27 Mar 2018 10:33:31 +0200 Subject: [PATCH 669/830] Fix search appearance --- src/librustdoc/html/static/main.js | 6 +++++- src/librustdoc/html/static/rustdoc.css | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 6c6c067f9518..fc78c5edc4cc 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1171,6 +1171,10 @@ return h1.innerHTML; } + function pathSplitter(path) { + return '' + path.replace(/::/g, '::'); + } + function addTab(array, query, display) { var extraStyle = ''; if (display === false) { @@ -1225,7 +1229,7 @@ output += '

' + '' + - displayPath + '' + + pathSplitter(displayPath) + '' + name + '' + '' + '' + escape(item.desc) + diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 9b899dd4517e..f10fa54050b2 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -296,6 +296,11 @@ nav.sub { overflow: auto; } +#results > table { + width: 100%; + table-layout: fixed; +} + .content pre.line-numbers { float: left; border: none; @@ -577,8 +582,16 @@ a { display: block; } -.content .search-results td:first-child { padding-right: 0; } -.content .search-results td:first-child a { padding-right: 10px; } +.content .search-results td:first-child { + padding-right: 0; + width: 75%; +} +.content .search-results td:first-child a { + padding-right: 10px; +} +.content .search-results td:first-child a span { + float: left; +} tr.result span.primitive::after { content: ' (primitive type)'; From 6313997e3eede7107614adcb622b41ce8f5bcd95 Mon Sep 17 00:00:00 2001 From: Wangshan Lu Date: Tue, 27 Mar 2018 16:47:50 +0800 Subject: [PATCH 670/830] Add back 1.24.1 release notes --- RELEASES.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 51c36c99858b..100de005990c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -98,6 +98,20 @@ Compatibility Notes [`ptr::NonNull`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html +Version 1.24.1 (2018-03-01) +========================== + + - [Do not abort when unwinding through FFI][48251] + - [Emit UTF-16 files for linker arguments on Windows][48318] + - [Make the error index generator work again][48308] + - [Cargo will warn on Windows 7 if an update is needed][cargo/5069]. + +[48251]: https://github.com/rust-lang/rust/issues/48251 +[48308]: https://github.com/rust-lang/rust/issues/48308 +[48318]: https://github.com/rust-lang/rust/issues/48318 +[cargo/5069]: https://github.com/rust-lang/cargo/pull/5069 + + Version 1.24.0 (2018-02-15) ========================== From 73b97c7e7c9cfac4dfa4804654b1db6ab687b589 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 27 Mar 2018 11:57:00 +0200 Subject: [PATCH 671/830] Hide type declarations by default --- src/librustdoc/html/render.rs | 287 +++++++++++++++-------------- src/librustdoc/html/static/main.js | 18 +- 2 files changed, 166 insertions(+), 139 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 678e1762a551..6a1ce2c7974f 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1675,11 +1675,19 @@ impl<'a> Item<'a> { } } +fn wrap_into_docblock(w: &mut fmt::Formatter, + f: F) -> fmt::Result +where F: Fn(&mut fmt::Formatter) -> fmt::Result { + write!(w, "
")?; + f(w)?; + write!(w, "
") +} + impl<'a> fmt::Display for Item<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { debug_assert!(!self.item.is_stripped()); // Write the breadcrumb trail header for the top - write!(fmt, "\n

")?; + write!(fmt, "

")?; match self.item.inner { clean::ModuleItem(ref m) => if m.is_crate { write!(fmt, "Crate ")?; @@ -1741,14 +1749,11 @@ impl<'a> fmt::Display for Item<'a> { } } - write!(fmt, "")?; // out-of-band - - write!(fmt, "

\n")?; + write!(fmt, "

")?; // out-of-band match self.item.inner { - clean::ModuleItem(ref m) => { - item_module(fmt, self.cx, self.item, &m.items) - } + clean::ModuleItem(ref m) => + item_module(fmt, self.cx, self.item, &m.items), clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => item_function(fmt, self.cx, self.item, f), clean::TraitItem(ref t) => item_trait(fmt, self.cx, self.item, t), @@ -2306,79 +2311,81 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } } - // Output the trait definition - write!(w, "
")?;
-    render_attributes(w, it)?;
-    write!(w, "{}{}{}trait {}{}{}",
-           VisSpace(&it.visibility),
-           UnsafetySpace(t.unsafety),
-           if t.is_auto { "auto " } else { "" },
-           it.name.as_ref().unwrap(),
-           t.generics,
-           bounds)?;
-
-    if !t.generics.where_predicates.is_empty() {
-        write!(w, "{}", WhereClause { gens: &t.generics, indent: 0, end_newline: true })?;
-    } else {
-        write!(w, " ")?;
-    }
-
     let types = t.items.iter().filter(|m| m.is_associated_type()).collect::>();
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>();
     let required = t.items.iter().filter(|m| m.is_ty_method()).collect::>();
     let provided = t.items.iter().filter(|m| m.is_method()).collect::>();
 
-    if t.items.is_empty() {
-        write!(w, "{{ }}")?;
-    } else {
-        // FIXME: we should be using a derived_id for the Anchors here
-        write!(w, "{{\n")?;
-        for t in &types {
-            write!(w, "    ")?;
-            render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
-            write!(w, ";\n")?;
-        }
-        if !types.is_empty() && !consts.is_empty() {
-            w.write_str("\n")?;
-        }
-        for t in &consts {
-            write!(w, "    ")?;
-            render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
-            write!(w, ";\n")?;
-        }
-        if !consts.is_empty() && !required.is_empty() {
-            w.write_str("\n")?;
-        }
-        for (pos, m) in required.iter().enumerate() {
-            write!(w, "    ")?;
-            render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
-            write!(w, ";\n")?;
+    // Output the trait definition
+    wrap_into_docblock(w, |w| {
+        write!(w, "
")?;
+        render_attributes(w, it)?;
+        write!(w, "{}{}{}trait {}{}{}",
+               VisSpace(&it.visibility),
+               UnsafetySpace(t.unsafety),
+               if t.is_auto { "auto " } else { "" },
+               it.name.as_ref().unwrap(),
+               t.generics,
+               bounds)?;
 
-            if pos < required.len() - 1 {
-               write!(w, "
")?; - } + if !t.generics.where_predicates.is_empty() { + write!(w, "{}", WhereClause { gens: &t.generics, indent: 0, end_newline: true })?; + } else { + write!(w, " ")?; } - if !required.is_empty() && !provided.is_empty() { - w.write_str("\n")?; - } - for (pos, m) in provided.iter().enumerate() { - write!(w, " ")?; - render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?; - match m.inner { - clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => { - write!(w, ",\n {{ ... }}\n")?; - }, - _ => { - write!(w, " {{ ... }}\n")?; - }, + + if t.items.is_empty() { + write!(w, "{{ }}")?; + } else { + // FIXME: we should be using a derived_id for the Anchors here + write!(w, "{{\n")?; + for t in &types { + write!(w, " ")?; + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?; + write!(w, ";\n")?; } - if pos < provided.len() - 1 { - write!(w, "
")?; + if !types.is_empty() && !consts.is_empty() { + w.write_str("\n")?; } + for t in &consts { + write!(w, " ")?; + render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?; + write!(w, ";\n")?; + } + if !consts.is_empty() && !required.is_empty() { + w.write_str("\n")?; + } + for (pos, m) in required.iter().enumerate() { + write!(w, " ")?; + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?; + write!(w, ";\n")?; + + if pos < required.len() - 1 { + write!(w, "
")?; + } + } + if !required.is_empty() && !provided.is_empty() { + w.write_str("\n")?; + } + for (pos, m) in provided.iter().enumerate() { + write!(w, " ")?; + render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?; + match m.inner { + clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => { + write!(w, ",\n {{ ... }}\n")?; + }, + _ => { + write!(w, " {{ ... }}\n")?; + }, + } + if pos < provided.len() - 1 { + write!(w, "
")?; + } + } + write!(w, "}}")?; } - write!(w, "}}")?; - } - write!(w, "
")?; + write!(w, "
") + })?; // Trait documentation document(w, cx, it)?; @@ -2717,16 +2724,18 @@ fn render_assoc_item(w: &mut fmt::Formatter, fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, s: &clean::Struct) -> fmt::Result { - write!(w, "
")?;
-    render_attributes(w, it)?;
-    render_struct(w,
-                  it,
-                  Some(&s.generics),
-                  s.struct_type,
-                  &s.fields,
-                  "",
-                  true)?;
-    write!(w, "
")?; + wrap_into_docblock(w, |w| { + write!(w, "
")?;
+        render_attributes(w, it)?;
+        render_struct(w,
+                      it,
+                      Some(&s.generics),
+                      s.struct_type,
+                      &s.fields,
+                      "",
+                      true)?;
+        write!(w, "
") + })?; document(w, cx, it)?; let mut fields = s.fields.iter().filter_map(|f| { @@ -2769,15 +2778,17 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, s: &clean::Union) -> fmt::Result { - write!(w, "
")?;
-    render_attributes(w, it)?;
-    render_union(w,
-                 it,
-                 Some(&s.generics),
-                 &s.fields,
-                 "",
-                 true)?;
-    write!(w, "
")?; + wrap_into_docblock(w, |w| { + write!(w, "
")?;
+        render_attributes(w, it)?;
+        render_union(w,
+                     it,
+                     Some(&s.generics),
+                     &s.fields,
+                     "",
+                     true)?;
+        write!(w, "
") + })?; document(w, cx, it)?; let mut fields = s.fields.iter().filter_map(|f| { @@ -2807,56 +2818,58 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, e: &clean::Enum) -> fmt::Result { - write!(w, "
")?;
-    render_attributes(w, it)?;
-    write!(w, "{}enum {}{}{}",
-           VisSpace(&it.visibility),
-           it.name.as_ref().unwrap(),
-           e.generics,
-           WhereClause { gens: &e.generics, indent: 0, end_newline: true })?;
-    if e.variants.is_empty() && !e.variants_stripped {
-        write!(w, " {{}}")?;
-    } else {
-        write!(w, " {{\n")?;
-        for v in &e.variants {
-            write!(w, "    ")?;
-            let name = v.name.as_ref().unwrap();
-            match v.inner {
-                clean::VariantItem(ref var) => {
-                    match var.kind {
-                        clean::VariantKind::CLike => write!(w, "{}", name)?,
-                        clean::VariantKind::Tuple(ref tys) => {
-                            write!(w, "{}(", name)?;
-                            for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 {
-                                    write!(w, ", ")?
+    wrap_into_docblock(w, |w| {
+        write!(w, "
")?;
+        render_attributes(w, it)?;
+        write!(w, "{}enum {}{}{}",
+               VisSpace(&it.visibility),
+               it.name.as_ref().unwrap(),
+               e.generics,
+               WhereClause { gens: &e.generics, indent: 0, end_newline: true })?;
+        if e.variants.is_empty() && !e.variants_stripped {
+            write!(w, " {{}}")?;
+        } else {
+            write!(w, " {{\n")?;
+            for v in &e.variants {
+                write!(w, "    ")?;
+                let name = v.name.as_ref().unwrap();
+                match v.inner {
+                    clean::VariantItem(ref var) => {
+                        match var.kind {
+                            clean::VariantKind::CLike => write!(w, "{}", name)?,
+                            clean::VariantKind::Tuple(ref tys) => {
+                                write!(w, "{}(", name)?;
+                                for (i, ty) in tys.iter().enumerate() {
+                                    if i > 0 {
+                                        write!(w, ", ")?
+                                    }
+                                    write!(w, "{}", *ty)?;
                                 }
-                                write!(w, "{}", *ty)?;
+                                write!(w, ")")?;
+                            }
+                            clean::VariantKind::Struct(ref s) => {
+                                render_struct(w,
+                                              v,
+                                              None,
+                                              s.struct_type,
+                                              &s.fields,
+                                              "    ",
+                                              false)?;
                             }
-                            write!(w, ")")?;
-                        }
-                        clean::VariantKind::Struct(ref s) => {
-                            render_struct(w,
-                                          v,
-                                          None,
-                                          s.struct_type,
-                                          &s.fields,
-                                          "    ",
-                                          false)?;
                         }
                     }
+                    _ => unreachable!()
                 }
-                _ => unreachable!()
+                write!(w, ",\n")?;
             }
-            write!(w, ",\n")?;
-        }
 
-        if e.variants_stripped {
-            write!(w, "    // some variants omitted\n")?;
+            if e.variants_stripped {
+                write!(w, "    // some variants omitted\n")?;
+            }
+            write!(w, "}}")?;
         }
-        write!(w, "}}")?;
-    }
-    write!(w, "
")?; + write!(w, "
") + })?; document(w, cx, it)?; if !e.variants.is_empty() { @@ -4043,11 +4056,13 @@ impl<'a> fmt::Display for Source<'a> { fn item_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, t: &clean::Macro) -> fmt::Result { - w.write_str(&highlight::render_with_highlighting(&t.source, - Some("macro"), - None, - None, - None))?; + wrap_into_docblock(w, |w| { + w.write_str(&highlight::render_with_highlighting(&t.source, + Some("macro"), + None, + None, + None)) + })?; document(w, cx, it) } diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 6c6c067f9518..121e35dc7029 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1833,11 +1833,16 @@ onEach(e.getElementsByClassName('associatedconstant'), func); }); - function createToggle() { + function createToggle(otherMessage) { var span = document.createElement('span'); span.className = 'toggle-label'; span.style.display = 'none'; - span.innerHTML = ' Expand description'; + if (!otherMessage) { + span.innerHTML = ' Expand description'; + } else { + span.innerHTML = otherMessage; + span.style.fontSize = '20px'; + } var mainToggle = toggle.cloneNode(true); mainToggle.appendChild(span); @@ -1850,7 +1855,14 @@ onEach(document.getElementById('main').getElementsByClassName('docblock'), function(e) { if (e.parentNode.id === "main") { - e.parentNode.insertBefore(createToggle(), e); + var otherMessage; + if (hasClass(e, "type-decl")) { + otherMessage = ' Show type declaration'; + } + e.parentNode.insertBefore(createToggle(otherMessage), e); + if (otherMessage) { + collapseDocs(e.previousSibling.childNodes[0], "toggle"); + } } }); From 5b1a60062c8882dbf60853037e4e8908b6ce7ec7 Mon Sep 17 00:00:00 2001 From: Tim Neumann Date: Tue, 27 Mar 2018 15:32:06 +0200 Subject: [PATCH 672/830] Update compiler-rt with fix for 32bit iOS ARM --- src/libcompiler_builtins | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins index 263a703b1035..2a2f6d96c8dc 160000 --- a/src/libcompiler_builtins +++ b/src/libcompiler_builtins @@ -1 +1 @@ -Subproject commit 263a703b10351d8930e48045b4fd09768991b867 +Subproject commit 2a2f6d96c8dc578d2474742f14c9bab0b36b0408 From 7f548bc8c6009c9a777409f8b1895c7ffc25fcb3 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 27 Mar 2018 16:31:19 +0200 Subject: [PATCH 673/830] add --edition flag to rustdoc --- src/librustdoc/core.rs | 5 ++++- src/librustdoc/lib.rs | 28 ++++++++++++++++++++++------ src/librustdoc/test.rs | 8 +++++++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1e0fafc8d9df..02d65c194f99 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -25,6 +25,7 @@ use rustc_metadata::cstore::CStore; use syntax::ast::NodeId; use syntax::codemap; +use syntax::edition::Edition; use syntax::feature_gate::UnstableFeatures; use errors; use errors::emitter::ColorConfig; @@ -120,7 +121,8 @@ pub fn run_core(search_paths: SearchPaths, maybe_sysroot: Option, allow_warnings: bool, crate_name: Option, - force_unstable_if_unmarked: bool) -> (clean::Crate, RenderInfo) + force_unstable_if_unmarked: bool, + edition: Edition) -> (clean::Crate, RenderInfo) { // Parse, resolve, and typecheck the given crate. @@ -144,6 +146,7 @@ pub fn run_core(search_paths: SearchPaths, actually_rustdoc: true, debugging_opts: config::DebuggingOptions { force_unstable_if_unmarked, + edition, ..config::basic_debugging_options() }, ..config::basic_options().clone() diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bec25a98227a..c22269cbab42 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -61,6 +61,7 @@ use std::path::{Path, PathBuf}; use std::process; use std::sync::mpsc::channel; +use syntax::edition::Edition; use externalfiles::ExternalHtml; use rustc::session::search_paths::SearchPaths; use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs}; @@ -270,6 +271,11 @@ pub fn opts() -> Vec { \"main-suffix.css\"", "PATH") }), + unstable("edition", |o| { + o.optopt("", "edition", + "edition to use when compiling rust code (default: 2015)", + "EDITION") + }), ] } @@ -428,6 +434,15 @@ pub fn main_args(args: &[String]) -> isize { let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance"); let resource_suffix = matches.opt_str("resource-suffix"); + let edition = matches.opt_str("edition").unwrap_or("2015".to_string()); + let edition = match edition.parse() { + Ok(e) => e, + Err(_) => { + print_error("could not parse edition"); + return 1; + } + }; + match (should_test, markdown_input) { (true, true) => { return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, @@ -435,7 +450,7 @@ pub fn main_args(args: &[String]) -> isize { } (true, false) => { return test::run(Path::new(input), cfgs, libs, externs, test_args, crate_name, - maybe_sysroot, display_warnings, linker) + maybe_sysroot, display_warnings, linker, edition) } (false, true) => return markdown::render(Path::new(input), output.unwrap_or(PathBuf::from("doc")), @@ -445,7 +460,7 @@ pub fn main_args(args: &[String]) -> isize { } let output_format = matches.opt_str("w"); - let res = acquire_input(PathBuf::from(input), externs, &matches, move |out| { + let res = acquire_input(PathBuf::from(input), externs, edition, &matches, move |out| { let Output { krate, passes, renderinfo } = out; info!("going to format"); match output_format.as_ref().map(|s| &**s) { @@ -486,14 +501,15 @@ fn print_error(error_message: T) where T: Display { /// and files and then generates the necessary rustdoc output for formatting. fn acquire_input(input: PathBuf, externs: Externs, + edition: Edition, matches: &getopts::Matches, f: F) -> Result where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { match matches.opt_str("r").as_ref().map(|s| &**s) { - Some("rust") => Ok(rust_input(input, externs, matches, f)), + Some("rust") => Ok(rust_input(input, externs, edition, matches, f)), Some(s) => Err(format!("unknown input format: {}", s)), - None => Ok(rust_input(input, externs, matches, f)) + None => Ok(rust_input(input, externs, edition, matches, f)) } } @@ -519,7 +535,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result { /// generated from the cleaned AST of the crate. /// /// This form of input will run all of the plug/cleaning passes -fn rust_input(cratefile: PathBuf, externs: Externs, matches: &getopts::Matches, f: F) -> R +fn rust_input(cratefile: PathBuf, externs: Externs, edition: Edition, matches: &getopts::Matches, f: F) -> R where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { let mut default_passes = !matches.opt_present("no-defaults"); let mut passes = matches.opt_strs("passes"); @@ -563,7 +579,7 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { let (mut krate, renderinfo) = core::run_core(paths, cfgs, externs, Input::File(cratefile), triple, maybe_sysroot, display_warnings, crate_name.clone(), - force_unstable_if_unmarked); + force_unstable_if_unmarked, edition); info!("finished with rustc"); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 3ce8bd4ebb4c..ba0060521b7b 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -34,6 +34,7 @@ use rustc_metadata::cstore::CStore; use rustc_resolve::MakeGlobMap; use syntax::ast; use syntax::codemap::CodeMap; +use syntax::edition::Edition; use syntax::feature_gate::UnstableFeatures; use syntax::with_globals; use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName}; @@ -57,7 +58,8 @@ pub fn run(input_path: &Path, crate_name: Option, maybe_sysroot: Option, display_warnings: bool, - linker: Option) + linker: Option, + edition: Edition) -> isize { let input = config::Input::File(input_path.to_owned()); @@ -70,6 +72,10 @@ pub fn run(input_path: &Path, unstable_features: UnstableFeatures::from_environment(), lint_cap: Some(::rustc::lint::Level::Allow), actually_rustdoc: true, + debugging_opts: config::DebuggingOptions { + edition, + ..config::basic_debugging_options() + }, ..config::basic_options().clone() }; From a0e48dde7c9d8cc7be9b22d7cf52a9549b5b0637 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Tue, 27 Mar 2018 16:36:15 +0200 Subject: [PATCH 674/830] talk about --edition in the Rustdoc Book --- src/doc/rustdoc/src/unstable-features.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 16356c20c706..b43ecab9d005 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -348,6 +348,19 @@ details. [issue-display-warnings]: https://github.com/rust-lang/rust/issues/41574 +### `--edition`: control the edition of docs and doctests + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs -Z unstable-options --edition 2018 +$ rustdoc --test src/lib.rs -Z unstable-options --edition 2018 +``` + +This flag allows rustdoc to treat your rust code as the given edition. It will compile doctests with +the given edition as well. As with `rustc`, the default edition that `rustdoc` will use is `2015` +(the first edition). + ### `-Z force-unstable-if-unmarked` Using this flag looks like this: From 422efd793b0d65bd1d1725937a853244af8124c8 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 27 Mar 2018 17:19:41 +0200 Subject: [PATCH 675/830] Use the actual discriminant instead of always choosing the dataful variant --- src/librustc_mir/hair/pattern/mod.rs | 6 ++++-- src/test/run-pass/match-arm-statics.rs | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 7359b1ed1021..798d63531818 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -878,8 +878,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ); }) } - ty::layout::Variants::NicheFilling { dataful_variant, .. } => - dataful_variant, + ty::layout::Variants::NicheFilling { .. } => { + assert_eq!(discr_val as usize as u128, discr_val); + discr_val as usize + }, }; let subpatterns = adt_subpatterns( adt_def.variants[variant_index].fields.len(), diff --git a/src/test/run-pass/match-arm-statics.rs b/src/test/run-pass/match-arm-statics.rs index 78a37f518378..ca6ef2e42777 100644 --- a/src/test/run-pass/match-arm-statics.rs +++ b/src/test/run-pass/match-arm-statics.rs @@ -94,6 +94,13 @@ fn issue_14576() { const F : C = C::D; assert_eq!(match C::D { F => 1, _ => 2, }, 1); + + // test gaps + #[derive(PartialEq, Eq)] + enum G { H = 3, I = 5 } + const K : G = G::I; + + assert_eq!(match G::I { K => 1, _ => 2, }, 1); } fn issue_13731() { From 4957a40d13a78e0f9f1208cc0528663c49f24386 Mon Sep 17 00:00:00 2001 From: matthew Date: Tue, 27 Mar 2018 08:39:15 -0700 Subject: [PATCH 676/830] Add extra test for expressions and fix typo in message --- src/librustc/hir/check_attr.rs | 2 +- src/test/compile-fail/issue-43988.rs | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index ecf8960c237d..316ed07ca05d 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { self.emit_repr_error( attr.span, stmt.span, - &format!("attribute should not be applied a statement"), + &format!("attribute should not be applied to a statement"), &format!("not a struct, enum or union"), ); } diff --git a/src/test/compile-fail/issue-43988.rs b/src/test/compile-fail/issue-43988.rs index c03cd67fef99..ff1fdaef416c 100644 --- a/src/test/compile-fail/issue-43988.rs +++ b/src/test/compile-fail/issue-43988.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(stmt_expr_attributes)] + fn main() { #[inline] @@ -21,7 +23,7 @@ fn main() { #[repr(nothing)] let _x = 0; - //~^^ ERROR attribute should not be applied a statement + //~^^ ERROR attribute should not be applied to a statement #[repr(something_not_real)] loop { @@ -31,7 +33,7 @@ fn main() { #[repr] let _y = "123"; - //~^^ ERROR attribute should not be applied a statement + //~^^ ERROR attribute should not be applied to a statement fn foo() {} @@ -39,4 +41,8 @@ fn main() { #[inline(ABC)] foo(); //~^^ ERROR attribute should be applied to function + + let _z = #[repr] 1; + //~^ ERROR attribute should not be applied to an expression + } From f513fbdf36ad0708fb222b8d55bc086dd4be18cf Mon Sep 17 00:00:00 2001 From: lukaslueg Date: Tue, 27 Mar 2018 20:56:15 +0200 Subject: [PATCH 677/830] Update CONTRIBUTING.md The current link is a 404, just link to the main repo page --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2b389888e518..7a62405f0596 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -594,7 +594,7 @@ If you're looking for somewhere to start, check out the [E-easy][eeasy] tag. [inom]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AI-nominated [eeasy]: https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3AE-easy [lru]: https://github.com/rust-lang/rust/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc -[rfcbot]: https://github.com/dikaiosune/rust-dashboard/blob/master/RFCBOT.md +[rfcbot]: https://github.com/anp/rfcbot-rs/ ## Out-of-tree Contributions [out-of-tree-contributions]: #out-of-tree-contributions From a93a4d259ae3670d748859f430aba94f065ea6df Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 27 Mar 2018 12:27:45 -0700 Subject: [PATCH 678/830] Enable target_feature on any LLVM 6+ In `LLVMRustHasFeature()`, rather than using `MCInfo->getFeatureTable()` that is specific to Rust's LLVM fork, we can use this in LLVM 6: /// Check whether the subtarget features are enabled/disabled as per /// the provided string, ignoring all other features. bool checkFeatures(StringRef FS) const; Now rustc using external LLVM can also have `target_feature`. --- src/rustllvm/PassWrapper.cpp | 12 ++++-------- src/test/run-pass/sse2.rs | 6 +++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 3d5cce81278a..382ef2cc407d 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -205,17 +205,13 @@ GEN_SUBTARGETS extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, const char *Feature) { -#if LLVM_RUSTLLVM +#if LLVM_VERSION_GE(6, 0) TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); - const FeatureBitset &Bits = MCInfo->getFeatureBits(); - const ArrayRef FeatTable = MCInfo->getFeatureTable(); - - for (auto &FeatureEntry : FeatTable) - if (!strcmp(FeatureEntry.Key, Feature)) - return (Bits & FeatureEntry.Value) == FeatureEntry.Value; -#endif + return MCInfo->checkFeatures(std::string("+") + Feature); +#else return false; +#endif } enum class LLVMRustCodeModel { diff --git a/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs index 22469b2fde05..b1d7e5435c4c 100644 --- a/src/test/run-pass/sse2.rs +++ b/src/test/run-pass/sse2.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// no-system-llvm -- needs MCSubtargetInfo::getFeatureTable() +// min-llvm-version 6.0 +// ^ needs MCSubtargetInfo::checkFeatures() // ignore-cloudabi no std::env #![feature(cfg_target_feature)] @@ -29,4 +30,7 @@ fn main() { assert!(cfg!(target_feature = "sse2"), "SSE2 was not detected as available on an x86 platform"); } + // check a negative case too -- whitelisted on x86, but not enabled by default + assert!(cfg!(not(target_feature = "avx2")), + "AVX2 shouldn't be detected as available by default on any platform"); } From 8be26a2ca0f9f01e5b1dd06d5681c4c94fc81042 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 27 Mar 2018 22:49:55 +0200 Subject: [PATCH 679/830] Fix collapse toggle insertions on impl with docs --- src/librustdoc/html/static/main.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 6c6c067f9518..0b510dd0b6c0 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1816,6 +1816,9 @@ var func = function(e) { var next = e.nextElementSibling; + if (hasClass(e, 'impl') && next && hasClass(next, 'docblock')) { + next = next.nextElementSibling; + } if (!next) { return; } From 38d48ef53778674baa99dd0a3a193cec78f74e63 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 27 Mar 2018 11:42:04 -0700 Subject: [PATCH 680/830] rustc: Forbid #[inline(always)] with #[target_feature] Once a target feature is enabled for a function that means that it in general can't be inlined into other functions which don't have that target feature enabled. This can cause both safety and LLVM issues if we were to actually inline it, so `#[inline(always)]` both can't be respected and would be an error if we did so! Today LLVM doesn't inline functions with different `#[target_feature]` annotations, but it turns out that if one is tagged with `#[inline(always)]` it'll override this and cause scary LLVM error to arise! This commit fixes this issue by forbidding these two attributes to be used in conjunction with one another. cc rust-lang-nursery/stdsimd#404 --- src/librustc_typeck/collect.rs | 15 +++++++++++++++ src/test/ui/target-feature-wrong.rs | 5 +++++ src/test/ui/target-feature-wrong.stderr | 8 +++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 6f24d06844bb..59156bf0dfea 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1769,6 +1769,7 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt let whitelist = tcx.target_features_whitelist(LOCAL_CRATE); + let mut inline_span = None; for attr in attrs.iter() { if attr.check_name("cold") { trans_fn_attrs.flags |= TransFnAttrFlags::COLD; @@ -1800,6 +1801,7 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt } MetaItemKind::List(ref items) => { mark_used(attr); + inline_span = Some(attr.span); if items.len() != 1 { span_err!(tcx.sess.diagnostic(), attr.span, E0534, "expected one argument"); @@ -1855,5 +1857,18 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt } } + // If a function uses #[target_feature] it can't be inlined into general + // purpose functions as they wouldn't have the right target features + // enabled. For that reason we also forbid #[inline(always)] as it can't be + // respected. + if trans_fn_attrs.target_features.len() > 0 { + if trans_fn_attrs.inline == InlineAttr::Always { + if let Some(span) = inline_span { + tcx.sess.span_err(span, "cannot use #[inline(always)] with \ + #[target_feature]"); + } + } + } + trans_fn_attrs } diff --git a/src/test/ui/target-feature-wrong.rs b/src/test/ui/target-feature-wrong.rs index c1e6245d24be..56acbed47210 100644 --- a/src/test/ui/target-feature-wrong.rs +++ b/src/test/ui/target-feature-wrong.rs @@ -33,6 +33,11 @@ fn bar() {} //~^ ERROR: should be applied to a function mod another {} +#[inline(always)] +//~^ ERROR: cannot use #[inline(always)] +#[target_feature(enable = "sse2")] +unsafe fn test() {} + fn main() { unsafe { foo(); diff --git a/src/test/ui/target-feature-wrong.stderr b/src/test/ui/target-feature-wrong.stderr index 0fa6910f2bb3..8773f8504cb0 100644 --- a/src/test/ui/target-feature-wrong.stderr +++ b/src/test/ui/target-feature-wrong.stderr @@ -37,5 +37,11 @@ LL | //~^ ERROR: should be applied to a function LL | mod another {} | -------------- not a function -error: aborting due to 5 previous errors +error: cannot use #[inline(always)] with #[target_feature] + --> $DIR/target-feature-wrong.rs:36:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors From 37fa6f8b12b9bcbd8fb663a6c1a6c5b98aa052fe Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Mar 2018 14:18:54 +0200 Subject: [PATCH 681/830] rustdoc: Don't use into_iter() when cleaning impl Trait --- src/librustdoc/clean/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a42b02140cd..b4c78df74152 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2756,7 +2756,7 @@ impl<'tcx> Clean for Ty<'tcx> { let predicates_of = cx.tcx.predicates_of(def_id); let substs = cx.tcx.lift(&substs).unwrap(); let bounds = predicates_of.instantiate(cx.tcx, substs); - ImplTrait(bounds.predicates.into_iter().filter_map(|predicate| { + ImplTrait(bounds.predicates.iter().filter_map(|predicate| { predicate.to_opt_poly_trait_ref().clean(cx) }).collect()) } From ac655d25c7c1b56fb70b272890b5df1cdd43d236 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Mar 2018 20:45:24 +0200 Subject: [PATCH 682/830] rustdoc: Include associated type bounds when cleaning foreign impl traits --- src/librustdoc/clean/mod.rs | 46 ++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b4c78df74152..875ed12718fa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1379,17 +1379,18 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option, has_self } } -impl<'tcx> Clean for ty::TraitRef<'tcx> { +impl<'a, 'tcx> Clean for (&'a ty::TraitRef<'tcx>, Vec) { fn clean(&self, cx: &DocContext) -> TyParamBound { - inline::record_extern_fqn(cx, self.def_id, TypeKind::Trait); - let path = external_path(cx, &cx.tcx.item_name(self.def_id), - Some(self.def_id), true, vec![], self.substs); + let (trait_ref, ref bounds) = *self; + inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait); + let path = external_path(cx, &cx.tcx.item_name(trait_ref.def_id), + Some(trait_ref.def_id), true, bounds.clone(), trait_ref.substs); - debug!("ty::TraitRef\n subst: {:?}\n", self.substs); + debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); // collect any late bound regions let mut late_bounds = vec![]; - for ty_s in self.input_types().skip(1) { + for ty_s in trait_ref.input_types().skip(1) { if let ty::TyTuple(ts) = ty_s.sty { for &ty_s in ts { if let ty::TyRef(ref reg, _) = ty_s.sty { @@ -1409,7 +1410,7 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { trait_: ResolvedPath { path, typarams: None, - did: self.def_id, + did: trait_ref.def_id, is_generic: false, }, generic_params: late_bounds, @@ -1419,6 +1420,12 @@ impl<'tcx> Clean for ty::TraitRef<'tcx> { } } +impl<'tcx> Clean for ty::TraitRef<'tcx> { + fn clean(&self, cx: &DocContext) -> TyParamBound { + (self, vec![]).clean(cx) + } +} + impl<'tcx> Clean>> for Substs<'tcx> { fn clean(&self, cx: &DocContext) -> Option> { let mut v = Vec::new(); @@ -2757,7 +2764,30 @@ impl<'tcx> Clean for Ty<'tcx> { let substs = cx.tcx.lift(&substs).unwrap(); let bounds = predicates_of.instantiate(cx.tcx, substs); ImplTrait(bounds.predicates.iter().filter_map(|predicate| { - predicate.to_opt_poly_trait_ref().clean(cx) + let trait_ref = if let Some(tr) = predicate.to_opt_poly_trait_ref() { + tr + } else { + return None; + }; + + let bounds = bounds.predicates.iter().filter_map(|pred| + if let ty::Predicate::Projection(proj) = *pred { + let proj = proj.skip_binder(); + if proj.projection_ty.trait_ref(cx.tcx) == *trait_ref.skip_binder() { + Some(TypeBinding { + name: cx.tcx.associated_item(proj.projection_ty.item_def_id) + .name.clean(cx), + ty: proj.ty.clean(cx), + }) + } else { + None + } + } else { + None + } + ).collect(); + + Some((trait_ref.skip_binder(), bounds).clean(cx)) }).collect()) } From 32446f8db3586ff8c56b745bc2fbaf4c88bcab71 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Mar 2018 20:59:09 +0200 Subject: [PATCH 683/830] rustdoc: Remove Sized bounds when cleaning foreign impl Trait --- src/librustdoc/clean/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 875ed12718fa..aa8a7fc53462 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2770,6 +2770,14 @@ impl<'tcx> Clean for Ty<'tcx> { return None; }; + if let Some(sized) = cx.tcx.lang_items().sized_trait() { + if trait_ref.def_id() == sized { + return None; + } + } + + // FIXME(Manishearth) handle cases which aren't Sized + let bounds = bounds.predicates.iter().filter_map(|pred| if let ty::Predicate::Projection(proj) = *pred { let proj = proj.skip_binder(); From 6a547b4f61f7acec8bf526e93cc244a82cb8925e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Mar 2018 21:26:44 +0200 Subject: [PATCH 684/830] rustdoc: Handle explicit ?Sized on foreign impl Trait --- src/librustdoc/clean/mod.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aa8a7fc53462..a7d34d525243 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2763,20 +2763,26 @@ impl<'tcx> Clean for Ty<'tcx> { let predicates_of = cx.tcx.predicates_of(def_id); let substs = cx.tcx.lift(&substs).unwrap(); let bounds = predicates_of.instantiate(cx.tcx, substs); - ImplTrait(bounds.predicates.iter().filter_map(|predicate| { + let mut regions = vec![]; + let mut has_sized = false; + let mut bounds = bounds.predicates.iter().filter_map(|predicate| { let trait_ref = if let Some(tr) = predicate.to_opt_poly_trait_ref() { tr + } else if let ty::Predicate::TypeOutlives(pred) = *predicate { + // these should turn up at the end + pred.skip_binder().1.clean(cx).map(|r| regions.push(RegionBound(r))); + return None; } else { return None; }; if let Some(sized) = cx.tcx.lang_items().sized_trait() { if trait_ref.def_id() == sized { + has_sized = true; return None; } } - // FIXME(Manishearth) handle cases which aren't Sized let bounds = bounds.predicates.iter().filter_map(|pred| if let ty::Predicate::Projection(proj) = *pred { @@ -2796,7 +2802,12 @@ impl<'tcx> Clean for Ty<'tcx> { ).collect(); Some((trait_ref.skip_binder(), bounds).clean(cx)) - }).collect()) + }).collect::>(); + bounds.extend(regions); + if !has_sized && !bounds.is_empty() { + bounds.insert(0, TyParamBound::maybe_sized(cx)); + } + ImplTrait(bounds) } ty::TyClosure(..) | ty::TyGenerator(..) => Tuple(vec![]), // FIXME(pcwalton) From 33dceaa24409951dfe7607c580de6fd504932c90 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 27 Mar 2018 21:37:27 +0200 Subject: [PATCH 685/830] rustdoc: Add test for foreign impl trait with bounds --- .../rustdoc/auxiliary/extern-impl-trait.rs | 37 +++++++++++++++++++ src/test/rustdoc/extern-impl-trait.rs | 21 +++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/test/rustdoc/auxiliary/extern-impl-trait.rs create mode 100644 src/test/rustdoc/extern-impl-trait.rs diff --git a/src/test/rustdoc/auxiliary/extern-impl-trait.rs b/src/test/rustdoc/auxiliary/extern-impl-trait.rs new file mode 100644 index 000000000000..ba6c3e956953 --- /dev/null +++ b/src/test/rustdoc/auxiliary/extern-impl-trait.rs @@ -0,0 +1,37 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait Foo { + type Associated; +} + +pub struct X; +pub struct Y; + + +impl Foo for X { + type Associated = (); +} + +impl Foo for Y { + type Associated = (); +} + +impl X { + pub fn returns_sized<'a>(&'a self) -> impl Foo + 'a { + X + } +} + +impl Y { + pub fn returns_unsized<'a>(&'a self) -> Box + 'a> { + Box::new(X) + } +} diff --git a/src/test/rustdoc/extern-impl-trait.rs b/src/test/rustdoc/extern-impl-trait.rs new file mode 100644 index 000000000000..02a8e962fe17 --- /dev/null +++ b/src/test/rustdoc/extern-impl-trait.rs @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:extern-impl-trait.rs + +#![crate_name = "foo"] + +extern crate extern_impl_trait; + +// @has 'foo/struct.X.html' '//code' "impl Foo + 'a" +pub use extern_impl_trait::X; + +// @has 'foo/struct.Y.html' '//code' "impl ?Sized + Foo + 'a" +pub use extern_impl_trait::Y; From 96ae0ee382a32d8218da454dc4fd2b2a6fa37c4a Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Tue, 27 Mar 2018 23:48:50 -0400 Subject: [PATCH 686/830] Use a new type to track if two-phase borrows are allowed Because more type safe is more better, and random boolean parameters everywhere were not the greatest thing. --- src/librustc/ty/adjustment.rs | 17 +++++++++++++++++ src/librustc_typeck/check/cast.rs | 5 +++-- src/librustc_typeck/check/coercion.rs | 20 ++++++++++++-------- src/librustc_typeck/check/demand.rs | 5 +++-- src/librustc_typeck/check/mod.rs | 10 ++++++---- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 7579d95a8fe6..edd6d56759d9 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -119,6 +119,23 @@ impl<'a, 'gcx, 'tcx> OverloadedDeref<'tcx> { } } +/// At least for initial deployment, we want to limit two-phase borrows to +/// only a few specific cases. Right now, those mostly "things that desugar" +/// into method calls +/// - using x.some_method() syntax, where some_method takes &mut self +/// - using Foo::some_method(&mut x, ...) syntax +/// - binary assignment operators (+=, -=, *=, etc.) +/// Anything else should be rejected until generalized two phase borrow support +/// is implemented. Right now, dataflow can't handle the general case where there +/// is more than one use of a mutable borrow, and we don't want to accept too much +/// new code via two-phase borrows, so we try to limit where we create two-phase +/// capable mutable borrows. +/// See #49434 for tracking. +pub enum AllowTwoPhase { + Yes, + No +} + #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] pub enum AutoBorrowMutability { Mutable { allow_two_phase_borrow: bool }, diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 70fe3afa6d25..8db8e52b10d4 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -47,6 +47,7 @@ use rustc::hir; use rustc::session::Session; use rustc::traits; use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::adjustment::AllowTwoPhase; use rustc::ty::cast::{CastKind, CastTy}; use rustc::ty::subst::Substs; use rustc::middle::lang_items; @@ -435,7 +436,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { let res = fcx.try_coerce(self.expr, self.expr_ty, fcx.tcx.mk_fn_ptr(f), - false); + AllowTwoPhase::No); if !res.is_ok() { return Err(CastError::NonScalar); } @@ -617,7 +618,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { } fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool { - fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, false).is_ok() + fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No).is_ok() } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 255794aeab43..8b4b4bab7c41 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -67,7 +67,7 @@ use rustc::hir::def_id::DefId; use rustc::infer::{Coercion, InferResult, InferOk}; use rustc::infer::type_variable::TypeVariableOrigin; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; -use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability}; +use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::{self, TypeAndMut, Ty, ClosureSubsts}; use rustc::ty::fold::TypeFoldable; use rustc::ty::error::TypeError; @@ -89,7 +89,8 @@ struct Coerce<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { /// allow deref coercions to create two-phase borrows, at least initially, /// but we do need two-phase borrows for function argument reborrows. /// See #47489 and #48598 - allow_two_phase: bool, + /// See docs on the "AllowTwoPhase" type for a more detailed discussion + allow_two_phase: AllowTwoPhase, } impl<'a, 'gcx, 'tcx> Deref for Coerce<'a, 'gcx, 'tcx> { @@ -131,7 +132,7 @@ fn success<'tcx>(adj: Vec>, impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { fn new(fcx: &'f FnCtxt<'f, 'gcx, 'tcx>, cause: ObligationCause<'tcx>, - allow_two_phase: bool) -> Self { + allow_two_phase: AllowTwoPhase) -> Self { Coerce { fcx, cause, @@ -433,7 +434,10 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let mutbl = match mt_b.mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { - allow_two_phase_borrow: self.allow_two_phase, + allow_two_phase_borrow: match self.allow_two_phase { + AllowTwoPhase::Yes => true, + AllowTwoPhase::No => false + }, } }; adjustments.push(Adjustment { @@ -761,7 +765,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &hir::Expr, expr_ty: Ty<'tcx>, target: Ty<'tcx>, - allow_two_phase: bool) + allow_two_phase: AllowTwoPhase) -> RelateResult<'tcx, Ty<'tcx>> { let source = self.resolve_type_vars_with_obligations(expr_ty); debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target); @@ -782,7 +786,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let cause = self.cause(syntax_pos::DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion - let coerce = Coerce::new(self, cause, false); + let coerce = Coerce::new(self, cause, AllowTwoPhase::No); self.probe(|_| coerce.coerce(source, target)).is_ok() } @@ -856,7 +860,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // probably aren't processing function arguments here and even if we were, // they're going to get autorefed again anyway and we can apply 2-phase borrows // at that time. - let mut coerce = Coerce::new(self, cause.clone(), false); + let mut coerce = Coerce::new(self, cause.clone(), AllowTwoPhase::No); coerce.use_lub = true; // First try to coerce the new expression to the type of the previous ones, @@ -1123,7 +1127,7 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E> // Special-case the first expression we are coercing. // To be honest, I'm not entirely sure why we do this. // We don't allow two-phase borrows, see comment in try_find_coercion_lub for why - fcx.try_coerce(expression, expression_ty, self.expected_ty, false) + fcx.try_coerce(expression, expression_ty, self.expected_ty, AllowTwoPhase::No) } else { match self.expressions { Expressions::Dynamic(ref exprs) => diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index ab89e17d81fe..36445e710015 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -21,6 +21,7 @@ use rustc::hir; use rustc::hir::print; use rustc::hir::def::Def; use rustc::ty::{self, Ty, AssociatedItem}; +use rustc::ty::adjustment::AllowTwoPhase; use errors::{DiagnosticBuilder, CodeMapper}; use super::method::probe; @@ -80,7 +81,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, - allow_two_phase: bool) + allow_two_phase: AllowTwoPhase) -> Ty<'tcx> { let (ty, err) = self.demand_coerce_diag(expr, checked_ty, expected, allow_two_phase); if let Some(mut err) = err { @@ -98,7 +99,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, - allow_two_phase: bool) + allow_two_phase: AllowTwoPhase) -> (Ty<'tcx>, Option>) { let expected = self.resolve_type_vars_with_obligations(expected); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fe27dd50af47..0e1d3fdbb976 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -97,7 +97,7 @@ use rustc::mir::interpret::{GlobalId}; use rustc::ty::subst::{Kind, Subst, Substs}; use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode}; use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate}; -use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; +use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::fold::TypeFoldable; use rustc::ty::maps::Providers; use rustc::ty::util::{Representability, IntTypeExt, Discr}; @@ -2649,7 +2649,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // to, which is `expected_ty` if `rvalue_hint` returns an // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise. let coerce_ty = expected.and_then(|e| e.only_has_type(self)); - self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty), true); + // We're processing function arguments so we definitely want to use two-phase borrows. + self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty), AllowTwoPhase::Yes); // 3. Relate the expected type and the formal one, // if the expected type was used for the coercion. @@ -2812,7 +2813,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expr, ExpectHasType(expected), needs); - self.demand_coerce(expr, ty, expected, false) + // checks don't need two phase + self.demand_coerce(expr, ty, expected, AllowTwoPhase::No) } fn check_expr_with_hint(&self, expr: &'gcx hir::Expr, @@ -4113,7 +4115,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match self.lookup_indexing(expr, base, base_t, idx_t, needs) { Some((index_ty, element_ty)) => { // two-phase not needed because index_ty is never mutable - self.demand_coerce(idx, idx_t, index_ty, false); + self.demand_coerce(idx, idx_t, index_ty, AllowTwoPhase::No); element_ty } None => { From 884153a2572b837c90725930345cfbe74c073dc1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Mar 2018 09:50:55 +0200 Subject: [PATCH 687/830] Fix trait implementation not collapsing docs --- src/librustdoc/html/static/main.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 6c6c067f9518..67a133a1934c 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1713,19 +1713,20 @@ // we are collapsing the impl block function implHider(addOrRemove) { return function(n) { - if (hasClass(n, "method")) { - if (addOrRemove) { - addClass(n, "hidden-by-impl-hider"); - } else { - removeClass(n, "hidden-by-impl-hider"); + var is_method = hasClass(n, "method"); + if (is_method || hasClass(n, "type")) { + if (is_method === true) { + if (addOrRemove) { + addClass(n, "hidden-by-impl-hider"); + } else { + removeClass(n, "hidden-by-impl-hider"); + } } var ns = n.nextElementSibling; while (true) { if (ns && ( hasClass(ns, "docblock") || - hasClass(ns, "stability") || - false - )) { + hasClass(ns, "stability"))) { if (addOrRemove) { addClass(ns, "hidden-by-impl-hider"); } else { @@ -1741,12 +1742,13 @@ } var relatedDoc = toggle.parentNode; + var docblock = relatedDoc.nextElementSibling; while (!hasClass(relatedDoc, "impl-items")) { relatedDoc = relatedDoc.nextElementSibling; } - if (!relatedDoc) { + if (!relatedDoc && !hasClass(docblock, "docblock")) { return; } @@ -1754,7 +1756,8 @@ var action = mode; if (action === "toggle") { - if (hasClass(relatedDoc, "fns-now-collapsed")) { + if (hasClass(relatedDoc, "fns-now-collapsed") || + hasClass(docblock, "hidden-by-impl-hider")) { action = "show"; } else { action = "hide"; @@ -1763,10 +1766,12 @@ if (action === "show") { removeClass(relatedDoc, "fns-now-collapsed"); + removeClass(docblock, "hidden-by-usual-hider"); onEach(toggle.childNodes, adjustToggle(false)); onEach(relatedDoc.childNodes, implHider(false)); } else if (action === "hide") { addClass(relatedDoc, "fns-now-collapsed"); + addClass(docblock, "hidden-by-usual-hider"); onEach(toggle.childNodes, adjustToggle(true)); onEach(relatedDoc.childNodes, implHider(true)); } From d64bd2afc3ee46b9167bb06b3bdacd3bd79add7e Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Wed, 28 Mar 2018 04:08:03 -0400 Subject: [PATCH 688/830] Push AllowTwoPhase down to the HAIR level For consistency, use AllowTwoPhase everywhere between the frontend and MIR. --- src/librustc/ich/impls_ty.rs | 4 ++++ src/librustc/ty/adjustment.rs | 3 ++- src/librustc_mir/hair/cx/expr.rs | 6 +++++- src/librustc_typeck/check/callee.rs | 4 ++-- src/librustc_typeck/check/coercion.rs | 7 ++----- src/librustc_typeck/check/method/confirm.rs | 6 +++--- src/librustc_typeck/check/mod.rs | 13 ++++++------- src/librustc_typeck/check/op.rs | 6 +++--- 8 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 9a442e052993..89b8bfcd4ca2 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -188,6 +188,10 @@ for ty::adjustment::Adjust<'gcx> { impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target }); impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl }); impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region }); +impl_stable_hash_for!(enum ty::adjustment::AllowTwoPhase { + Yes, + No +}); impl<'gcx> HashStable> for ty::adjustment::AutoBorrowMutability { fn hash_stable(&self, diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index edd6d56759d9..a0c31e8b5092 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -131,6 +131,7 @@ impl<'a, 'gcx, 'tcx> OverloadedDeref<'tcx> { /// new code via two-phase borrows, so we try to limit where we create two-phase /// capable mutable borrows. /// See #49434 for tracking. +#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] pub enum AllowTwoPhase { Yes, No @@ -138,7 +139,7 @@ pub enum AllowTwoPhase { #[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)] pub enum AutoBorrowMutability { - Mutable { allow_two_phase_borrow: bool }, + Mutable { allow_two_phase_borrow: AllowTwoPhase }, Immutable, } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 62d1b43d6257..5b3739084801 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -662,9 +662,13 @@ trait ToBorrowKind { fn to_borrow_kind(&self) -> BorrowKind; } impl ToBorrowKind for AutoBorrowMutability { fn to_borrow_kind(&self) -> BorrowKind { + use rustc::ty::adjustment::AllowTwoPhase; match *self { AutoBorrowMutability::Mutable { allow_two_phase_borrow } => - BorrowKind::Mut { allow_two_phase_borrow }, + BorrowKind::Mut { allow_two_phase_borrow: match allow_two_phase_borrow { + AllowTwoPhase::Yes => true, + AllowTwoPhase::No => false + }}, AutoBorrowMutability::Immutable => BorrowKind::Shared, } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 3d61ffe39336..b1fb0938698c 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -16,7 +16,7 @@ use hir::def::Def; use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::{infer, traits}; use rustc::ty::{self, TyCtxt, TypeFoldable, Ty}; -use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability}; +use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use syntax::abi; use syntax::symbol::Symbol; use syntax_pos::Span; @@ -182,7 +182,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // For initial two-phase borrow // deployment, conservatively omit // overloaded function call ops. - allow_two_phase_borrow: false, + allow_two_phase_borrow: AllowTwoPhase::No, } }; autoref = Some(Adjustment { diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 8b4b4bab7c41..a956dd9a4ee0 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -434,10 +434,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let mutbl = match mt_b.mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { - allow_two_phase_borrow: match self.allow_two_phase { - AllowTwoPhase::Yes => true, - AllowTwoPhase::No => false - }, + allow_two_phase_borrow: self.allow_two_phase, } }; adjustments.push(Adjustment { @@ -486,7 +483,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // We don't allow two-phase borrows here, at least for initial // implementation. If it happens that this coercion is a function argument, // the reborrow in coerce_borrowed_ptr will pick it up. - allow_two_phase_borrow: false, + allow_two_phase_borrow: AllowTwoPhase::No, } }; Some((Adjustment { diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index b777ac30920c..8a37c11f191e 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -17,7 +17,7 @@ use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, Ty}; use rustc::ty::subst::Subst; -use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability, OverloadedDeref}; +use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, OverloadedDeref}; use rustc::ty::fold::TypeFoldable; use rustc::infer::{self, InferOk}; use syntax_pos::Span; @@ -170,7 +170,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { hir::MutMutable => AutoBorrowMutability::Mutable { // Method call receivers are the primary use case // for two-phase borrows. - allow_two_phase_borrow: true, + allow_two_phase_borrow: AllowTwoPhase::Yes, } }; adjustments.push(Adjustment { @@ -544,7 +544,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // For initial two-phase borrow // deployment, conservatively omit // overloaded operators. - allow_two_phase_borrow: false, + allow_two_phase_borrow: AllowTwoPhase::No, } }; adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(region, mutbl)); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0e1d3fdbb976..a377ff4d29d2 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2341,12 +2341,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mutbl = match mt.mutbl { hir::MutImmutable => AutoBorrowMutability::Immutable, hir::MutMutable => AutoBorrowMutability::Mutable { - // FIXME (#46747): arguably indexing is - // "just another kind of call"; perhaps it - // would be more consistent to allow - // two-phase borrows for .index() - // receivers here. - allow_two_phase_borrow: false, + // Indexing can be desugared to a method call, + // so maybe we could use two-phase here. + // See the documentation of AllowTwoPhase for why that's + // not the case today. + allow_two_phase_borrow: AllowTwoPhase::No, } }; adjustments.push(Adjustment { @@ -3647,7 +3646,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // (It shouldn't actually matter for unary ops whether // we enable two-phase borrows or not, since a unary // op has no additional operands.) - allow_two_phase_borrow: false, + allow_two_phase_borrow: AllowTwoPhase::No, } }; self.apply_adjustments(oprnd, vec![Adjustment { diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index eae692f4cdad..a6fa3a6453fd 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -14,7 +14,7 @@ use super::{FnCtxt, Needs}; use super::method::MethodCallee; use rustc::ty::{self, Ty, TypeFoldable, TypeVariants}; use rustc::ty::TypeVariants::{TyStr, TyRef, TyAdt}; -use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability}; +use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::infer::type_variable::TypeVariableOrigin; use errors; use syntax_pos::Span; @@ -206,7 +206,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::MutMutable => AutoBorrowMutability::Mutable { // Allow two-phase borrows for binops in initial deployment // since they desugar to methods - allow_two_phase_borrow: true, + allow_two_phase_borrow: AllowTwoPhase::Yes, } }; let autoref = Adjustment { @@ -223,7 +223,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::MutMutable => AutoBorrowMutability::Mutable { // Allow two-phase borrows for binops in initial deployment // since they desugar to methods - allow_two_phase_borrow: true, + allow_two_phase_borrow: AllowTwoPhase::Yes, } }; let autoref = Adjustment { From fa60b7212373a0984c014c2ada74a0538b5b324c Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 27 Mar 2018 10:38:51 +0200 Subject: [PATCH 689/830] Fix stable hashing of AllocIds --- src/librustc/ich/hcx.rs | 4 +++ src/librustc/ich/impls_ty.rs | 30 +++++++++++-------- .../static_stable_hash/issue-49301.rs | 28 +++++++++++++++++ 3 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 src/test/incremental/static_stable_hash/issue-49301.rs diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 33e0d0e69449..04b725957b62 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -15,6 +15,7 @@ use hir::map::definitions::Definitions; use ich::{self, CachingCodemapView, Fingerprint}; use middle::cstore::CrateStore; use ty::{TyCtxt, fast_reject}; +use mir::interpret::AllocId; use session::Session; use std::cmp::Ord; @@ -59,6 +60,8 @@ pub struct StableHashingContext<'a> { // CachingCodemapView, so we initialize it lazily. raw_codemap: &'a CodeMap, caching_codemap: Option>, + + pub(super) alloc_id_recursion_tracker: FxHashSet, } #[derive(PartialEq, Eq, Clone, Copy)] @@ -102,6 +105,7 @@ impl<'a> StableHashingContext<'a> { hash_spans: hash_spans_initial, hash_bodies: true, node_id_hashing_mode: NodeIdHashingMode::HashDefPath, + alloc_id_recursion_tracker: Default::default(), } } diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 9a442e052993..832f49d5b236 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -379,13 +379,13 @@ impl_stable_hash_for!(struct mir::interpret::MemoryPointer { }); enum AllocDiscriminant { - Static, - Constant, + Alloc, + ExternStatic, Function, } impl_stable_hash_for!(enum self::AllocDiscriminant { - Static, - Constant, + Alloc, + ExternStatic, Function }); @@ -397,17 +397,23 @@ impl<'a> HashStable> for mir::interpret::AllocId { ) { ty::tls::with_opt(|tcx| { let tcx = tcx.expect("can't hash AllocIds during hir lowering"); - if let Some(def_id) = tcx.interpret_interner.get_corresponding_static_def_id(*self) { - AllocDiscriminant::Static.hash_stable(hcx, hasher); - // statics are unique via their DefId - def_id.hash_stable(hcx, hasher); - } else if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) { - // not a static, can't be recursive, hash the allocation - AllocDiscriminant::Constant.hash_stable(hcx, hasher); - alloc.hash_stable(hcx, hasher); + if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) { + AllocDiscriminant::Alloc.hash_stable(hcx, hasher); + if !hcx.alloc_id_recursion_tracker.insert(*self) { + tcx + .interpret_interner + .get_corresponding_static_def_id(*self) + .hash_stable(hcx, hasher); + alloc.hash_stable(hcx, hasher); + assert!(hcx.alloc_id_recursion_tracker.remove(self)); + } } else if let Some(inst) = tcx.interpret_interner.get_fn(*self) { AllocDiscriminant::Function.hash_stable(hcx, hasher); inst.hash_stable(hcx, hasher); + } else if let Some(def_id) = tcx.interpret_interner + .get_corresponding_static_def_id(*self) { + AllocDiscriminant::ExternStatic.hash_stable(hcx, hasher); + def_id.hash_stable(hcx, hasher); } else { bug!("no allocation for {}", self); } diff --git a/src/test/incremental/static_stable_hash/issue-49301.rs b/src/test/incremental/static_stable_hash/issue-49301.rs new file mode 100644 index 000000000000..3e421b27c11b --- /dev/null +++ b/src/test/incremental/static_stable_hash/issue-49301.rs @@ -0,0 +1,28 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// https://github.com/rust-lang/rust/issues/49081 + +// revisions:rpass1 rpass2 + +#[cfg(rpass1)] +pub static A: &str = "hello"; +#[cfg(rpass2)] +pub static A: &str = "xxxxx"; + +#[cfg(rpass1)] +fn main() { + assert_eq!(A, "hello"); +} + +#[cfg(rpass2)] +fn main() { + assert_eq!(A, "xxxxx"); +} From 7038236da9aaadfd16208ee489e61a1a1230417c Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 28 Mar 2018 10:49:45 +0200 Subject: [PATCH 690/830] Delete leftover librustc_const_eval Probably accidentally reintroduced in a rebase/merge --- src/librustc_const_eval/lib.rs | 59 ---------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 src/librustc_const_eval/lib.rs diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs deleted file mode 100644 index 2620448927d8..000000000000 --- a/src/librustc_const_eval/lib.rs +++ /dev/null @@ -1,59 +0,0 @@ -// 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. - -//! constant evaluation on the HIR and code to validate patterns/matches -//! -//! # Note -//! -//! This API is completely unstable and subject to change. - -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/")] -#![deny(warnings)] - -#![feature(rustc_diagnostic_macros)] -#![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(macro_lifetime_matcher)] -#![cfg_attr(stage0, feature(i128_type))] -#![feature(from_ref)] - -extern crate arena; -#[macro_use] extern crate syntax; -#[macro_use] extern crate log; -#[macro_use] extern crate rustc; -extern crate rustc_const_math; -extern crate rustc_data_structures; -extern crate rustc_errors; -extern crate syntax_pos; - -// NB: This module needs to be declared first so diagnostics are -// registered before they are used. -mod diagnostics; - -mod eval; -mod _match; -pub mod check_match; -pub mod pattern; - -pub use eval::*; - -use rustc::ty::maps::Providers; - -pub fn provide(providers: &mut Providers) { - *providers = Providers { - check_match: check_match::check_match, - ..*providers - }; -} - -// Build the diagnostics array at the end so that the metadata includes error use sites. -__build_diagnostic_array! { librustc_const_eval, DIAGNOSTICS } From 3c65f536206a4df9900f5f6666f3674817d3638b Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Mon, 26 Mar 2018 23:39:29 +0200 Subject: [PATCH 691/830] Stabilize match_default_bindings This includes a submodule update to rustfmt in order to allow a stable feature declaration. --- src/Cargo.lock | 48 +++++++-------- .../match-default-bindings.md | 58 ------------------ src/librustc/diagnostics.rs | 59 ------------------- src/librustc/lib.rs | 2 +- src/librustc_borrowck/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_traits/lib.rs | 2 +- src/librustc_typeck/check/_match.rs | 41 ++----------- src/librustc_typeck/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 5 +- src/libsyntax/lib.rs | 2 +- src/test/compile-fail/issue-16338.rs | 1 - src/test/compile-fail/issue-20261.rs | 2 +- src/test/compile-fail/match-range-fail.rs | 2 - src/test/compile-fail/match-vec-mismatch.rs | 2 +- src/test/run-pass/nll/rc-loop.rs | 1 - .../rfc-2005-default-binding-mode/box.rs | 1 - .../rfc-2005-default-binding-mode/constref.rs | 2 - .../rfc-2005-default-binding-mode/enum.rs | 2 - .../rfc-2005-default-binding-mode/for.rs | 2 - .../rfc-2005-default-binding-mode/general.rs | 2 - .../rfc-2005-default-binding-mode/lit.rs | 2 - .../rfc-2005-default-binding-mode/range.rs | 2 - .../ref-region.rs | 2 - .../reset-mode.rs | 2 - .../rfc-2005-default-binding-mode/slice.rs | 1 - .../rfc-2005-default-binding-mode/struct.rs | 2 - .../tuple-struct.rs | 2 - .../rfc-2005-default-binding-mode/tuple.rs | 2 - src/test/ui/error-codes/E0029-teach.rs | 1 - src/test/ui/error-codes/E0029-teach.stderr | 13 +--- src/test/ui/error-codes/E0029.rs | 1 - src/test/ui/error-codes/E0029.stderr | 13 +--- .../ui/feature-gate-match_default_bindings.rs | 17 ------ ...feature-gate-match_default_bindings.stderr | 11 ---- src/test/ui/pat-slice-old-style.rs | 27 --------- src/test/ui/pat-slice-old-style.stderr | 11 ---- .../ui/rfc-2005-default-binding-mode/const.rs | 2 - .../const.stderr | 2 +- .../ui/rfc-2005-default-binding-mode/enum.rs | 2 - .../rfc-2005-default-binding-mode/enum.stderr | 6 +- .../explicit-mut.rs | 2 - .../explicit-mut.stderr | 6 +- .../ui/rfc-2005-default-binding-mode/for.rs | 2 - .../rfc-2005-default-binding-mode/for.stderr | 2 +- .../issue-44912-or.rs | 2 - .../issue-44912-or.stderr | 2 +- .../ui/rfc-2005-default-binding-mode/lit.rs | 2 - .../rfc-2005-default-binding-mode/lit.stderr | 4 +- .../ui/rfc-2005-default-binding-mode/slice.rs | 1 - .../slice.stderr | 2 +- .../suggestion.rs | 15 ----- .../suggestion.stderr | 11 ---- .../dont-suggest-dereference-on-arg.rs | 19 ------ .../dont-suggest-dereference-on-arg.stderr | 11 ---- src/tools/rustfmt | 2 +- 56 files changed, 55 insertions(+), 389 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/match-default-bindings.md delete mode 100644 src/test/ui/feature-gate-match_default_bindings.rs delete mode 100644 src/test/ui/feature-gate-match_default_bindings.stderr delete mode 100644 src/test/ui/pat-slice-old-style.rs delete mode 100644 src/test/ui/pat-slice-old-style.stderr delete mode 100644 src/test/ui/rfc-2005-default-binding-mode/suggestion.rs delete mode 100644 src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr delete mode 100644 src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs delete mode 100644 src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr diff --git a/src/Cargo.lock b/src/Cargo.lock index ad745d29e15e..8ace51ddac2b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1511,7 +1511,7 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_cratesio_shim" -version = "67.0.0" +version = "73.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1520,7 +1520,7 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "67.0.0" +version = "73.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1528,20 +1528,20 @@ dependencies = [ "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_errors" -version = "67.0.0" +version = "73.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1549,32 +1549,32 @@ dependencies = [ [[package]] name = "rustc-ap-serialize" -version = "67.0.0" +version = "73.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rustc-ap-syntax" -version = "67.0.0" +version = "73.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-syntax_pos" -version = "67.0.0" +version = "73.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2009,7 +2009,7 @@ dependencies = [ "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2729,12 +2729,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rls-rustc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "885f66b92757420572cbb02e033d4a9558c7413ca9b7ac206f28fd58ffdb44ea" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rls-vfs 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "be231e1e559c315bc60ced5ad2cc2d7a9c208ed7d4e2c126500149836fda19bb" -"checksum rustc-ap-rustc_cratesio_shim 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "adc16e4a6e50a4ffbd4633d737aedbdfcb565bdf658159e0544266908180a919" -"checksum rustc-ap-rustc_data_structures 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ec5f0a018fbec07f64b689ac20f7343ed77939055ca07d2aceb37c832245b1b" -"checksum rustc-ap-rustc_errors 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8301221cc07002666eed552a089b15000bc954c94b14a460c0653363a7f42f4c" -"checksum rustc-ap-serialize 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5212ee40fc332d791cacf202ae5fb99197341857c0a14bcdf60541fea7dfc5ed" -"checksum rustc-ap-syntax 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "168571b3878c6c61aef4bacef95c86d30fa61fb1cff04395d9535c80c196e559" -"checksum rustc-ap-syntax_pos 67.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd7a0486f56db583caa665c8b4ff02c4774fe279db1741509437bc8a84c53361" +"checksum rustc-ap-rustc_cratesio_shim 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "421262e22426c06306e46057a75048f883dbc43886f78dbe1e750397a9c9b8e6" +"checksum rustc-ap-rustc_data_structures 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8460c1207f9abb48a9720aee8be418bcfac018b6eee7b740b98a410e7799d24a" +"checksum rustc-ap-rustc_errors 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad2077469162e52fcd84543334e18632088b9e342fe54e3b78c37d7077d09714" +"checksum rustc-ap-serialize 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69943901ae255dca5f63faeae2ff08b402d34a56d1eb50d34fbff6e83e6ace60" +"checksum rustc-ap-syntax 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a44363359a43df753e26a4d4fef72720af183de635ebae8699686cb5d5de813" +"checksum rustc-ap-syntax_pos 73.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "413f464657e8d5f3864de308dba1867526f21a44809b6f338b34e8c0caf88fb0" "checksum rustc-demangle 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11fb43a206a04116ffd7cfcf9bcb941f8eb6cc7ff667272246b0a1c74259a3cb" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" diff --git a/src/doc/unstable-book/src/language-features/match-default-bindings.md b/src/doc/unstable-book/src/language-features/match-default-bindings.md deleted file mode 100644 index cc542931cbe1..000000000000 --- a/src/doc/unstable-book/src/language-features/match-default-bindings.md +++ /dev/null @@ -1,58 +0,0 @@ -# `match_default_bindings` - -The tracking issue for this feature is: [#42640] - -[#42640]: https://github.com/rust-lang/rust/issues/42640 - ------------------------- - -Match default bindings (also called "default binding modes in match") improves ergonomics for -pattern-matching on references by introducing automatic dereferencing (and a corresponding shift -in binding modes) for large classes of patterns that would otherwise not compile. - -For example, under match default bindings, - -```rust -#![feature(match_default_bindings)] - -fn main() { - let x: &Option<_> = &Some(0); - - match x { - Some(y) => { - println!("y={}", *y); - }, - None => {}, - } -} -``` - -compiles and is equivalent to either of the below: - -```rust -fn main() { - let x: &Option<_> = &Some(0); - - match *x { - Some(ref y) => { - println!("y={}", *y); - }, - None => {}, - } -} -``` - -or - -```rust -fn main() { - let x: &Option<_> = &Some(0); - - match x { - &Some(ref y) => { - println!("y={}", *y); - }, - &None => {}, - } -} -``` diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index f95c355012a2..c74ae2343b86 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -887,65 +887,6 @@ foo(3_i8); // therefore the type-checker complains with this error code. ``` -Here is a more subtle instance of the same problem, that can -arise with for-loops in Rust: - -```compile_fail -let vs: Vec = vec![1, 2, 3, 4]; -for v in &vs { - match v { - 1 => {}, - _ => {}, - } -} -``` - -The above fails because of an analogous type mismatch, -though may be harder to see. Again, here are some -explanatory comments for the same example: - -```compile_fail -{ - let vs = vec![1, 2, 3, 4]; - - // `for`-loops use a protocol based on the `Iterator` - // trait. Each item yielded in a `for` loop has the - // type `Iterator::Item` -- that is, `Item` is the - // associated type of the concrete iterator impl. - for v in &vs { -// ~ ~~~ -// | | -// | We borrow `vs`, iterating over a sequence of -// | *references* of type `&Elem` (where `Elem` is -// | vector's element type). Thus, the associated -// | type `Item` must be a reference `&`-type ... -// | -// ... and `v` has the type `Iterator::Item`, as dictated by -// the `for`-loop protocol ... - - match v { - 1 => {} -// ~ -// | -// ... but *here*, `v` is forced to have some integral type; -// only types like `u8`,`i8`,`u16`,`i16`, et cetera can -// match the pattern `1` ... - - _ => {} - } - -// ... therefore, the compiler complains, because it sees -// an attempt to solve the equations -// `some integral-type` = type-of-`v` -// = `Iterator::Item` -// = `&Elem` (i.e. `some reference type`) -// -// which cannot possibly all be true. - - } -} -``` - To avoid those issues, you have to make the types match correctly. So we can fix the previous examples like this: diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index e835d6192e54..ae8ae9404bc8 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -55,7 +55,7 @@ #![cfg_attr(stage0, feature(i128_type, i128))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![cfg_attr(windows, feature(libc))] -#![feature(match_default_bindings)] +#![cfg_attr(stage0, feature(match_default_bindings))] #![feature(macro_lifetime_matcher)] #![feature(macro_vis_matcher)] #![feature(exhaustive_patterns)] diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 2bdee3198f22..d54654c60868 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -16,7 +16,7 @@ #![allow(non_camel_case_types)] #![feature(from_ref)] -#![feature(match_default_bindings)] +#![cfg_attr(stage0, feature(match_default_bindings))] #![feature(quote)] #[macro_use] extern crate log; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index a1f096b2a382..262e5f608ca6 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -30,7 +30,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![cfg_attr(stage0, feature(i128_type))] #![cfg_attr(stage0, feature(inclusive_range_syntax))] #![feature(macro_vis_matcher)] -#![feature(match_default_bindings)] +#![cfg_attr(stage0, feature(match_default_bindings))] #![feature(exhaustive_patterns)] #![feature(range_contains)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 2a0f076cefde..0a21cc597e63 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -14,7 +14,7 @@ #![deny(warnings)] #![feature(crate_visibility_modifier)] -#![feature(match_default_bindings)] +#![cfg_attr(stage0, feature(match_default_bindings))] #![feature(underscore_lifetimes)] #[macro_use] diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 00c3b2278098..43ff925e422f 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -23,7 +23,6 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cmp; use syntax::ast; use syntax::codemap::Spanned; -use syntax::feature_gate; use syntax::ptr::P; use syntax_pos::Span; @@ -114,42 +113,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; if pat_adjustments.len() > 0 { - if tcx.features().match_default_bindings { - debug!("default binding mode is now {:?}", def_bm); - self.inh.tables.borrow_mut() - .pat_adjustments_mut() - .insert(pat.hir_id, pat_adjustments); - } else { - let mut ref_sp = pat.span; - let mut id = pat.id; - loop { // make span include all enclosing `&` to avoid confusing diag output - id = tcx.hir.get_parent_node(id); - let node = tcx.hir.find(id); - if let Some(hir::map::NodePat(pat)) = node { - if let hir::PatKind::Ref(..) = pat.node { - ref_sp = pat.span; - } else { - break; - } - } else { - break; - } - } - let sp = ref_sp.to(pat.span); - let mut err = feature_gate::feature_err( - &tcx.sess.parse_sess, - "match_default_bindings", - sp, - feature_gate::GateIssue::Language, - "non-reference pattern used to match a reference", - ); - if let Ok(snippet) = tcx.sess.codemap().span_to_snippet(sp) { - err.span_suggestion(sp, - "consider using a reference", - format!("&{}", &snippet)); - } - err.emit(); - } + debug!("default binding mode is now {:?}", def_bm); + self.inh.tables.borrow_mut() + .pat_adjustments_mut() + .insert(pat.hir_id, pat_adjustments); } } else if let PatKind::Ref(..) = pat.node { // When you encounter a `&pat` pattern, reset to "by diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 86c5e49d1674..44ecb32a0bf9 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -79,7 +79,7 @@ This API is completely unstable and subject to change. #![cfg_attr(stage0, feature(copy_closures, clone_closures))] #![feature(crate_visibility_modifier)] #![feature(from_ref)] -#![feature(match_default_bindings)] +#![cfg_attr(stage0, feature(match_default_bindings))] #![feature(exhaustive_patterns)] #![feature(option_filter)] #![feature(quote)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 4e3c77d5e465..ce8c613dc8bb 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -385,9 +385,6 @@ declare_features! ( // allow `'_` placeholder lifetimes (active, underscore_lifetimes, "1.22.0", Some(44524), None), - // Default match binding modes (RFC 2005) - (active, match_default_bindings, "1.22.0", Some(42640), None), - // Trait object syntax with `dyn` prefix (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), @@ -563,6 +560,8 @@ declare_features! ( (accepted, conservative_impl_trait, "1.26.0", Some(34511), None), // The `i128` type (accepted, i128_type, "1.26.0", Some(35118), None), + // Default match binding modes (RFC 2005) + (accepted, match_default_bindings, "1.26.0", Some(42640), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 2218b3966851..dc349c1a3e6a 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -22,7 +22,7 @@ #![feature(unicode)] #![feature(rustc_diagnostic_macros)] -#![feature(match_default_bindings)] +#![cfg_attr(stage0, feature(match_default_bindings))] #![feature(non_exhaustive)] #![cfg_attr(stage0, feature(i128_type))] #![feature(const_atomic_usize_new)] diff --git a/src/test/compile-fail/issue-16338.rs b/src/test/compile-fail/issue-16338.rs index 6fdf8802e385..438073e3b2f8 100644 --- a/src/test/compile-fail/issue-16338.rs +++ b/src/test/compile-fail/issue-16338.rs @@ -17,5 +17,4 @@ fn main() { let Slice { data: data, len: len } = "foo"; //~^ ERROR mismatched types //~| found type `Slice<_>` - //~| ERROR non-reference pattern used to match a reference } diff --git a/src/test/compile-fail/issue-20261.rs b/src/test/compile-fail/issue-20261.rs index 092aaa769550..bb4dbdcd0cba 100644 --- a/src/test/compile-fail/issue-20261.rs +++ b/src/test/compile-fail/issue-20261.rs @@ -11,7 +11,7 @@ fn main() { // NB: this (almost) typechecks when default binding modes are enabled. for (ref i,) in [].iter() { - //~^ ERROR non-reference pattern used to match a reference i.clone(); + //~^ ERROR type annotations needed } } diff --git a/src/test/compile-fail/match-range-fail.rs b/src/test/compile-fail/match-range-fail.rs index 355ff6404cea..f89b3e39390d 100644 --- a/src/test/compile-fail/match-range-fail.rs +++ b/src/test/compile-fail/match-range-fail.rs @@ -15,7 +15,6 @@ fn main() { //~^^ ERROR only char and numeric types are allowed in range //~| start type: &'static str //~| end type: &'static str - //~| ERROR non-reference pattern used to match a reference match "wow" { 10 ... "what" => () @@ -23,7 +22,6 @@ fn main() { //~^^ ERROR only char and numeric types are allowed in range //~| start type: {integer} //~| end type: &'static str - //~| ERROR non-reference pattern used to match a reference match 5 { 'c' ... 100 => { } diff --git a/src/test/compile-fail/match-vec-mismatch.rs b/src/test/compile-fail/match-vec-mismatch.rs index 998c11979953..d737aa0029bf 100644 --- a/src/test/compile-fail/match-vec-mismatch.rs +++ b/src/test/compile-fail/match-vec-mismatch.rs @@ -19,7 +19,7 @@ fn main() { // Note that this one works with default binding modes. match &[0, 1, 2] { - [..] => {} //~ ERROR non-reference pattern used to match a reference + [..] => {} }; match &[0, 1, 2] { diff --git a/src/test/run-pass/nll/rc-loop.rs b/src/test/run-pass/nll/rc-loop.rs index 2b746fac4d42..2114dbebe93f 100644 --- a/src/test/run-pass/nll/rc-loop.rs +++ b/src/test/run-pass/nll/rc-loop.rs @@ -14,7 +14,6 @@ // `x`. The lexical checker makes this very painful. The NLL checker // does not. -#![feature(match_default_bindings)] #![feature(nll)] use std::rc::Rc; diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/box.rs b/src/test/run-pass/rfc-2005-default-binding-mode/box.rs index 85453f32208c..95bce1935e52 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/box.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/box.rs @@ -9,7 +9,6 @@ // except according to those terms. #![feature(box_syntax, box_patterns)] -#![feature(match_default_bindings)] struct Foo{} diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs b/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs index 1b8fdbaa4d75..af40ef2b1c5d 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/constref.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - const CONST_REF: &[u8; 3] = b"foo"; trait Foo { diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs b/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs index a7b3db021b02..4755fc37ef34 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/enum.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - enum Wrapper { Wrap(i32), } diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/for.rs b/src/test/run-pass/rfc-2005-default-binding-mode/for.rs index 4feab94a7edf..c2467d3f0091 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/for.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/for.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - pub fn main() { let mut tups = vec![(0u8, 1u8)]; diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/general.rs b/src/test/run-pass/rfc-2005-default-binding-mode/general.rs index 779a38bdb167..df28046d7d70 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/general.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/general.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - fn some_or_wildcard(r: &Option, b: &i32) { let _: &i32 = match r { Some(a) => a, diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs b/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs index 0b2a8e52fbf7..004ea42b65b8 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/lit.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - fn with_u8() { let s = 5u8; let r = match &s { diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/range.rs b/src/test/run-pass/rfc-2005-default-binding-mode/range.rs index aafaa4cca82c..2292d97eaf4e 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/range.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/range.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - pub fn main() { let i = 5; match &&&&i { diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs b/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs index de7df011b56f..bc96853fd948 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/ref-region.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - fn foo<'a, 'b>(x: &'a &'b Option) -> &'a u32 { let x: &'a &'a Option = x; match x { diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs index f980ef0ccddd..1d86a2ecf869 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - // Test that we "reset" the mode as we pass through a `&` pattern. // // cc #46688 diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs b/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs index 6178f613b4b8..0d1d0893c593 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/slice.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] #![feature(slice_patterns)] fn slice_pat() { diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs b/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs index 11a675c0c72a..017439b3b140 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/struct.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - #[derive(Debug, PartialEq)] struct Foo { x: u8, diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs b/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs index 7867d6529050..3b55405abdd7 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/tuple-struct.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - enum Foo { Bar(Option, (), (), Vec), Baz, diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs b/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs index cf27265b2ed5..966b8e1a8127 100644 --- a/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs +++ b/src/test/run-pass/rfc-2005-default-binding-mode/tuple.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - pub fn main() { let foo = (Some(1), (), (), vec![2, 3]); diff --git a/src/test/ui/error-codes/E0029-teach.rs b/src/test/ui/error-codes/E0029-teach.rs index ca85f58133cc..1bc2c2d58b19 100644 --- a/src/test/ui/error-codes/E0029-teach.rs +++ b/src/test/ui/error-codes/E0029-teach.rs @@ -16,7 +16,6 @@ fn main() { match s { "hello" ... "world" => {} //~^ ERROR only char and numeric types are allowed in range patterns - //~| ERROR non-reference pattern used to match a reference _ => {} } } diff --git a/src/test/ui/error-codes/E0029-teach.stderr b/src/test/ui/error-codes/E0029-teach.stderr index 25d95108f963..4bb71f68a98b 100644 --- a/src/test/ui/error-codes/E0029-teach.stderr +++ b/src/test/ui/error-codes/E0029-teach.stderr @@ -1,11 +1,3 @@ -error[E0658]: non-reference pattern used to match a reference (see issue #42640) - --> $DIR/E0029-teach.rs:17:9 - | -LL | "hello" ... "world" => {} - | ^^^^^^^^^^^^^^^^^^^ help: consider using a reference: `&"hello" ... "world"` - | - = help: add #![feature(match_default_bindings)] to the crate attributes to enable - error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/E0029-teach.rs:17:9 | @@ -16,7 +8,6 @@ LL | "hello" ... "world" => {} = note: end type: &'static str = note: In a match expression, only numbers and characters can be matched against a range. This is because the compiler checks that the range is non-empty at compile-time, and is unable to evaluate arbitrary comparison functions. If you want to capture values of an orderable type between two end-points, you can use a guard. -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0029, E0658. -For more information about an error, try `rustc --explain E0029`. +For more information about this error, try `rustc --explain E0029`. diff --git a/src/test/ui/error-codes/E0029.rs b/src/test/ui/error-codes/E0029.rs index 80d215bd327c..29b6fe441135 100644 --- a/src/test/ui/error-codes/E0029.rs +++ b/src/test/ui/error-codes/E0029.rs @@ -14,7 +14,6 @@ fn main() { match s { "hello" ... "world" => {} //~^ ERROR only char and numeric types are allowed in range patterns - //~| ERROR non-reference pattern used to match a reference _ => {} } } diff --git a/src/test/ui/error-codes/E0029.stderr b/src/test/ui/error-codes/E0029.stderr index 53c228c6e38c..bcdfa3871110 100644 --- a/src/test/ui/error-codes/E0029.stderr +++ b/src/test/ui/error-codes/E0029.stderr @@ -1,11 +1,3 @@ -error[E0658]: non-reference pattern used to match a reference (see issue #42640) - --> $DIR/E0029.rs:15:9 - | -LL | "hello" ... "world" => {} - | ^^^^^^^^^^^^^^^^^^^ help: consider using a reference: `&"hello" ... "world"` - | - = help: add #![feature(match_default_bindings)] to the crate attributes to enable - error[E0029]: only char and numeric types are allowed in range patterns --> $DIR/E0029.rs:15:9 | @@ -15,7 +7,6 @@ LL | "hello" ... "world" => {} = note: start type: &'static str = note: end type: &'static str -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0029, E0658. -For more information about an error, try `rustc --explain E0029`. +For more information about this error, try `rustc --explain E0029`. diff --git a/src/test/ui/feature-gate-match_default_bindings.rs b/src/test/ui/feature-gate-match_default_bindings.rs deleted file mode 100644 index 4ee2c1e2936a..000000000000 --- a/src/test/ui/feature-gate-match_default_bindings.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -pub fn main() { - match &Some(3) { - Some(n) => {}, - //~^ ERROR non-reference pattern used to match a reference - _ => panic!(), - } -} diff --git a/src/test/ui/feature-gate-match_default_bindings.stderr b/src/test/ui/feature-gate-match_default_bindings.stderr deleted file mode 100644 index 8fa553561de2..000000000000 --- a/src/test/ui/feature-gate-match_default_bindings.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: non-reference pattern used to match a reference (see issue #42640) - --> $DIR/feature-gate-match_default_bindings.rs:13:9 - | -LL | Some(n) => {}, - | ^^^^^^^ help: consider using a reference: `&Some(n)` - | - = help: add #![feature(match_default_bindings)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/pat-slice-old-style.rs b/src/test/ui/pat-slice-old-style.rs deleted file mode 100644 index 65578e76d6d6..000000000000 --- a/src/test/ui/pat-slice-old-style.rs +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -// NB: this test was introduced in #23121 and will have to change when default match binding modes -// stabilizes. - -#![feature(slice_patterns)] - -fn slice_pat(x: &[u8]) { - // OLD! - match x { - [a, b..] => {}, - //~^ ERROR non-reference pattern used to match a reference - _ => panic!(), - } -} - -fn main() { - slice_pat("foo".as_bytes()); -} diff --git a/src/test/ui/pat-slice-old-style.stderr b/src/test/ui/pat-slice-old-style.stderr deleted file mode 100644 index 6fa5b18a14e8..000000000000 --- a/src/test/ui/pat-slice-old-style.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: non-reference pattern used to match a reference (see issue #42640) - --> $DIR/pat-slice-old-style.rs:19:9 - | -LL | [a, b..] => {}, - | ^^^^^^^^ help: consider using a reference: `&[a, b..]` - | - = help: add #![feature(match_default_bindings)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.rs b/src/test/ui/rfc-2005-default-binding-mode/const.rs index fca99f064a27..f80e47507ff0 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/const.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/const.rs @@ -10,8 +10,6 @@ // FIXME(tschottdorf): this test should pass. -#![feature(match_default_bindings)] - #[derive(PartialEq, Eq)] struct Foo { bar: i32, diff --git a/src/test/ui/rfc-2005-default-binding-mode/const.stderr b/src/test/ui/rfc-2005-default-binding-mode/const.stderr index 302b3a8dbc32..4849c39a5d09 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/const.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/const.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/const.rs:26:9 + --> $DIR/const.rs:24:9 | LL | FOO => {}, //~ ERROR mismatched types | ^^^ expected &Foo, found struct `Foo` diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.rs b/src/test/ui/rfc-2005-default-binding-mode/enum.rs index 76ea64e248ef..a108653f85d2 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/enum.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/enum.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - enum Wrapper { Wrap(i32), } diff --git a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr index 18cd0774667c..a7f3b507508e 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/enum.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/enum.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to immutable borrowed content `*x` - --> $DIR/enum.rs:21:5 + --> $DIR/enum.rs:19:5 | LL | let Wrap(x) = &Wrap(3); | - consider changing this to `x` @@ -7,7 +7,7 @@ LL | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*x` - --> $DIR/enum.rs:25:9 + --> $DIR/enum.rs:23:9 | LL | if let Some(x) = &Some(3) { | - consider changing this to `x` @@ -15,7 +15,7 @@ LL | *x += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*x` - --> $DIR/enum.rs:31:9 + --> $DIR/enum.rs:29:9 | LL | while let Some(x) = &Some(3) { | - consider changing this to `x` diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs index 2e43d9722a90..8001d980174e 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - // Verify the binding mode shifts - only when no `&` are auto-dereferenced is the // final default binding mode mutable. diff --git a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr index 392efecb9cd1..f2b9bde41ab3 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/explicit-mut.stderr @@ -1,5 +1,5 @@ error[E0594]: cannot assign to immutable borrowed content `*n` - --> $DIR/explicit-mut.rs:19:13 + --> $DIR/explicit-mut.rs:17:13 | LL | Some(n) => { | - consider changing this to `n` @@ -7,7 +7,7 @@ LL | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*n` - --> $DIR/explicit-mut.rs:27:13 + --> $DIR/explicit-mut.rs:25:13 | LL | Some(n) => { | - consider changing this to `n` @@ -15,7 +15,7 @@ LL | *n += 1; //~ ERROR cannot assign to immutable | ^^^^^^^ cannot borrow as mutable error[E0594]: cannot assign to immutable borrowed content `*n` - --> $DIR/explicit-mut.rs:35:13 + --> $DIR/explicit-mut.rs:33:13 | LL | Some(n) => { | - consider changing this to `n` diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.rs b/src/test/ui/rfc-2005-default-binding-mode/for.rs index e9004c13a0e2..a354d2216a9c 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/for.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - struct Foo {} pub fn main() { diff --git a/src/test/ui/rfc-2005-default-binding-mode/for.stderr b/src/test/ui/rfc-2005-default-binding-mode/for.stderr index 4094c185063e..dbd4bd5dbec4 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/for.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/for.stderr @@ -1,5 +1,5 @@ error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/for.rs:18:13 + --> $DIR/for.rs:16:13 | LL | for (n, mut m) in &tups { | - ^^^^^ by-move pattern here diff --git a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs index 9fbcf5d68b6f..4f4c2a149a7d 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - // FIXME(tschottdorf): This should compile. See #44912. pub fn main() { diff --git a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr index 154fa79fa3f3..04fa3708ffb7 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/issue-44912-or.stderr @@ -1,5 +1,5 @@ error[E0409]: variable `x` is bound in inconsistent ways within the same match arm - --> $DIR/issue-44912-or.rs:18:35 + --> $DIR/issue-44912-or.rs:16:35 | LL | Some((x, 3)) | &Some((ref x, 5)) => x, | - first binding ^ bound in different ways diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.rs b/src/test/ui/rfc-2005-default-binding-mode/lit.rs index 783287fd458b..209f58453461 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/lit.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/lit.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] - // FIXME(tschottdorf): we want these to compile, but they don't. fn with_str() { diff --git a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr index dde1f2d352c7..d5c230bc8de5 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/lit.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/lit.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/lit.rs:19:13 + --> $DIR/lit.rs:17:13 | LL | "abc" => true, //~ ERROR mismatched types | ^^^^^ expected &str, found str @@ -8,7 +8,7 @@ LL | "abc" => true, //~ ERROR mismatched types found type `&'static str` error[E0308]: mismatched types - --> $DIR/lit.rs:28:9 + --> $DIR/lit.rs:26:9 | LL | b"abc" => true, //~ ERROR mismatched types | ^^^^^^ expected &[u8], found array of 3 elements diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs index 20ef0624bf91..fbe4dfe21619 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(match_default_bindings)] #![feature(slice_patterns)] pub fn main() { diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr index c0127e5990e9..18dc6b2869ab 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `&[]` not covered - --> $DIR/slice.rs:17:11 + --> $DIR/slice.rs:16:11 | LL | match sl { //~ ERROR non-exhaustive patterns | ^^ pattern `&[]` not covered diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs b/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs deleted file mode 100644 index b9b974ff3c52..000000000000 --- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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() { - if let Some(y) = &Some(22) { //~ ERROR non-reference pattern - println!("{}", y); - } -} diff --git a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr b/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr deleted file mode 100644 index ea58c62fc847..000000000000 --- a/src/test/ui/rfc-2005-default-binding-mode/suggestion.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: non-reference pattern used to match a reference (see issue #42640) - --> $DIR/suggestion.rs:12:12 - | -LL | if let Some(y) = &Some(22) { //~ ERROR non-reference pattern - | ^^^^^^^ help: consider using a reference: `&Some(y)` - | - = help: add #![feature(match_default_bindings)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs deleted file mode 100644 index 0a2e7ef32260..000000000000 --- a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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 foo(s: &str) -> bool { true } - -fn main() { - let x = vec![(String::new(), String::new())]; - x.iter() - .filter(|&(ref a, _)| foo(a)) - //~^ ERROR non-reference pattern used to match a reference - .collect(); -} diff --git a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr b/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr deleted file mode 100644 index 4e2a321ffac0..000000000000 --- a/src/test/ui/suggestions/dont-suggest-dereference-on-arg.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: non-reference pattern used to match a reference (see issue #42640) - --> $DIR/dont-suggest-dereference-on-arg.rs:16:18 - | -LL | .filter(|&(ref a, _)| foo(a)) - | ^^^^^^^^^^^ help: consider using a reference: `&&(ref a, _)` - | - = help: add #![feature(match_default_bindings)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/tools/rustfmt b/src/tools/rustfmt index 374dba833e22..a4462d18bf6b 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit 374dba833e22cc8df8e16e19cccbde61c69d9aed +Subproject commit a4462d18bf6b92aaec1eeb1c30d5ddf94a3ca987 From 8ecbec1dba048bf55461dbff772f18a72311ecc2 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Wed, 28 Mar 2018 18:47:16 +0900 Subject: [PATCH 692/830] Use mprotect instead of mmap --- src/libstd/sys/unix/thread.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 6064b55489ef..775289f393b0 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -355,10 +355,9 @@ pub mod guard { // macOS. Instead, just restore the page to a writable state. // This ain't Linux, so we probably don't need to care about // execstack. - let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); + let result = mprotect(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE); - if result != stackaddr || result == MAP_FAILED { + if result != 0 { panic!("unable to reset the guard page"); } } From 50ca86be2438369dd1263c619a3bac21bd30a37f Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Wed, 28 Mar 2018 18:51:25 +0900 Subject: [PATCH 693/830] Set link args for rustdoc --- src/rustc/rustc.rs | 1 + src/tools/rustdoc/main.rs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/rustc/rustc.rs b/src/rustc/rustc.rs index bd36aaf01f86..9fa33f911a16 100644 --- a/src/rustc/rustc.rs +++ b/src/rustc/rustc.rs @@ -17,6 +17,7 @@ // We only build for msvc and gnu now, but we use a exhaustive condition here // so we can expect either the stack size to be set or the build fails. #[cfg_attr(all(windows, not(target_env = "msvc")), link_args = "-Wl,--stack,16777216")] +// Also, don't forget to set this for rustdoc. extern {} extern crate rustc_driver; diff --git a/src/tools/rustdoc/main.rs b/src/tools/rustdoc/main.rs index 9c37e249ba8c..e726dea84f10 100644 --- a/src/tools/rustdoc/main.rs +++ b/src/tools/rustdoc/main.rs @@ -8,6 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(link_args)] +// Set the stack size at link time on Windows. See rustc_driver::in_rustc_thread +// for the rationale. +#[cfg_attr(all(windows, target_env = "msvc"), link_args = "/STACK:16777216")] +// We only build for msvc and gnu now, but we use a exhaustive condition here +// so we can expect either the stack size to be set or the build fails. +#[cfg_attr(all(windows, not(target_env = "msvc")), link_args = "-Wl,--stack,16777216")] +// See src/rustc/rustc.rs for the corresponding rustc settings. +extern {} + extern crate rustdoc; fn main() { rustdoc::main() } From 347cf21290c80c528363cc33d9cade6cd1e77888 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 28 Mar 2018 12:03:28 +0200 Subject: [PATCH 694/830] Remove adjacent all-const match arm hack. An old fix for moves-in-guards had a hack for adjacent all-const match arms. The hack was explained in a comment, which you can see here: https://github.com/rust-lang/rust/pull/22580/files#diff-402a0fa4b3c6755c5650027c6d4cf1efR497 But hack was incomplete (and thus unsound), as pointed out here: https://github.com/rust-lang/rust/issues/47295#issuecomment-357108458 Plus, it is likely to be at least tricky to reimplement this hack in the new NLL borrowck. So rather than try to preserve the hack, we want to try to just remove it outright. (At least to see the results of a crater run.) [breaking-change] This is a breaking-change, but our hope is that no one is actually relying on such an extreme special case. (We hypothesize the hack was originally added to accommodate a file in our own test suite, not code in the wild.) --- src/librustc/cfg/construct.rs | 42 ++++--------------- .../move-guard-same-consts.rs} | 12 +++++- 2 files changed, 18 insertions(+), 36 deletions(-) rename src/test/{run-pass/move-guard-const.rs => compile-fail/move-guard-same-consts.rs} (53%) diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index ff2c36416bfd..1247db55f585 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -473,8 +473,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { // Keep track of the previous guard expressions let mut prev_guards = Vec::new(); - // Track if the previous pattern contained bindings or wildcards - let mut prev_has_bindings = false; for arm in arms { // Add an exit node for when we've visited all the @@ -493,40 +491,16 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { // Visit the guard expression let guard_exit = self.expr(&guard, guard_start); - let this_has_bindings = pat.contains_bindings_or_wild(); - - // If both this pattern and the previous pattern - // were free of bindings, they must consist only - // of "constant" patterns. Note we cannot match an - // all-constant pattern, fail the guard, and then - // match *another* all-constant pattern. This is - // because if the previous pattern matches, then - // we *cannot* match this one, unless all the - // constants are the same (which is rejected by - // `check_match`). - // - // We can use this to be smarter about the flow - // along guards. If the previous pattern matched, - // then we know we will not visit the guard in - // this one (whether or not the guard succeeded), - // if the previous pattern failed, then we know - // the guard for that pattern will not have been - // visited. Thus, it is not possible to visit both - // the previous guard and the current one when - // both patterns consist only of constant - // sub-patterns. - // - // However, if the above does not hold, then all - // previous guards need to be wired to visit the - // current guard pattern. - if prev_has_bindings || this_has_bindings { - while let Some(prev) = prev_guards.pop() { - self.add_contained_edge(prev, guard_start); - } + // #47295: We used to have very special case code + // here for when a pair of arms are both formed + // solely from constants, and if so, not add these + // edges. But this was not actually sound without + // other constraints that we stopped enforcing at + // some point. + while let Some(prev) = prev_guards.pop() { + self.add_contained_edge(prev, guard_start); } - prev_has_bindings = this_has_bindings; - // Push the guard onto the list of previous guards prev_guards.push(guard_exit); diff --git a/src/test/run-pass/move-guard-const.rs b/src/test/compile-fail/move-guard-same-consts.rs similarity index 53% rename from src/test/run-pass/move-guard-const.rs rename to src/test/compile-fail/move-guard-same-consts.rs index 6e49538e98a3..05fe48e0199d 100644 --- a/src/test/run-pass/move-guard-const.rs +++ b/src/test/compile-fail/move-guard-same-consts.rs @@ -8,7 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pretty-expanded FIXME #23616 +// #47295: We used to have a hack of special-casing adjacent amtch +// arms whose patterns were composed solely of constants to not have +// them linked in the cfg. +// +// THis was broken for various reasons. In particular, that hack was +// originally authored under the assunption that other checks +// elsewhere would ensure that the two patterns did not overlap. But +// that assumption did not hold, at least not in the long run (namely, +// overlapping patterns were turned into warnings rather than errors). #![feature(box_syntax)] @@ -18,8 +26,8 @@ fn main() { let v = (1, 2); match v { - (2, 1) if take(x) => (), (1, 2) if take(x) => (), + (1, 2) if take(x) => (), //~ ERROR use of moved value: `x` _ => (), } } From 1f143bc46fe04aa564736b4741a8f179c46eccc5 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 28 Mar 2018 11:25:52 +0200 Subject: [PATCH 695/830] Explicitly mention `Option` in `?` error message. Save users the time/effort of having to lookup what types implement the `Try` trait. --- src/libcore/ops/try.rs | 2 +- src/test/ui/suggestions/try-on-option.stderr | 2 +- src/test/ui/suggestions/try-operator-on-main.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/ops/try.rs b/src/libcore/ops/try.rs index 81e5cb5c3504..ef6a8fb6a61c 100644 --- a/src/libcore/ops/try.rs +++ b/src/libcore/ops/try.rs @@ -20,7 +20,7 @@ any(from_method="from_error", from_method="from_ok"), from_desugaring="?"), message="the `?` operator can only be used in a \ - function that returns `Result` \ + function that returns `Result` or `Option` \ (or another type that implements `{Try}`)", label="cannot use the `?` operator in a function that returns `{Self}`"), on(all(from_method="into_result", from_desugaring="?"), diff --git a/src/test/ui/suggestions/try-on-option.stderr b/src/test/ui/suggestions/try-on-option.stderr index aee52808f1e2..265ee593bb70 100644 --- a/src/test/ui/suggestions/try-on-option.stderr +++ b/src/test/ui/suggestions/try-on-option.stderr @@ -6,7 +6,7 @@ LL | x?; //~ the trait bound | = note: required by `std::convert::From::from` -error[E0277]: the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`) +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`) --> $DIR/try-on-option.rs:23:5 | LL | x?; //~ the `?` operator diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr index 7536bbcd2db3..121ae14f999c 100644 --- a/src/test/ui/suggestions/try-operator-on-main.stderr +++ b/src/test/ui/suggestions/try-operator-on-main.stderr @@ -1,4 +1,4 @@ -error[E0277]: the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`) +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`) --> $DIR/try-operator-on-main.rs:19:5 | LL | std::fs::File::open("foo")?; //~ ERROR the `?` operator can only From e9dcec070d6097e5a22b6658844dccd9d1f578cf Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 24 Mar 2018 22:56:07 -0400 Subject: [PATCH 696/830] Remove hidden `foo` functions from doc examples; use `Termination` trait. Fixes https://github.com/rust-lang/rust/issues/49233. --- src/libstd/env.rs | 14 +- src/libstd/fs.rs | 526 ++++++++++++++------------- src/libstd/io/buffered.rs | 223 ++++++------ src/libstd/io/mod.rs | 605 +++++++++++++++---------------- src/libstd/io/stdio.rs | 106 +++--- src/libstd/io/util.rs | 15 +- src/libstd/net/mod.rs | 10 +- src/libstd/net/tcp.rs | 16 +- src/libstd/net/udp.rs | 28 +- src/libstd/os/linux/fs.rs | 238 ++++++------ src/libstd/sys/redox/ext/fs.rs | 38 +- src/libstd/sys/unix/ext/fs.rs | 340 ++++++++--------- src/libstd/sys/windows/ext/fs.rs | 96 ++--- 13 files changed, 1129 insertions(+), 1126 deletions(-) diff --git a/src/libstd/env.rs b/src/libstd/env.rs index c4946b6b2824..320a9f935d45 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -552,17 +552,17 @@ pub fn home_dir() -> Option { /// /// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx /// -/// ``` +/// ```no_run /// use std::env; /// use std::fs::File; /// -/// # fn foo() -> std::io::Result<()> { -/// let mut dir = env::temp_dir(); -/// dir.push("foo.txt"); +/// fn main() -> std::io::Result<()> { +/// let mut dir = env::temp_dir(); +/// dir.push("foo.txt"); /// -/// let f = File::create(dir)?; -/// # Ok(()) -/// # } +/// let f = File::create(dir)?; +/// Ok(()) +/// } /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn temp_dir() -> PathBuf { diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index db52ed67d3a8..46d164e31ba4 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -41,11 +41,11 @@ use time::SystemTime; /// use std::fs::File; /// use std::io::prelude::*; /// -/// # fn foo() -> std::io::Result<()> { -/// let mut file = File::create("foo.txt")?; -/// file.write_all(b"Hello, world!")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let mut file = File::create("foo.txt")?; +/// file.write_all(b"Hello, world!")?; +/// Ok(()) +/// } /// ``` /// /// Read the contents of a file into a [`String`]: @@ -54,13 +54,13 @@ use time::SystemTime; /// use std::fs::File; /// use std::io::prelude::*; /// -/// # fn foo() -> std::io::Result<()> { -/// let mut file = File::open("foo.txt")?; -/// let mut contents = String::new(); -/// file.read_to_string(&mut contents)?; -/// assert_eq!(contents, "Hello, world!"); -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let mut file = File::open("foo.txt")?; +/// let mut contents = String::new(); +/// file.read_to_string(&mut contents)?; +/// assert_eq!(contents, "Hello, world!"); +/// Ok(()) +/// } /// ``` /// /// It can be more efficient to read the contents of a file with a buffered @@ -71,14 +71,14 @@ use time::SystemTime; /// use std::io::BufReader; /// use std::io::prelude::*; /// -/// # fn foo() -> std::io::Result<()> { -/// let file = File::open("foo.txt")?; -/// let mut buf_reader = BufReader::new(file); -/// let mut contents = String::new(); -/// buf_reader.read_to_string(&mut contents)?; -/// assert_eq!(contents, "Hello, world!"); -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let file = File::open("foo.txt")?; +/// let mut buf_reader = BufReader::new(file); +/// let mut contents = String::new(); +/// buf_reader.read_to_string(&mut contents)?; +/// assert_eq!(contents, "Hello, world!"); +/// Ok(()) +/// } /// ``` /// /// Note that, although read and write methods require a `&mut File`, because @@ -256,10 +256,10 @@ fn initial_buffer_size(file: &File) -> usize { /// use std::fs; /// use std::net::SocketAddr; /// -/// # fn foo() -> Result<(), Box> { -/// let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?; -/// # Ok(()) -/// # } +/// fn main() -> Result<(), Box> { +/// let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?; +/// Ok(()) +/// } /// ``` #[unstable(feature = "fs_read_write", issue = "46588")] pub fn read>(path: P) -> io::Result> { @@ -298,10 +298,10 @@ pub fn read>(path: P) -> io::Result> { /// use std::fs; /// use std::net::SocketAddr; /// -/// # fn foo() -> Result<(), Box> { -/// let foo: SocketAddr = fs::read_string("address.txt")?.parse()?; -/// # Ok(()) -/// # } +/// fn main() -> Result<(), Box> { +/// let foo: SocketAddr = fs::read_string("address.txt")?.parse()?; +/// Ok(()) +/// } /// ``` #[unstable(feature = "fs_read_write", issue = "46588")] pub fn read_string>(path: P) -> io::Result { @@ -329,10 +329,10 @@ pub fn read_string>(path: P) -> io::Result { /// /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::write("foo.txt", b"Lorem ipsum")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::write("foo.txt", b"Lorem ipsum")?; +/// Ok(()) +/// } /// ``` #[unstable(feature = "fs_read_write", issue = "46588")] pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> { @@ -356,7 +356,7 @@ impl File { /// ```no_run /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { + /// fn main() -> std::io::Result<()> { /// let mut f = File::open("foo.txt")?; /// # Ok(()) /// # } @@ -380,10 +380,10 @@ impl File { /// ```no_run /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut f = File::create("foo.txt")?; - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let mut f = File::create("foo.txt")?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn create>(path: P) -> io::Result { @@ -401,13 +401,13 @@ impl File { /// use std::fs::File; /// use std::io::prelude::*; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut f = File::create("foo.txt")?; - /// f.write_all(b"Hello, world!")?; + /// fn main() -> std::io::Result<()> { + /// let mut f = File::create("foo.txt")?; + /// f.write_all(b"Hello, world!")?; /// - /// f.sync_all()?; - /// # Ok(()) - /// # } + /// f.sync_all()?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_all(&self) -> io::Result<()> { @@ -432,13 +432,13 @@ impl File { /// use std::fs::File; /// use std::io::prelude::*; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut f = File::create("foo.txt")?; - /// f.write_all(b"Hello, world!")?; + /// fn main() -> std::io::Result<()> { + /// let mut f = File::create("foo.txt")?; + /// f.write_all(b"Hello, world!")?; /// - /// f.sync_data()?; - /// # Ok(()) - /// # } + /// f.sync_data()?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_data(&self) -> io::Result<()> { @@ -466,11 +466,11 @@ impl File { /// ```no_run /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut f = File::create("foo.txt")?; - /// f.set_len(10)?; - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let mut f = File::create("foo.txt")?; + /// f.set_len(10)?; + /// Ok(()) + /// } /// ``` /// /// Note that this method alters the content of the underlying file, even @@ -487,11 +487,11 @@ impl File { /// ```no_run /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// let metadata = f.metadata()?; - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let mut f = File::open("foo.txt")?; + /// let metadata = f.metadata()?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn metadata(&self) -> io::Result { @@ -509,11 +509,11 @@ impl File { /// ```no_run /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut file = File::open("foo.txt")?; - /// let file_copy = file.try_clone()?; - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let file_copy = file.try_clone()?; + /// Ok(()) + /// } /// ``` /// /// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create @@ -525,17 +525,17 @@ impl File { /// use std::io::SeekFrom; /// use std::io::prelude::*; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut file = File::open("foo.txt")?; - /// let mut file_copy = file.try_clone()?; + /// fn main() -> std::io::Result<()> { + /// let mut file = File::open("foo.txt")?; + /// let mut file_copy = file.try_clone()?; /// - /// file.seek(SeekFrom::Start(3))?; + /// file.seek(SeekFrom::Start(3))?; /// - /// let mut contents = vec![]; - /// file_copy.read_to_end(&mut contents)?; - /// assert_eq!(contents, b"def\n"); - /// # Ok(()) - /// # } + /// let mut contents = vec![]; + /// file_copy.read_to_end(&mut contents)?; + /// assert_eq!(contents, b"def\n"); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_try_clone", since = "1.9.0")] pub fn try_clone(&self) -> io::Result { @@ -562,16 +562,16 @@ impl File { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { - /// use std::fs::File; + /// ```no_run + /// fn main() -> std::io::Result<()> { + /// use std::fs::File; /// - /// let file = File::open("foo.txt")?; - /// let mut perms = file.metadata()?.permissions(); - /// perms.set_readonly(true); - /// file.set_permissions(perms)?; - /// # Ok(()) - /// # } + /// let file = File::open("foo.txt")?; + /// let mut perms = file.metadata()?.permissions(); + /// perms.set_readonly(true); + /// file.set_permissions(perms)?; + /// Ok(()) + /// } /// ``` /// /// Note that this method alters the permissions of the underlying file, @@ -891,15 +891,15 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { - /// use std::fs; + /// ```no_run + /// fn main() -> std::io::Result<()> { + /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// let metadata = fs::metadata("foo.txt")?; /// - /// println!("{:?}", metadata.file_type()); - /// # Ok(()) - /// # } + /// println!("{:?}", metadata.file_type()); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn file_type(&self) -> FileType { @@ -910,15 +910,15 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { - /// use std::fs; + /// ```no_run + /// fn main() -> std::io::Result<()> { + /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// let metadata = fs::metadata("foo.txt")?; /// - /// assert!(!metadata.is_dir()); - /// # Ok(()) - /// # } + /// assert!(!metadata.is_dir()); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn is_dir(&self) -> bool { self.file_type().is_dir() } @@ -927,15 +927,15 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { + /// ```no_run /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; /// - /// assert!(metadata.is_file()); - /// # Ok(()) - /// # } + /// assert!(metadata.is_file()); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn is_file(&self) -> bool { self.file_type().is_file() } @@ -944,15 +944,15 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { + /// ```no_run /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; /// - /// assert_eq!(0, metadata.len()); - /// # Ok(()) - /// # } + /// assert_eq!(0, metadata.len()); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> u64 { self.0.size() } @@ -961,15 +961,15 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { + /// ```no_run /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; /// - /// assert!(!metadata.permissions().readonly()); - /// # Ok(()) - /// # } + /// assert!(!metadata.permissions().readonly()); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn permissions(&self) -> Permissions { @@ -988,19 +988,19 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { + /// ```no_run /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; /// - /// if let Ok(time) = metadata.modified() { - /// println!("{:?}", time); - /// } else { - /// println!("Not supported on this platform"); + /// if let Ok(time) = metadata.modified() { + /// println!("{:?}", time); + /// } else { + /// println!("Not supported on this platform"); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` #[stable(feature = "fs_time", since = "1.10.0")] pub fn modified(&self) -> io::Result { @@ -1023,19 +1023,19 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { + /// ```no_run /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; /// - /// if let Ok(time) = metadata.accessed() { - /// println!("{:?}", time); - /// } else { - /// println!("Not supported on this platform"); + /// if let Ok(time) = metadata.accessed() { + /// println!("{:?}", time); + /// } else { + /// println!("Not supported on this platform"); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` #[stable(feature = "fs_time", since = "1.10.0")] pub fn accessed(&self) -> io::Result { @@ -1054,19 +1054,19 @@ impl Metadata { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { + /// ```no_run /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; /// - /// if let Ok(time) = metadata.created() { - /// println!("{:?}", time); - /// } else { - /// println!("Not supported on this platform"); + /// if let Ok(time) = metadata.created() { + /// println!("{:?}", time); + /// } else { + /// println!("Not supported on this platform"); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` #[stable(feature = "fs_time", since = "1.10.0")] pub fn created(&self) -> io::Result { @@ -1098,16 +1098,16 @@ impl Permissions { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; + /// fn main() -> std::io::Result<()> { + /// let mut f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; /// - /// assert_eq!(false, metadata.permissions().readonly()); - /// # Ok(()) - /// # } + /// assert_eq!(false, metadata.permissions().readonly()); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn readonly(&self) -> bool { self.0.readonly() } @@ -1123,23 +1123,23 @@ impl Permissions { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let mut permissions = metadata.permissions(); + /// fn main() -> std::io::Result<()> { + /// let f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; + /// let mut permissions = metadata.permissions(); /// - /// permissions.set_readonly(true); + /// permissions.set_readonly(true); /// - /// // filesystem doesn't change - /// assert_eq!(false, metadata.permissions().readonly()); + /// // filesystem doesn't change + /// assert_eq!(false, metadata.permissions().readonly()); /// - /// // just this particular `permissions`. - /// assert_eq!(true, permissions.readonly()); - /// # Ok(()) - /// # } + /// // just this particular `permissions`. + /// assert_eq!(true, permissions.readonly()); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn set_readonly(&mut self, readonly: bool) { @@ -1152,16 +1152,16 @@ impl FileType { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { - /// use std::fs; + /// ```no_run + /// fn main() -> std::io::Result<()> { + /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; - /// let file_type = metadata.file_type(); + /// let metadata = fs::metadata("foo.txt")?; + /// let file_type = metadata.file_type(); /// - /// assert_eq!(file_type.is_dir(), false); - /// # Ok(()) - /// # } + /// assert_eq!(file_type.is_dir(), false); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_dir(&self) -> bool { self.0.is_dir() } @@ -1170,16 +1170,16 @@ impl FileType { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { - /// use std::fs; + /// ```no_run + /// fn main() -> std::io::Result<()> { + /// use std::fs; /// - /// let metadata = fs::metadata("foo.txt")?; - /// let file_type = metadata.file_type(); + /// let metadata = fs::metadata("foo.txt")?; + /// let file_type = metadata.file_type(); /// - /// assert_eq!(file_type.is_file(), true); - /// # Ok(()) - /// # } + /// assert_eq!(file_type.is_file(), true); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_file(&self) -> bool { self.0.is_file() } @@ -1199,16 +1199,16 @@ impl FileType { /// /// # Examples /// - /// ``` - /// # fn foo() -> std::io::Result<()> { + /// ```no_run /// use std::fs; /// - /// let metadata = fs::symlink_metadata("foo.txt")?; - /// let file_type = metadata.file_type(); + /// fn main() -> std::io::Result<()> { + /// let metadata = fs::symlink_metadata("foo.txt")?; + /// let file_type = metadata.file_type(); /// - /// assert_eq!(file_type.is_symlink(), false); - /// # Ok(()) - /// # } + /// assert_eq!(file_type.is_symlink(), false); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type", since = "1.1.0")] pub fn is_symlink(&self) -> bool { self.0.is_symlink() } @@ -1245,15 +1245,16 @@ impl DirEntry { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; - /// # fn foo() -> std::io::Result<()> { - /// for entry in fs::read_dir(".")? { - /// let dir = entry?; - /// println!("{:?}", dir.path()); + /// + /// fn main() -> std::io::Result<()> { + /// for entry in fs::read_dir(".")? { + /// let dir = entry?; + /// println!("{:?}", dir.path()); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` /// /// This prints output like: @@ -1398,13 +1399,13 @@ impl AsInner for DirEntry { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::remove_file("a.txt")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::remove_file("a.txt")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove_file>(path: P) -> io::Result<()> { @@ -1435,14 +1436,14 @@ pub fn remove_file>(path: P) -> io::Result<()> { /// /// # Examples /// -/// ```rust -/// # fn foo() -> std::io::Result<()> { +/// ```rust,no_run /// use std::fs; /// -/// let attr = fs::metadata("/some/file/path.txt")?; -/// // inspect attr ... -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let attr = fs::metadata("/some/file/path.txt")?; +/// // inspect attr ... +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn metadata>(path: P) -> io::Result { @@ -1469,14 +1470,14 @@ pub fn metadata>(path: P) -> io::Result { /// /// # Examples /// -/// ```rust -/// # fn foo() -> std::io::Result<()> { +/// ```rust,no_run /// use std::fs; /// -/// let attr = fs::symlink_metadata("/some/file/path.txt")?; -/// // inspect attr ... -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let attr = fs::symlink_metadata("/some/file/path.txt")?; +/// // inspect attr ... +/// Ok(()) +/// } /// ``` #[stable(feature = "symlink_metadata", since = "1.1.0")] pub fn symlink_metadata>(path: P) -> io::Result { @@ -1513,13 +1514,13 @@ pub fn symlink_metadata>(path: P) -> io::Result { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::rename("a.txt", "b.txt")?; // Rename a.txt to b.txt -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::rename("a.txt", "b.txt")?; // Rename a.txt to b.txt +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> { @@ -1564,9 +1565,10 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::copy("foo.txt", "bar.txt")?; // Copy foo.txt to bar.txt -/// # Ok(()) } +/// fn main() -> std::io::Result<()> { +/// fs::copy("foo.txt", "bar.txt")?; // Copy foo.txt to bar.txt +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn copy, Q: AsRef>(from: P, to: Q) -> io::Result { @@ -1595,13 +1597,13 @@ pub fn copy, Q: AsRef>(from: P, to: Q) -> io::Result { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::hard_link("a.txt", "b.txt")?; // Hard link a.txt to b.txt -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::hard_link("a.txt", "b.txt")?; // Hard link a.txt to b.txt +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn hard_link, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { @@ -1618,13 +1620,13 @@ pub fn hard_link, Q: AsRef>(src: P, dst: Q) -> io::Result<( /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::soft_link("a.txt", "b.txt")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::soft_link("a.txt", "b.txt")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.1.0", @@ -1655,13 +1657,13 @@ pub fn soft_link, Q: AsRef>(src: P, dst: Q) -> io::Result<( /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// let path = fs::read_link("a.txt")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let path = fs::read_link("a.txt")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn read_link>(path: P) -> io::Result { @@ -1689,13 +1691,13 @@ pub fn read_link>(path: P) -> io::Result { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// let path = fs::canonicalize("../a/../foo.txt")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let path = fs::canonicalize("../a/../foo.txt")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "fs_canonicalize", since = "1.5.0")] pub fn canonicalize>(path: P) -> io::Result { @@ -1722,13 +1724,13 @@ pub fn canonicalize>(path: P) -> io::Result { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::create_dir("/some/dir")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::create_dir("/some/dir")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir>(path: P) -> io::Result<()> { @@ -1764,13 +1766,13 @@ pub fn create_dir>(path: P) -> io::Result<()> { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::create_dir_all("/some/dir")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::create_dir_all("/some/dir")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn create_dir_all>(path: P) -> io::Result<()> { @@ -1797,13 +1799,13 @@ pub fn create_dir_all>(path: P) -> io::Result<()> { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::remove_dir("/some/dir")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::remove_dir("/some/dir")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir>(path: P) -> io::Result<()> { @@ -1831,13 +1833,13 @@ pub fn remove_dir>(path: P) -> io::Result<()> { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::remove_dir_all("/some/dir")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::remove_dir_all("/some/dir")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn remove_dir_all>(path: P) -> io::Result<()> { @@ -1917,15 +1919,15 @@ pub fn read_dir>(path: P) -> io::Result { /// /// # Examples /// -/// ``` -/// # fn foo() -> std::io::Result<()> { +/// ```no_run /// use std::fs; /// -/// let mut perms = fs::metadata("foo.txt")?.permissions(); -/// perms.set_readonly(true); -/// fs::set_permissions("foo.txt", perms)?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// let mut perms = fs::metadata("foo.txt")?.permissions(); +/// perms.set_readonly(true); +/// fs::set_permissions("foo.txt", perms)?; +/// Ok(()) +/// } /// ``` #[stable(feature = "set_permissions", since = "1.1.0")] pub fn set_permissions>(path: P, perm: Permissions) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index ccaa19acc837..cefff2f143ce 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -31,20 +31,20 @@ use memchr; /// /// # Examples /// -/// ``` +/// ```no_run /// use std::io::prelude::*; /// use std::io::BufReader; /// use std::fs::File; /// -/// # fn foo() -> std::io::Result<()> { -/// let f = File::open("log.txt")?; -/// let mut reader = BufReader::new(f); +/// fn main() -> std::io::Result<()> { +/// let f = File::open("log.txt")?; +/// let mut reader = BufReader::new(f); /// -/// let mut line = String::new(); -/// let len = reader.read_line(&mut line)?; -/// println!("First line is {} bytes long", len); -/// # Ok(()) -/// # } +/// let mut line = String::new(); +/// let len = reader.read_line(&mut line)?; +/// println!("First line is {} bytes long", len); +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct BufReader { @@ -59,15 +59,15 @@ impl BufReader { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::BufReader; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f = File::open("log.txt")?; - /// let reader = BufReader::new(f); - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let f = File::open("log.txt")?; + /// let reader = BufReader::new(f); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: R) -> BufReader { @@ -80,15 +80,15 @@ impl BufReader { /// /// Creating a buffer with ten bytes of capacity: /// - /// ``` + /// ```no_run /// use std::io::BufReader; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f = File::open("log.txt")?; - /// let reader = BufReader::with_capacity(10, f); - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let f = File::open("log.txt")?; + /// let reader = BufReader::with_capacity(10, f); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn with_capacity(cap: usize, inner: R) -> BufReader { @@ -111,17 +111,17 @@ impl BufReader { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::BufReader; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f1 = File::open("log.txt")?; - /// let reader = BufReader::new(f1); + /// fn main() -> std::io::Result<()> { + /// let f1 = File::open("log.txt")?; + /// let reader = BufReader::new(f1); /// - /// let f2 = reader.get_ref(); - /// # Ok(()) - /// # } + /// let f2 = reader.get_ref(); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &R { &self.inner } @@ -132,17 +132,17 @@ impl BufReader { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::BufReader; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f1 = File::open("log.txt")?; - /// let mut reader = BufReader::new(f1); + /// fn main() -> std::io::Result<()> { + /// let f1 = File::open("log.txt")?; + /// let mut reader = BufReader::new(f1); /// - /// let f2 = reader.get_mut(); - /// # Ok(()) - /// # } + /// let f2 = reader.get_mut(); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut R { &mut self.inner } @@ -150,22 +150,23 @@ impl BufReader { /// Returns `true` if there are no bytes in the internal buffer. /// /// # Examples - /// ``` + // + /// ```no_run /// # #![feature(bufreader_is_empty)] /// use std::io::BufReader; /// use std::io::BufRead; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f1 = File::open("log.txt")?; - /// let mut reader = BufReader::new(f1); - /// assert!(reader.is_empty()); + /// fn main() -> std::io::Result<()> { + /// let f1 = File::open("log.txt")?; + /// let mut reader = BufReader::new(f1); + /// assert!(reader.is_empty()); /// - /// if reader.fill_buf()?.len() > 0 { - /// assert!(!reader.is_empty()); + /// if reader.fill_buf()?.len() > 0 { + /// assert!(!reader.is_empty()); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` #[unstable(feature = "bufreader_is_empty", issue = "45323", reason = "recently added")] #[rustc_deprecated(since = "1.26.0", reason = "use .buffer().is_empty() instead")] @@ -179,21 +180,21 @@ impl BufReader { /// /// # Examples /// - /// ``` + /// ```no_ru /// # #![feature(bufreader_buffer)] /// use std::io::{BufReader, BufRead}; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f = File::open("log.txt")?; - /// let mut reader = BufReader::new(f); - /// assert!(reader.buffer().is_empty()); + /// fn main() -> std::io::Result<()> { + /// let f = File::open("log.txt")?; + /// let mut reader = BufReader::new(f); + /// assert!(reader.buffer().is_empty()); /// - /// if reader.fill_buf()?.len() > 0 { - /// assert!(!reader.buffer().is_empty()); + /// if reader.fill_buf()?.len() > 0 { + /// assert!(!reader.buffer().is_empty()); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` #[unstable(feature = "bufreader_buffer", issue = "45323")] pub fn buffer(&self) -> &[u8] { @@ -206,17 +207,17 @@ impl BufReader { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::BufReader; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let f1 = File::open("log.txt")?; - /// let reader = BufReader::new(f1); + /// fn main() -> std::io::Result<()> { + /// let f1 = File::open("log.txt")?; + /// let reader = BufReader::new(f1); /// - /// let f2 = reader.into_inner(); - /// # Ok(()) - /// # } + /// let f2 = reader.into_inner(); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> R { self.inner } @@ -724,34 +725,34 @@ impl fmt::Display for IntoInnerError { /// We can use `LineWriter` to write one line at a time, significantly /// reducing the number of actual writes to the file. /// -/// ``` +/// ```no_run /// use std::fs::File; /// use std::io::prelude::*; /// use std::io::LineWriter; /// -/// # fn foo() -> std::io::Result<()> { -/// let road_not_taken = b"I shall be telling this with a sigh +/// fn main() -> std::io::Result<()> { +/// let road_not_taken = b"I shall be telling this with a sigh /// Somewhere ages and ages hence: /// Two roads diverged in a wood, and I - /// I took the one less traveled by, /// And that has made all the difference."; /// -/// let file = File::create("poem.txt")?; -/// let mut file = LineWriter::new(file); +/// let file = File::create("poem.txt")?; +/// let mut file = LineWriter::new(file); /// -/// for &byte in road_not_taken.iter() { -/// file.write(&[byte]).unwrap(); +/// for &byte in road_not_taken.iter() { +/// file.write(&[byte]).unwrap(); +/// } +/// +/// // let's check we did the right thing. +/// let mut file = File::open("poem.txt")?; +/// let mut contents = String::new(); +/// +/// file.read_to_string(&mut contents)?; +/// +/// assert_eq!(contents.as_bytes(), &road_not_taken[..]); +/// Ok(()) /// } -/// -/// // let's check we did the right thing. -/// let mut file = File::open("poem.txt")?; -/// let mut contents = String::new(); -/// -/// file.read_to_string(&mut contents)?; -/// -/// assert_eq!(contents.as_bytes(), &road_not_taken[..]); -/// # Ok(()) -/// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct LineWriter { @@ -764,15 +765,15 @@ impl LineWriter { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// use std::io::LineWriter; /// - /// # fn foo() -> std::io::Result<()> { - /// let file = File::create("poem.txt")?; - /// let file = LineWriter::new(file); - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let file = File::create("poem.txt")?; + /// let file = LineWriter::new(file); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn new(inner: W) -> LineWriter { @@ -785,15 +786,15 @@ impl LineWriter { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// use std::io::LineWriter; /// - /// # fn foo() -> std::io::Result<()> { - /// let file = File::create("poem.txt")?; - /// let file = LineWriter::with_capacity(100, file); - /// # Ok(()) - /// # } + /// fn main() -> std::io::Result<()> { + /// let file = File::create("poem.txt")?; + /// let file = LineWriter::with_capacity(100, file); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn with_capacity(cap: usize, inner: W) -> LineWriter { @@ -807,17 +808,17 @@ impl LineWriter { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// use std::io::LineWriter; /// - /// # fn foo() -> std::io::Result<()> { - /// let file = File::create("poem.txt")?; - /// let file = LineWriter::new(file); + /// fn main() -> std::io::Result<()> { + /// let file = File::create("poem.txt")?; + /// let file = LineWriter::new(file); /// - /// let reference = file.get_ref(); - /// # Ok(()) - /// # } + /// let reference = file.get_ref(); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_ref(&self) -> &W { self.inner.get_ref() } @@ -829,18 +830,18 @@ impl LineWriter { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// use std::io::LineWriter; /// - /// # fn foo() -> std::io::Result<()> { - /// let file = File::create("poem.txt")?; - /// let mut file = LineWriter::new(file); + /// fn main() -> std::io::Result<()> { + /// let file = File::create("poem.txt")?; + /// let mut file = LineWriter::new(file); /// - /// // we can use reference just like file - /// let reference = file.get_mut(); - /// # Ok(()) - /// # } + /// // we can use reference just like file + /// let reference = file.get_mut(); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn get_mut(&mut self) -> &mut W { self.inner.get_mut() } @@ -855,18 +856,18 @@ impl LineWriter { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs::File; /// use std::io::LineWriter; /// - /// # fn foo() -> std::io::Result<()> { - /// let file = File::create("poem.txt")?; + /// fn main() -> std::io::Result<()> { + /// let file = File::create("poem.txt")?; /// - /// let writer: LineWriter = LineWriter::new(file); + /// let writer: LineWriter = LineWriter::new(file); /// - /// let file: File = writer.into_inner()?; - /// # Ok(()) - /// # } + /// let file: File = writer.into_inner()?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn into_inner(self) -> Result>> { diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index d403bf6bfe53..63b631ace969 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -24,21 +24,21 @@ //! example, [`Read`] adds a [`read`][`Read::read`] method, which we can use on //! [`File`]s: //! -//! ``` +//! ```no_run //! use std::io; //! use std::io::prelude::*; //! use std::fs::File; //! -//! # fn foo() -> io::Result<()> { -//! let mut f = File::open("foo.txt")?; -//! let mut buffer = [0; 10]; +//! fn main() -> io::Result<()> { +//! let mut f = File::open("foo.txt")?; +//! let mut buffer = [0; 10]; //! -//! // read up to 10 bytes -//! f.read(&mut buffer)?; +//! // read up to 10 bytes +//! f.read(&mut buffer)?; //! -//! println!("The bytes: {:?}", buffer); -//! # Ok(()) -//! # } +//! println!("The bytes: {:?}", buffer); +//! Ok(()) +//! } //! ``` //! //! [`Read`] and [`Write`] are so important, implementors of the two traits have a @@ -52,25 +52,25 @@ //! how the reading happens. [`Seek`] lets you control where the next byte is //! coming from: //! -//! ``` +//! ```no_run //! use std::io; //! use std::io::prelude::*; //! use std::io::SeekFrom; //! use std::fs::File; //! -//! # fn foo() -> io::Result<()> { -//! let mut f = File::open("foo.txt")?; -//! let mut buffer = [0; 10]; +//! fn main() -> io::Result<()> { +//! let mut f = File::open("foo.txt")?; +//! let mut buffer = [0; 10]; //! -//! // skip to the last 10 bytes of the file -//! f.seek(SeekFrom::End(-10))?; +//! // skip to the last 10 bytes of the file +//! f.seek(SeekFrom::End(-10))?; //! -//! // read up to 10 bytes -//! f.read(&mut buffer)?; +//! // read up to 10 bytes +//! f.read(&mut buffer)?; //! -//! println!("The bytes: {:?}", buffer); -//! # Ok(()) -//! # } +//! println!("The bytes: {:?}", buffer); +//! Ok(()) +//! } //! ``` //! //! [`BufRead`] uses an internal buffer to provide a number of other ways to read, but @@ -87,70 +87,70 @@ //! For example, [`BufReader`] works with the [`BufRead`] trait to add extra //! methods to any reader: //! -//! ``` +//! ```no_run //! use std::io; //! use std::io::prelude::*; //! use std::io::BufReader; //! use std::fs::File; //! -//! # fn foo() -> io::Result<()> { -//! let f = File::open("foo.txt")?; -//! let mut reader = BufReader::new(f); -//! let mut buffer = String::new(); +//! fn main() -> io::Result<()> { +//! let f = File::open("foo.txt")?; +//! let mut reader = BufReader::new(f); +//! let mut buffer = String::new(); //! -//! // read a line into buffer -//! reader.read_line(&mut buffer)?; +//! // read a line into buffer +//! reader.read_line(&mut buffer)?; //! -//! println!("{}", buffer); -//! # Ok(()) -//! # } +//! println!("{}", buffer); +//! Ok(()) +//! } //! ``` //! //! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call //! to [`write`][`Write::write`]: //! -//! ``` +//! ```no_run //! use std::io; //! use std::io::prelude::*; //! use std::io::BufWriter; //! use std::fs::File; //! -//! # fn foo() -> io::Result<()> { -//! let f = File::create("foo.txt")?; -//! { -//! let mut writer = BufWriter::new(f); +//! fn main() -> io::Result<()> { +//! let f = File::create("foo.txt")?; +//! { +//! let mut writer = BufWriter::new(f); //! -//! // write a byte to the buffer -//! writer.write(&[42])?; +//! // write a byte to the buffer +//! writer.write(&[42])?; //! -//! } // the buffer is flushed once writer goes out of scope +//! } // the buffer is flushed once writer goes out of scope //! -//! # Ok(()) -//! # } +//! Ok(()) +//! } //! ``` //! //! ## Standard input and output //! //! A very common source of input is standard input: //! -//! ``` +//! ```no_run //! use std::io; //! -//! # fn foo() -> io::Result<()> { -//! let mut input = String::new(); +//! fn main() -> io::Result<()> { +//! let mut input = String::new(); //! -//! io::stdin().read_line(&mut input)?; +//! io::stdin().read_line(&mut input)?; //! -//! println!("You typed: {}", input.trim()); -//! # Ok(()) -//! # } +//! println!("You typed: {}", input.trim()); +//! Ok(()) +//! } //! ``` //! //! Note that you cannot use the [`?` operator] in functions that do not return //! a [`Result`][`Result`] (e.g. `main`). Instead, you can call [`.unwrap()`] //! or `match` on the return value to catch any possible errors: //! -//! ``` +//! ```no_run //! use std::io; //! //! let mut input = String::new(); @@ -160,14 +160,14 @@ //! //! And a very common source of output is standard output: //! -//! ``` +//! ```no_run //! use std::io; //! use std::io::prelude::*; //! -//! # fn foo() -> io::Result<()> { -//! io::stdout().write(&[42])?; -//! # Ok(()) -//! # } +//! fn main() -> io::Result<()> { +//! io::stdout().write(&[42])?; +//! Ok(()) +//! } //! ``` //! //! Of course, using [`io::stdout`] directly is less common than something like @@ -179,22 +179,21 @@ //! ways of iterating over I/O. For example, [`Lines`] is used to split over //! lines: //! -//! ``` +//! ```no_run //! use std::io; //! use std::io::prelude::*; //! use std::io::BufReader; //! use std::fs::File; //! -//! # fn foo() -> io::Result<()> { -//! let f = File::open("foo.txt")?; -//! let reader = BufReader::new(f); +//! fn main() -> io::Result<()> { +//! let f = File::open("foo.txt")?; +//! let reader = BufReader::new(f); //! -//! for line in reader.lines() { -//! println!("{}", line?); +//! for line in reader.lines() { +//! println!("{}", line?); +//! } +//! Ok(()) //! } -//! -//! # Ok(()) -//! # } //! ``` //! //! ## Functions @@ -203,13 +202,13 @@ //! features. For example, we can use three of these functions to copy everything //! from standard input to standard output: //! -//! ``` +//! ```no_run //! use std::io; //! -//! # fn foo() -> io::Result<()> { -//! io::copy(&mut io::stdin(), &mut io::stdout())?; -//! # Ok(()) -//! # } +//! fn main() -> io::Result<()> { +//! io::copy(&mut io::stdin(), &mut io::stdout())?; +//! Ok(()) +//! } //! ``` //! //! [functions-list]: #functions-1 @@ -416,47 +415,47 @@ fn read_to_end(r: &mut R, buf: &mut Vec) -> Result /// /// [`File`]s implement `Read`: /// -/// ``` -/// # use std::io; +/// ```no_run +/// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// -/// # fn foo() -> io::Result<()> { -/// let mut f = File::open("foo.txt")?; -/// let mut buffer = [0; 10]; +/// fn main() -> io::Result<()> { +/// let mut f = File::open("foo.txt")?; +/// let mut buffer = [0; 10]; /// -/// // read up to 10 bytes -/// f.read(&mut buffer)?; +/// // read up to 10 bytes +/// f.read(&mut buffer)?; /// -/// let mut buffer = vec![0; 10]; -/// // read the whole file -/// f.read_to_end(&mut buffer)?; +/// let mut buffer = vec![0; 10]; +/// // read the whole file +/// f.read_to_end(&mut buffer)?; /// -/// // read into a String, so that you don't need to do the conversion. -/// let mut buffer = String::new(); -/// f.read_to_string(&mut buffer)?; +/// // read into a String, so that you don't need to do the conversion. +/// let mut buffer = String::new(); +/// f.read_to_string(&mut buffer)?; /// -/// // and more! See the other methods for more details. -/// # Ok(()) -/// # } +/// // and more! See the other methods for more details. +/// Ok(()) +/// } /// ``` /// /// Read from [`&str`] because [`&[u8]`][slice] implements `Read`: /// -/// ``` +/// ```no_run /// # use std::io; /// use std::io::prelude::*; /// -/// # fn foo() -> io::Result<()> { -/// let mut b = "This string will be read".as_bytes(); -/// let mut buffer = [0; 10]; +/// fn main() -> io::Result<()> { +/// let mut b = "This string will be read".as_bytes(); +/// let mut buffer = [0; 10]; /// -/// // read up to 10 bytes -/// b.read(&mut buffer)?; +/// // read up to 10 bytes +/// b.read(&mut buffer)?; /// -/// // etc... it works exactly as a File does! -/// # Ok(()) -/// # } +/// // etc... it works exactly as a File does! +/// Ok(()) +/// } /// ``` /// /// [`read()`]: trait.Read.html#tymethod.read @@ -509,19 +508,19 @@ pub trait Read { /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted /// [`File`]: ../fs/struct.File.html /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// let mut buffer = [0; 10]; + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; + /// let mut buffer = [0; 10]; /// - /// // read up to 10 bytes - /// f.read(&mut buffer[..])?; - /// # Ok(()) - /// # } + /// // read up to 10 bytes + /// f.read(&mut buffer[..])?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn read(&mut self, buf: &mut [u8]) -> Result; @@ -582,19 +581,19 @@ pub trait Read { /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted /// [`File`]: ../fs/struct.File.html /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// let mut buffer = Vec::new(); + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; + /// let mut buffer = Vec::new(); /// - /// // read the whole file - /// f.read_to_end(&mut buffer)?; - /// # Ok(()) - /// # } + /// // read the whole file + /// f.read_to_end(&mut buffer)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn read_to_end(&mut self, buf: &mut Vec) -> Result { @@ -621,18 +620,18 @@ pub trait Read { /// /// [file]: ../fs/struct.File.html /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// let mut buffer = String::new(); + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; + /// let mut buffer = String::new(); /// - /// f.read_to_string(&mut buffer)?; - /// # Ok(()) - /// # } + /// f.read_to_string(&mut buffer)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn read_to_string(&mut self, buf: &mut String) -> Result { @@ -683,19 +682,19 @@ pub trait Read { /// [`ErrorKind::Interrupted`]: ../../std/io/enum.ErrorKind.html#variant.Interrupted /// [`ErrorKind::UnexpectedEof`]: ../../std/io/enum.ErrorKind.html#variant.UnexpectedEof /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// let mut buffer = [0; 10]; + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; + /// let mut buffer = [0; 10]; /// - /// // read exactly 10 bytes - /// f.read_exact(&mut buffer)?; - /// # Ok(()) - /// # } + /// // read exactly 10 bytes + /// f.read_exact(&mut buffer)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "read_exact", since = "1.6.0")] fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> { @@ -726,28 +725,28 @@ pub trait Read { /// /// [file]: ../fs/struct.File.html /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::Read; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// let mut buffer = Vec::new(); - /// let mut other_buffer = Vec::new(); + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; + /// let mut buffer = Vec::new(); + /// let mut other_buffer = Vec::new(); /// - /// { - /// let reference = f.by_ref(); + /// { + /// let reference = f.by_ref(); /// - /// // read at most 5 bytes - /// reference.take(5).read_to_end(&mut buffer)?; + /// // read at most 5 bytes + /// reference.take(5).read_to_end(&mut buffer)?; /// - /// } // drop our &mut reference so we can use f again + /// } // drop our &mut reference so we can use f again /// - /// // original file still usable, read the rest - /// f.read_to_end(&mut other_buffer)?; - /// # Ok(()) - /// # } + /// // original file still usable, read the rest + /// f.read_to_end(&mut other_buffer)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self where Self: Sized { self } @@ -772,19 +771,19 @@ pub trait Read { /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// [`None`]: ../../std/option/enum.Option.html#variant.None /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; /// - /// for byte in f.bytes() { - /// println!("{}", byte.unwrap()); + /// for byte in f.bytes() { + /// println!("{}", byte.unwrap()); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn bytes(self) -> Bytes where Self: Sized { @@ -812,20 +811,20 @@ pub trait Read { /// [`char`]: ../../std/primitive.char.html /// [`None`]: ../../std/option/enum.Option.html#variant.None /// - /// ``` + /// ```no_run /// #![feature(io)] /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; /// - /// for c in f.chars() { - /// println!("{}", c.unwrap()); + /// for c in f.chars() { + /// println!("{}", c.unwrap()); + /// } + /// Ok(()) /// } - /// # Ok(()) - /// # } /// ``` #[unstable(feature = "io", reason = "the semantics of a partial read/write \ of where errors happen is currently \ @@ -847,23 +846,23 @@ pub trait Read { /// /// [file]: ../fs/struct.File.html /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f1 = File::open("foo.txt")?; - /// let mut f2 = File::open("bar.txt")?; + /// fn main() -> io::Result<()> { + /// let mut f1 = File::open("foo.txt")?; + /// let mut f2 = File::open("bar.txt")?; /// - /// let mut handle = f1.chain(f2); - /// let mut buffer = String::new(); + /// let mut handle = f1.chain(f2); + /// let mut buffer = String::new(); /// - /// // read the value into a String. We could use any Read method here, - /// // this is just one example. - /// handle.read_to_string(&mut buffer)?; - /// # Ok(()) - /// # } + /// // read the value into a String. We could use any Read method here, + /// // this is just one example. + /// handle.read_to_string(&mut buffer)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn chain(self, next: R) -> Chain where Self: Sized { @@ -885,21 +884,21 @@ pub trait Read { /// [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok /// [`read()`]: trait.Read.html#tymethod.read /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut f = File::open("foo.txt")?; - /// let mut buffer = [0; 5]; + /// fn main() -> io::Result<()> { + /// let mut f = File::open("foo.txt")?; + /// let mut buffer = [0; 5]; /// - /// // read at most five bytes - /// let mut handle = f.take(5); + /// // read at most five bytes + /// let mut handle = f.take(5); /// - /// handle.read(&mut buffer)?; - /// # Ok(()) - /// # } + /// handle.read(&mut buffer)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn take(self, limit: u64) -> Take where Self: Sized { @@ -974,16 +973,16 @@ impl Initializer { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::io::prelude::*; /// use std::fs::File; /// -/// # fn foo() -> std::io::Result<()> { -/// let mut buffer = File::create("foo.txt")?; +/// fn main() -> std::io::Result<()> { +/// let mut buffer = File::create("foo.txt")?; /// -/// buffer.write(b"some bytes")?; -/// # Ok(()) -/// # } +/// buffer.write(b"some bytes")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[doc(spotlight)] @@ -1022,17 +1021,17 @@ pub trait Write { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut buffer = File::create("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let mut buffer = File::create("foo.txt")?; /// - /// // Writes some prefix of the byte string, not necessarily all of it. - /// buffer.write(b"some bytes")?; - /// # Ok(()) - /// # } + /// // Writes some prefix of the byte string, not necessarily all of it. + /// buffer.write(b"some bytes")?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn write(&mut self, buf: &[u8]) -> Result; @@ -1047,18 +1046,18 @@ pub trait Write { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::prelude::*; /// use std::io::BufWriter; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut buffer = BufWriter::new(File::create("foo.txt")?); + /// fn main() -> std::io::Result<()> { + /// let mut buffer = BufWriter::new(File::create("foo.txt")?); /// - /// buffer.write(b"some bytes")?; - /// buffer.flush()?; - /// # Ok(()) - /// # } + /// buffer.write(b"some bytes")?; + /// buffer.flush()?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn flush(&mut self) -> Result<()>; @@ -1082,16 +1081,16 @@ pub trait Write { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut buffer = File::create("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let mut buffer = File::create("foo.txt")?; /// - /// buffer.write_all(b"some bytes")?; - /// # Ok(()) - /// # } + /// buffer.write_all(b"some bytes")?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn write_all(&mut self, mut buf: &[u8]) -> Result<()> { @@ -1131,19 +1130,19 @@ pub trait Write { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut buffer = File::create("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let mut buffer = File::create("foo.txt")?; /// - /// // this call - /// write!(buffer, "{:.*}", 2, 1.234567)?; - /// // turns into this: - /// buffer.write_fmt(format_args!("{:.*}", 2, 1.234567))?; - /// # Ok(()) - /// # } + /// // this call + /// write!(buffer, "{:.*}", 2, 1.234567)?; + /// // turns into this: + /// buffer.write_fmt(format_args!("{:.*}", 2, 1.234567))?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()> { @@ -1187,19 +1186,19 @@ pub trait Write { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::Write; /// use std::fs::File; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut buffer = File::create("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let mut buffer = File::create("foo.txt")?; /// - /// let reference = buffer.by_ref(); + /// let reference = buffer.by_ref(); /// - /// // we can use reference just like our original buffer - /// reference.write_all(b"some bytes")?; - /// # Ok(()) - /// # } + /// // we can use reference just like our original buffer + /// reference.write_all(b"some bytes")?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn by_ref(&mut self) -> &mut Self where Self: Sized { self } @@ -1217,19 +1216,19 @@ pub trait Write { /// /// [file]: ../fs/struct.File.html /// -/// ``` +/// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// use std::io::SeekFrom; /// -/// # fn foo() -> io::Result<()> { -/// let mut f = File::open("foo.txt")?; +/// fn main() -> io::Result<()> { +/// let mut f = File::open("foo.txt")?; /// -/// // move the cursor 42 bytes from the start of the file -/// f.seek(SeekFrom::Start(42))?; -/// # Ok(()) -/// # } +/// // move the cursor 42 bytes from the start of the file +/// f.seek(SeekFrom::Start(42))?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait Seek { @@ -1320,7 +1319,7 @@ fn read_until(r: &mut R, delim: u8, buf: &mut Vec) /// /// A locked standard input implements `BufRead`: /// -/// ``` +/// ```no_run /// use std::io; /// use std::io::prelude::*; /// @@ -1342,21 +1341,21 @@ fn read_until(r: &mut R, delim: u8, buf: &mut Vec) /// [`lines`]: #method.lines /// [`Read`]: trait.Read.html /// -/// ``` +/// ```no_run /// use std::io::{self, BufReader}; /// use std::io::prelude::*; /// use std::fs::File; /// -/// # fn foo() -> io::Result<()> { -/// let f = File::open("foo.txt")?; -/// let f = BufReader::new(f); +/// fn main() -> io::Result<()> { +/// let f = File::open("foo.txt")?; +/// let f = BufReader::new(f); /// -/// for line in f.lines() { -/// println!("{}", line.unwrap()); +/// for line in f.lines() { +/// println!("{}", line.unwrap()); +/// } +/// +/// Ok(()) /// } -/// -/// # Ok(()) -/// # } /// ``` /// #[stable(feature = "rust1", since = "1.0.0")] @@ -1383,7 +1382,7 @@ pub trait BufRead: Read { /// /// A locked standard input implements `BufRead`: /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// @@ -1645,19 +1644,19 @@ impl Chain { /// /// # Examples /// - /// ``` - /// # use std::io; + /// ```no_run + /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut foo_file = File::open("foo.txt")?; - /// let mut bar_file = File::open("bar.txt")?; + /// fn main() -> io::Result<()> { + /// let mut foo_file = File::open("foo.txt")?; + /// let mut bar_file = File::open("bar.txt")?; /// - /// let chain = foo_file.chain(bar_file); - /// let (foo_file, bar_file) = chain.into_inner(); - /// # Ok(()) - /// # } + /// let chain = foo_file.chain(bar_file); + /// let (foo_file, bar_file) = chain.into_inner(); + /// Ok(()) + /// } /// ``` #[stable(feature = "more_io_inner_methods", since = "1.20.0")] pub fn into_inner(self) -> (T, U) { @@ -1668,19 +1667,19 @@ impl Chain { /// /// # Examples /// - /// ``` - /// # use std::io; + /// ```no_run + /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut foo_file = File::open("foo.txt")?; - /// let mut bar_file = File::open("bar.txt")?; + /// fn main() -> io::Result<()> { + /// let mut foo_file = File::open("foo.txt")?; + /// let mut bar_file = File::open("bar.txt")?; /// - /// let chain = foo_file.chain(bar_file); - /// let (foo_file, bar_file) = chain.get_ref(); - /// # Ok(()) - /// # } + /// let chain = foo_file.chain(bar_file); + /// let (foo_file, bar_file) = chain.get_ref(); + /// Ok(()) + /// } /// ``` #[stable(feature = "more_io_inner_methods", since = "1.20.0")] pub fn get_ref(&self) -> (&T, &U) { @@ -1695,19 +1694,19 @@ impl Chain { /// /// # Examples /// - /// ``` - /// # use std::io; + /// ```no_run + /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut foo_file = File::open("foo.txt")?; - /// let mut bar_file = File::open("bar.txt")?; + /// fn main() -> io::Result<()> { + /// let mut foo_file = File::open("foo.txt")?; + /// let mut bar_file = File::open("bar.txt")?; /// - /// let mut chain = foo_file.chain(bar_file); - /// let (foo_file, bar_file) = chain.get_mut(); - /// # Ok(()) - /// # } + /// let mut chain = foo_file.chain(bar_file); + /// let (foo_file, bar_file) = chain.get_mut(); + /// Ok(()) + /// } /// ``` #[stable(feature = "more_io_inner_methods", since = "1.20.0")] pub fn get_mut(&mut self) -> (&mut T, &mut U) { @@ -1794,20 +1793,20 @@ impl Take { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let f = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let f = File::open("foo.txt")?; /// - /// // read at most five bytes - /// let handle = f.take(5); + /// // read at most five bytes + /// let handle = f.take(5); /// - /// println!("limit: {}", handle.limit()); - /// # Ok(()) - /// # } + /// println!("limit: {}", handle.limit()); + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn limit(&self) -> u64 { self.limit } @@ -1819,22 +1818,22 @@ impl Take { /// /// # Examples /// - /// ``` + /// ```no_run /// #![feature(take_set_limit)] /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let f = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let f = File::open("foo.txt")?; /// - /// // read at most five bytes - /// let mut handle = f.take(5); - /// handle.set_limit(10); + /// // read at most five bytes + /// let mut handle = f.take(5); + /// handle.set_limit(10); /// - /// assert_eq!(handle.limit(), 10); - /// # Ok(()) - /// # } + /// assert_eq!(handle.limit(), 10); + /// Ok(()) + /// } /// ``` #[unstable(feature = "take_set_limit", issue = "42781")] pub fn set_limit(&mut self, limit: u64) { @@ -1845,21 +1844,21 @@ impl Take { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; /// - /// let mut buffer = [0; 5]; - /// let mut handle = file.take(5); - /// handle.read(&mut buffer)?; + /// let mut buffer = [0; 5]; + /// let mut handle = file.take(5); + /// handle.read(&mut buffer)?; /// - /// let file = handle.into_inner(); - /// # Ok(()) - /// # } + /// let file = handle.into_inner(); + /// Ok(()) + /// } /// ``` #[stable(feature = "io_take_into_inner", since = "1.15.0")] pub fn into_inner(self) -> T { @@ -1870,21 +1869,21 @@ impl Take { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; /// - /// let mut buffer = [0; 5]; - /// let mut handle = file.take(5); - /// handle.read(&mut buffer)?; + /// let mut buffer = [0; 5]; + /// let mut handle = file.take(5); + /// handle.read(&mut buffer)?; /// - /// let file = handle.get_ref(); - /// # Ok(()) - /// # } + /// let file = handle.get_ref(); + /// Ok(()) + /// } /// ``` #[stable(feature = "more_io_inner_methods", since = "1.20.0")] pub fn get_ref(&self) -> &T { @@ -1899,21 +1898,21 @@ impl Take { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io; /// use std::io::prelude::*; /// use std::fs::File; /// - /// # fn foo() -> io::Result<()> { - /// let mut file = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let mut file = File::open("foo.txt")?; /// - /// let mut buffer = [0; 5]; - /// let mut handle = file.take(5); - /// handle.read(&mut buffer)?; + /// let mut buffer = [0; 5]; + /// let mut handle = file.take(5); + /// handle.read(&mut buffer)?; /// - /// let file = handle.get_mut(); - /// # Ok(()) - /// # } + /// let file = handle.get_mut(); + /// Ok(()) + /// } /// ``` #[stable(feature = "more_io_inner_methods", since = "1.20.0")] pub fn get_mut(&mut self) -> &mut T { diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 1f73054e3bee..2472bed5ba43 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -171,29 +171,29 @@ pub struct StdinLock<'a> { /// /// Using implicit synchronization: /// -/// ``` +/// ```no_run /// use std::io::{self, Read}; /// -/// # fn foo() -> io::Result { -/// let mut buffer = String::new(); -/// io::stdin().read_to_string(&mut buffer)?; -/// # Ok(buffer) -/// # } +/// fn main() -> io::Result<()> { +/// let mut buffer = String::new(); +/// io::stdin().read_to_string(&mut buffer)?; +/// Ok(()) +/// } /// ``` /// /// Using explicit synchronization: /// -/// ``` +/// ```no_run /// use std::io::{self, Read}; /// -/// # fn foo() -> io::Result { -/// let mut buffer = String::new(); -/// let stdin = io::stdin(); -/// let mut handle = stdin.lock(); +/// fn main() -> io::Result<()> { +/// let mut buffer = String::new(); +/// let stdin = io::stdin(); +/// let mut handle = stdin.lock(); /// -/// handle.read_to_string(&mut buffer)?; -/// # Ok(buffer) -/// # } +/// handle.read_to_string(&mut buffer)?; +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn stdin() -> Stdin { @@ -225,17 +225,17 @@ impl Stdin { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::{self, Read}; /// - /// # fn foo() -> io::Result { - /// let mut buffer = String::new(); - /// let stdin = io::stdin(); - /// let mut handle = stdin.lock(); + /// fn main() -> io::Result<()> { + /// let mut buffer = String::new(); + /// let stdin = io::stdin(); + /// let mut handle = stdin.lock(); /// - /// handle.read_to_string(&mut buffer)?; - /// # Ok(buffer) - /// # } + /// handle.read_to_string(&mut buffer)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdinLock { @@ -369,29 +369,29 @@ pub struct StdoutLock<'a> { /// /// Using implicit synchronization: /// -/// ``` +/// ```no_run /// use std::io::{self, Write}; /// -/// # fn foo() -> io::Result<()> { -/// io::stdout().write(b"hello world")?; +/// fn main() -> io::Result<()> { +/// io::stdout().write(b"hello world")?; /// -/// # Ok(()) -/// # } +/// Ok(()) +/// } /// ``` /// /// Using explicit synchronization: /// -/// ``` +/// ```no_run /// use std::io::{self, Write}; /// -/// # fn foo() -> io::Result<()> { -/// let stdout = io::stdout(); -/// let mut handle = stdout.lock(); +/// fn main() -> io::Result<()> { +/// let stdout = io::stdout(); +/// let mut handle = stdout.lock(); /// -/// handle.write(b"hello world")?; +/// handle.write(b"hello world")?; /// -/// # Ok(()) -/// # } +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn stdout() -> Stdout { @@ -419,17 +419,17 @@ impl Stdout { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::io::{self, Write}; /// - /// # fn foo() -> io::Result<()> { - /// let stdout = io::stdout(); - /// let mut handle = stdout.lock(); + /// fn main() -> io::Result<()> { + /// let stdout = io::stdout(); + /// let mut handle = stdout.lock(); /// - /// handle.write(b"hello world")?; + /// handle.write(b"hello world")?; /// - /// # Ok(()) - /// # } + /// Ok(()) + /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> StdoutLock { @@ -505,29 +505,29 @@ pub struct StderrLock<'a> { /// /// Using implicit synchronization: /// -/// ``` +/// ```no_run /// use std::io::{self, Write}; /// -/// # fn foo() -> io::Result<()> { -/// io::stderr().write(b"hello world")?; +/// fn main() -> io::Result<()> { +/// io::stderr().write(b"hello world")?; /// -/// # Ok(()) -/// # } +/// Ok(()) +/// } /// ``` /// /// Using explicit synchronization: /// -/// ``` +/// ```no_run /// use std::io::{self, Write}; /// -/// # fn foo() -> io::Result<()> { -/// let stderr = io::stderr(); -/// let mut handle = stderr.lock(); +/// fn main() -> io::Result<()> { +/// let stderr = io::stderr(); +/// let mut handle = stderr.lock(); /// -/// handle.write(b"hello world")?; +/// handle.write(b"hello world")?; /// -/// # Ok(()) -/// # } +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn stderr() -> Stderr { diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs index 45d281ee34ac..195310a26fed 100644 --- a/src/libstd/io/util.rs +++ b/src/libstd/io/util.rs @@ -34,16 +34,15 @@ use mem; /// ``` /// use std::io; /// -/// # fn foo() -> io::Result<()> { -/// let mut reader: &[u8] = b"hello"; -/// let mut writer: Vec = vec![]; +/// fn main() -> io::Result<()> { +/// let mut reader: &[u8] = b"hello"; +/// let mut writer: Vec = vec![]; /// -/// io::copy(&mut reader, &mut writer)?; +/// io::copy(&mut reader, &mut writer)?; /// -/// assert_eq!(&b"hello"[..], &writer[..]); -/// # Ok(()) -/// # } -/// # foo().unwrap(); +/// assert_eq!(&b"hello"[..], &writer[..]); +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn copy(reader: &mut R, writer: &mut W) -> io::Result diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index eef043683b02..b0d5e563cb9e 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -175,12 +175,12 @@ impl fmt::Debug for LookupHost { /// /// use std::net; /// -/// # fn foo() -> std::io::Result<()> { -/// for host in net::lookup_host("rust-lang.org")? { -/// println!("found address: {}", host); +/// fn main() -> std::io::Result<()> { +/// for host in net::lookup_host("rust-lang.org")? { +/// println!("found address: {}", host); +/// } +/// Ok(()) /// } -/// # Ok(()) -/// # } /// ``` #[unstable(feature = "lookup_host", reason = "unsure about the returned \ iterator and returning socket \ diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index e28ccdb766ae..0f60b5b3ee4b 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -72,7 +72,7 @@ pub struct TcpStream(net_imp::TcpStream); /// /// # Examples /// -/// ``` +/// ```no_run /// # use std::io; /// use std::net::{TcpListener, TcpStream}; /// @@ -80,15 +80,15 @@ pub struct TcpStream(net_imp::TcpStream); /// // ... /// } /// -/// # fn process() -> io::Result<()> { -/// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); +/// fn main() -> io::Result<()> { +/// let listener = TcpListener::bind("127.0.0.1:80").unwrap(); /// -/// // accept connections and process them serially -/// for stream in listener.incoming() { -/// handle_client(stream?); +/// // accept connections and process them serially +/// for stream in listener.incoming() { +/// handle_client(stream?); +/// } +/// Ok(()) /// } -/// # Ok(()) -/// # } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct TcpListener(net_imp::TcpListener); diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs index 8e56954bea43..d25e29999cb6 100644 --- a/src/libstd/net/udp.rs +++ b/src/libstd/net/udp.rs @@ -44,22 +44,22 @@ use time::Duration; /// ```no_run /// use std::net::UdpSocket; /// -/// # fn foo() -> std::io::Result<()> { -/// { -/// let mut socket = UdpSocket::bind("127.0.0.1:34254")?; +/// fn main() -> std::io::Result<()> { +/// { +/// let mut socket = UdpSocket::bind("127.0.0.1:34254")?; /// -/// // Receives a single datagram message on the socket. If `buf` is too small to hold -/// // the message, it will be cut off. -/// let mut buf = [0; 10]; -/// let (amt, src) = socket.recv_from(&mut buf)?; +/// // Receives a single datagram message on the socket. If `buf` is too small to hold +/// // the message, it will be cut off. +/// let mut buf = [0; 10]; +/// let (amt, src) = socket.recv_from(&mut buf)?; /// -/// // Redeclare `buf` as slice of the received data and send reverse data back to origin. -/// let buf = &mut buf[..amt]; -/// buf.reverse(); -/// socket.send_to(buf, &src)?; -/// # Ok(()) -/// } // the socket is closed here -/// # } +/// // Redeclare `buf` as slice of the received data and send reverse data back to origin. +/// let buf = &mut buf[..amt]; +/// buf.reverse(); +/// socket.send_to(buf, &src)?; +/// } // the socket is closed here +/// Ok(()) +/// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct UdpSocket(net_imp::UdpSocket); diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs index 5d37d970e89b..2be2fbcb2dbf 100644 --- a/src/libstd/os/linux/fs.rs +++ b/src/libstd/os/linux/fs.rs @@ -32,16 +32,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let stat = meta.as_raw_stat(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let stat = meta.as_raw_stat(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] #[rustc_deprecated(since = "1.8.0", @@ -54,16 +54,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_dev()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_dev()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_dev(&self) -> u64; @@ -71,16 +71,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_ino()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ino()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_ino(&self) -> u64; @@ -88,16 +88,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_mode()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mode()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_mode(&self) -> u32; @@ -105,16 +105,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_nlink()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_nlink()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_nlink(&self) -> u64; @@ -122,16 +122,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_uid()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_uid()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_uid(&self) -> u32; @@ -139,16 +139,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_gid()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_gid()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_gid(&self) -> u32; @@ -156,16 +156,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_rdev()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_rdev()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_rdev(&self) -> u64; @@ -176,16 +176,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_size()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_size()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_size(&self) -> u64; @@ -193,16 +193,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_atime()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_atime()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_atime(&self) -> i64; @@ -210,16 +210,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_atime_nsec()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_atime_nsec()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_atime_nsec(&self) -> i64; @@ -227,16 +227,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_mtime()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mtime()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_mtime(&self) -> i64; @@ -244,16 +244,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_mtime_nsec()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_mtime_nsec()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_mtime_nsec(&self) -> i64; @@ -261,16 +261,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_ctime()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ctime()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_ctime(&self) -> i64; @@ -278,16 +278,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_ctime_nsec()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_ctime_nsec()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_ctime_nsec(&self) -> i64; @@ -295,16 +295,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_blksize()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_blksize()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_blksize(&self) -> u64; @@ -312,16 +312,16 @@ pub trait MetadataExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; + /// use std::io; /// use std::os::linux::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// println!("{}", meta.st_blocks()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// println!("{}", meta.st_blocks()); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext2", since = "1.8.0")] fn st_blocks(&self) -> u64; diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs index 5d4edc2cf92c..0f4762aa8810 100644 --- a/src/libstd/sys/redox/ext/fs.rs +++ b/src/libstd/sys/redox/ext/fs.rs @@ -30,13 +30,14 @@ pub trait PermissionsExt { /// use std::fs::File; /// use std::os::redox::fs::PermissionsExt; /// - /// # fn run() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let permissions = metadata.permissions(); + /// fn main() -> std::io::Result<()> { + /// let f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; + /// let permissions = metadata.permissions(); /// - /// println!("permissions: {}", permissions.mode()); - /// # Ok(()) } + /// println!("permissions: {}", permissions.mode()); + /// Ok(()) + /// } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; @@ -49,14 +50,15 @@ pub trait PermissionsExt { /// use std::fs::File; /// use std::os::redox::fs::PermissionsExt; /// - /// # fn run() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let mut permissions = metadata.permissions(); + /// fn main() -> std::io::Result<()> { + /// let f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; + /// let mut permissions = metadata.permissions(); /// - /// permissions.set_mode(0o644); // Read/write for owner and read for others. - /// assert_eq!(permissions.mode(), 0o644); - /// # Ok(()) } + /// permissions.set_mode(0o644); // Read/write for owner and read for others. + /// assert_eq!(permissions.mode(), 0o644); + /// Ok(()) + /// } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32); @@ -291,13 +293,13 @@ impl FileTypeExt for fs::FileType { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::os::redox::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::symlink("a.txt", "b.txt")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::symlink("a.txt", "b.txt")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "symlink", since = "1.1.0")] pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs index 2e17fd58e0a1..3c5b9424fb06 100644 --- a/src/libstd/sys/unix/ext/fs.rs +++ b/src/libstd/sys/unix/ext/fs.rs @@ -41,20 +41,20 @@ pub trait FileExt { /// /// # Examples /// - /// ``` - /// use std::os::unix::prelude::FileExt; + /// ```no_run + /// use std::io; /// use std::fs::File; + /// use std::os::unix::prelude::FileExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let mut buf = [0u8; 8]; - /// let file = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let mut buf = [0u8; 8]; + /// let file = File::open("foo.txt")?; /// - /// // We now read 8 bytes from the offset 10. - /// let num_bytes_read = file.read_at(&mut buf, 10)?; - /// println!("read {} bytes: {:?}", num_bytes_read, buf); - /// # Ok(()) - /// # } + /// // We now read 8 bytes from the offset 10. + /// let num_bytes_read = file.read_at(&mut buf, 10)?; + /// println!("read {} bytes: {:?}", num_bytes_read, buf); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_offset", since = "1.15.0")] fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result; @@ -78,18 +78,18 @@ pub trait FileExt { /// /// # Examples /// - /// ``` - /// use std::os::unix::prelude::FileExt; + /// ```no_run /// use std::fs::File; + /// use std::io; + /// use std::os::unix::prelude::FileExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let file = File::open("foo.txt")?; + /// fn main() -> io::Result<()> { + /// let file = File::open("foo.txt")?; /// - /// // We now write at the offset 10. - /// file.write_at(b"sushi", 10)?; - /// # Ok(()) - /// # } + /// // We now write at the offset 10. + /// file.write_at(b"sushi", 10)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "file_offset", since = "1.15.0")] fn write_at(&self, buf: &[u8], offset: u64) -> io::Result; @@ -117,13 +117,13 @@ pub trait PermissionsExt { /// use std::fs::File; /// use std::os::unix::fs::PermissionsExt; /// - /// # fn run() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let permissions = metadata.permissions(); + /// fn main() -> std::io::Result<()> { + /// let f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; + /// let permissions = metadata.permissions(); /// - /// println!("permissions: {}", permissions.mode()); - /// # Ok(()) } + /// println!("permissions: {}", permissions.mode()); + /// Ok(()) } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn mode(&self) -> u32; @@ -136,14 +136,14 @@ pub trait PermissionsExt { /// use std::fs::File; /// use std::os::unix::fs::PermissionsExt; /// - /// # fn run() -> std::io::Result<()> { - /// let f = File::create("foo.txt")?; - /// let metadata = f.metadata()?; - /// let mut permissions = metadata.permissions(); + /// fn main() -> std::io::Result<()> { + /// let f = File::create("foo.txt")?; + /// let metadata = f.metadata()?; + /// let mut permissions = metadata.permissions(); /// - /// permissions.set_mode(0o644); // Read/write for owner and read for others. - /// assert_eq!(permissions.mode(), 0o644); - /// # Ok(()) } + /// permissions.set_mode(0o644); // Read/write for owner and read for others. + /// assert_eq!(permissions.mode(), 0o644); + /// Ok(()) } /// ``` #[stable(feature = "fs_ext", since = "1.1.0")] fn set_mode(&mut self, mode: u32); @@ -260,15 +260,15 @@ pub trait MetadataExt { /// # Examples /// /// ```no_run + /// use std::io; /// use std::fs; /// use std::os::unix::fs::MetadataExt; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let dev_id = meta.dev(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let dev_id = meta.dev(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn dev(&self) -> u64; @@ -279,13 +279,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let inode = meta.ino(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let inode = meta.ino(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ino(&self) -> u64; @@ -296,17 +296,17 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let mode = meta.mode(); - /// let user_has_write_access = mode & 0o200; - /// let user_has_read_write_access = mode & 0o600; - /// let group_has_read_access = mode & 0o040; - /// let others_have_exec_access = mode & 0o001; - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let mode = meta.mode(); + /// let user_has_write_access = mode & 0o200; + /// let user_has_read_write_access = mode & 0o600; + /// let group_has_read_access = mode & 0o040; + /// let others_have_exec_access = mode & 0o001; + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mode(&self) -> u32; @@ -317,13 +317,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let nb_hard_links = meta.nlink(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nb_hard_links = meta.nlink(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn nlink(&self) -> u64; @@ -334,13 +334,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let user_id = meta.uid(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let user_id = meta.uid(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn uid(&self) -> u32; @@ -351,13 +351,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let group_id = meta.gid(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let group_id = meta.gid(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn gid(&self) -> u32; @@ -368,13 +368,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let device_id = meta.rdev(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let device_id = meta.rdev(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn rdev(&self) -> u64; @@ -385,13 +385,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let file_size = meta.size(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let file_size = meta.size(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn size(&self) -> u64; @@ -402,13 +402,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let last_access_time = meta.atime(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let last_access_time = meta.atime(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn atime(&self) -> i64; @@ -419,13 +419,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let nano_last_access_time = meta.atime_nsec(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_access_time = meta.atime_nsec(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn atime_nsec(&self) -> i64; @@ -436,13 +436,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let last_modification_time = meta.mtime(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let last_modification_time = meta.mtime(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mtime(&self) -> i64; @@ -453,13 +453,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let nano_last_modification_time = meta.mtime_nsec(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_modification_time = meta.mtime_nsec(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn mtime_nsec(&self) -> i64; @@ -470,13 +470,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let last_status_change_time = meta.ctime(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let last_status_change_time = meta.ctime(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ctime(&self) -> i64; @@ -487,13 +487,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let nano_last_status_change_time = meta.ctime_nsec(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let nano_last_status_change_time = meta.ctime_nsec(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn ctime_nsec(&self) -> i64; @@ -504,13 +504,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let blocksize = meta.blksize(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let blocksize = meta.blksize(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn blksize(&self) -> u64; @@ -523,13 +523,13 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("some_file")?; - /// let blocks = meta.blocks(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("some_file")?; + /// let blocks = meta.blocks(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn blocks(&self) -> u64; @@ -562,17 +562,17 @@ pub trait FileTypeExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; /// use std::os::unix::fs::FileTypeExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("block_device_file")?; - /// let file_type = meta.file_type(); - /// assert!(file_type.is_block_device()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("block_device_file")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_block_device()); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type_ext", since = "1.5.0")] fn is_block_device(&self) -> bool; @@ -580,17 +580,17 @@ pub trait FileTypeExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; /// use std::os::unix::fs::FileTypeExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("char_device_file")?; - /// let file_type = meta.file_type(); - /// assert!(file_type.is_char_device()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("char_device_file")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_char_device()); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type_ext", since = "1.5.0")] fn is_char_device(&self) -> bool; @@ -598,17 +598,17 @@ pub trait FileTypeExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; /// use std::os::unix::fs::FileTypeExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("fifo_file")?; - /// let file_type = meta.file_type(); - /// assert!(file_type.is_fifo()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("fifo_file")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_fifo()); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type_ext", since = "1.5.0")] fn is_fifo(&self) -> bool; @@ -616,17 +616,17 @@ pub trait FileTypeExt { /// /// # Examples /// - /// ``` + /// ```no_run /// use std::fs; /// use std::os::unix::fs::FileTypeExt; + /// use std::io; /// - /// # use std::io; - /// # fn f() -> io::Result<()> { - /// let meta = fs::metadata("unix.socket")?; - /// let file_type = meta.file_type(); - /// assert!(file_type.is_socket()); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let meta = fs::metadata("unix.socket")?; + /// let file_type = meta.file_type(); + /// assert!(file_type.is_socket()); + /// Ok(()) + /// } /// ``` #[stable(feature = "file_type_ext", since = "1.5.0")] fn is_socket(&self) -> bool; @@ -687,13 +687,13 @@ impl DirEntryExt for fs::DirEntry { /// /// # Examples /// -/// ``` +/// ```no_run /// use std::os::unix::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::symlink("a.txt", "b.txt")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::symlink("a.txt", "b.txt")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "symlink", since = "1.1.0")] pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs index 38bf4cca851f..e5cd51b6550b 100644 --- a/src/libstd/sys/windows/ext/fs.rs +++ b/src/libstd/sys/windows/ext/fs.rs @@ -45,15 +45,15 @@ pub trait FileExt { /// 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]; + /// fn main() -> 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(()) - /// # } + /// // 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; @@ -79,14 +79,14 @@ pub trait FileExt { /// use std::fs::File; /// use std::os::windows::prelude::*; /// - /// # fn foo() -> std::io::Result<()> { - /// let mut buffer = File::create("foo.txt")?; + /// fn main() -> std::io::Result<()> { + /// let mut buffer = File::create("foo.txt")?; /// - /// // Write a byte string starting 72 bytes from - /// // the start of the file. - /// buffer.seek_write(b"some bytes", 72)?; - /// # Ok(()) - /// # } + /// // Write a byte string starting 72 bytes from + /// // the start of the file. + /// buffer.seek_write(b"some bytes", 72)?; + /// Ok(()) + /// } /// ``` #[stable(feature = "file_offset", since = "1.15.0")] fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result; @@ -305,11 +305,11 @@ pub trait MetadataExt { /// use std::fs; /// use std::os::windows::prelude::*; /// - /// # fn foo() -> io::Result<()> { - /// let metadata = fs::metadata("foo.txt")?; - /// let attributes = metadata.file_attributes(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; + /// let attributes = metadata.file_attributes(); + /// Ok(()) + /// } /// ``` /// /// [File Attribute Constants]: @@ -335,11 +335,11 @@ pub trait MetadataExt { /// use std::fs; /// use std::os::windows::prelude::*; /// - /// # fn foo() -> io::Result<()> { - /// let metadata = fs::metadata("foo.txt")?; - /// let creation_time = metadata.creation_time(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; + /// let creation_time = metadata.creation_time(); + /// Ok(()) + /// } /// ``` /// /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx @@ -370,11 +370,11 @@ pub trait MetadataExt { /// use std::fs; /// use std::os::windows::prelude::*; /// - /// # fn foo() -> io::Result<()> { - /// let metadata = fs::metadata("foo.txt")?; - /// let last_access_time = metadata.last_access_time(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; + /// let last_access_time = metadata.last_access_time(); + /// Ok(()) + /// } /// ``` /// /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx @@ -403,11 +403,11 @@ pub trait MetadataExt { /// use std::fs; /// use std::os::windows::prelude::*; /// - /// # fn foo() -> io::Result<()> { - /// let metadata = fs::metadata("foo.txt")?; - /// let last_write_time = metadata.last_write_time(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; + /// let last_write_time = metadata.last_write_time(); + /// Ok(()) + /// } /// ``` /// /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx @@ -426,11 +426,11 @@ pub trait MetadataExt { /// use std::fs; /// use std::os::windows::prelude::*; /// - /// # fn foo() -> io::Result<()> { - /// let metadata = fs::metadata("foo.txt")?; - /// let file_size = metadata.file_size(); - /// # Ok(()) - /// # } + /// fn main() -> io::Result<()> { + /// let metadata = fs::metadata("foo.txt")?; + /// let file_size = metadata.file_size(); + /// Ok(()) + /// } /// ``` #[stable(feature = "metadata_ext", since = "1.1.0")] fn file_size(&self) -> u64; @@ -473,10 +473,10 @@ impl FileTypeExt for fs::FileType { /// ```no_run /// use std::os::windows::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::symlink_file("a.txt", "b.txt")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::symlink_file("a.txt", "b.txt")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "symlink", since = "1.1.0")] pub fn symlink_file, Q: AsRef>(src: P, dst: Q) @@ -494,10 +494,10 @@ pub fn symlink_file, Q: AsRef>(src: P, dst: Q) /// ```no_run /// use std::os::windows::fs; /// -/// # fn foo() -> std::io::Result<()> { -/// fs::symlink_dir("a", "b")?; -/// # Ok(()) -/// # } +/// fn main() -> std::io::Result<()> { +/// fs::symlink_dir("a", "b")?; +/// Ok(()) +/// } /// ``` #[stable(feature = "symlink", since = "1.1.0")] pub fn symlink_dir, Q: AsRef>(src: P, dst: Q) From b89fb71441db5fc7f719bbd25ba2ec61b0b9091a Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 26 Mar 2018 17:43:49 +0200 Subject: [PATCH 697/830] Clarify network byte order conversions for integer / IP address conversions. Opened primarily to address https://github.com/rust-lang/rust/issues/48819. --- src/libstd/net/ip.rs | 82 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 0d73a6f4fd7f..8115f50f09b6 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -769,7 +769,16 @@ impl FromInner for Ipv4Addr { #[stable(feature = "ip_u32", since = "1.1.0")] impl From for u32 { - /// It performs the conversion in network order (big-endian). + /// Convert an `Ipv4Addr` into a host byte order `u32`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::new(13, 12, 11, 10); + /// assert_eq!(0x0d0c0b0au32, u32::from(addr)); + /// ``` fn from(ip: Ipv4Addr) -> u32 { let ip = ip.octets(); ((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32) @@ -778,7 +787,16 @@ impl From for u32 { #[stable(feature = "ip_u32", since = "1.1.0")] impl From for Ipv4Addr { - /// It performs the conversion in network order (big-endian). + /// Convert a host byte order `u32` into an `Ipv4Addr`. + /// + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::from(0x0d0c0b0au32); + /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr); + /// ``` fn from(ip: u32) -> Ipv4Addr { Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8) } @@ -786,6 +804,14 @@ impl From for Ipv4Addr { #[stable(feature = "from_slice_v4", since = "1.9.0")] impl From<[u8; 4]> for Ipv4Addr { + /// # Examples + /// + /// ``` + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::from([13u8, 12u8, 11u8, 10u8]); + /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr); + /// ``` fn from(octets: [u8; 4]) -> Ipv4Addr { Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]) } @@ -793,6 +819,16 @@ impl From<[u8; 4]> for Ipv4Addr { #[stable(feature = "ip_from_slice", since = "1.17.0")] impl From<[u8; 4]> for IpAddr { + /// Create an `IpAddr::V4` from a four element byte array. + /// + /// # Examples + /// + /// ``` + /// use std::net::{IpAddr, Ipv4Addr}; + /// + /// let addr = IpAddr::from([13u8, 12u8, 11u8, 10u8]); + /// assert_eq!(IpAddr::V4(Ipv4Addr::new(13, 12, 11, 10)), addr); + /// ``` fn from(octets: [u8; 4]) -> IpAddr { IpAddr::V4(Ipv4Addr::from(octets)) } @@ -1386,6 +1422,27 @@ impl From<[u16; 8]> for Ipv6Addr { #[stable(feature = "ip_from_slice", since = "1.17.0")] impl From<[u8; 16]> for IpAddr { + /// Create an `IpAddr::V6` from a sixteen element byte array. + /// + /// # Examples + /// + /// ``` + /// use std::net::{IpAddr, Ipv6Addr}; + /// + /// let addr = IpAddr::from([ + /// 25u8, 24u8, 23u8, 22u8, 21u8, 20u8, 19u8, 18u8, + /// 17u8, 16u8, 15u8, 14u8, 13u8, 12u8, 11u8, 10u8, + /// ]); + /// assert_eq!( + /// IpAddr::V6(Ipv6Addr::new( + /// 0x1918, 0x1716, + /// 0x1514, 0x1312, + /// 0x1110, 0x0f0e, + /// 0x0d0c, 0x0b0a + /// )), + /// addr + /// ); + /// ``` fn from(octets: [u8; 16]) -> IpAddr { IpAddr::V6(Ipv6Addr::from(octets)) } @@ -1393,6 +1450,27 @@ impl From<[u8; 16]> for IpAddr { #[stable(feature = "ip_from_slice", since = "1.17.0")] impl From<[u16; 8]> for IpAddr { + /// Create an `IpAddr::V6` from an eight element 16-bit array. + /// + /// # Examples + /// + /// ``` + /// use std::net::{IpAddr, Ipv6Addr}; + /// + /// let addr = IpAddr::from([ + /// 525u16, 524u16, 523u16, 522u16, + /// 521u16, 520u16, 519u16, 518u16, + /// ]); + /// assert_eq!( + /// IpAddr::V6(Ipv6Addr::new( + /// 0x20d, 0x20c, + /// 0x20b, 0x20a, + /// 0x209, 0x208, + /// 0x207, 0x206 + /// )), + /// addr + /// ); + /// ``` fn from(segments: [u16; 8]) -> IpAddr { IpAddr::V6(Ipv6Addr::from(segments)) } From 51f26acaea46afd630fbab4ca441748802d20670 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Mar 2018 09:00:58 +0200 Subject: [PATCH 698/830] Fix text overlap --- src/librustdoc/html/render.rs | 33 ++++++++++--------- src/librustdoc/html/static/rustdoc.css | 30 ++++++++++++++--- src/test/rustdoc/synthetic_auto/complex.rs | 2 +- src/test/rustdoc/synthetic_auto/lifetimes.rs | 4 +-- src/test/rustdoc/synthetic_auto/manual.rs | 4 +-- src/test/rustdoc/synthetic_auto/negative.rs | 4 +-- src/test/rustdoc/synthetic_auto/nested.rs | 4 +-- .../rustdoc/synthetic_auto/no-redundancy.rs | 2 +- src/test/rustdoc/synthetic_auto/project.rs | 4 +-- 9 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 678e1762a551..2eee60890e87 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2243,14 +2243,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter, implementor_dups: &FxHashMap<&str, (DefId, bool)>) -> Result<(), fmt::Error> { - write!(w, "
  • ")?; - if let Some(l) = (Item { cx, item: &implementor.impl_item }).src_href() { - write!(w, "
    ")?; - write!(w, "[src]", - l, "goto source code")?; - write!(w, "
    ")?; - } - write!(w, "")?; + write!(w, "
  • ")?; // If there's already another implementor that has the same abbridged name, use the // full path, for example in `std::iter::ExactSizeIterator` let use_absolute = match implementor.inner_impl().for_ { @@ -2269,7 +2262,14 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter, write!(w, ";")?; } } - writeln!(w, "")?; + write!(w, "")?; + if let Some(l) = (Item { cx, item: &implementor.impl_item }).src_href() { + write!(w, "
    ")?; + write!(w, "[src]", + l, "goto source code")?; + write!(w, "
    ")?; + } + writeln!(w, "
  • ")?; Ok(()) } @@ -3314,10 +3314,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi Some(ref t) => format!("impl-{}", small_url_encode(&format!("{:#}", t))), None => "impl".to_string(), }); - write!(w, "

    {}", + write!(w, "

    \ +
    {}", id, i.inner_impl())?; write!(w, "", id)?; - write!(w, "")?; + write!(w, "")?; let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]); if let Some(l) = (Item { item: &i.impl_item, cx: cx }).src_href() { write!(w, "
    ")?; @@ -3327,8 +3328,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } else { render_stability_since_raw(w, since, outer_version)?; } - write!(w, "
    ")?; - write!(w, "\n")?; + write!(w, "

    ")?; if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) { write!(w, "
    {}
    ", Markdown(&*dox, &i.impl_item.links()))?; @@ -3357,19 +3357,20 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi write!(w, "

    ", id, item_type)?; write!(w, "{}", spotlight_decl(decl)?)?; write!(w, "

    ")?; } } clean::TypedefItem(ref tydef, _) => { diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 9b899dd4517e..5fb2aa4ef74f 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -387,8 +387,6 @@ h4 > code, h3 > code, .invisible > code { .content .in-band { margin: 0px; padding: 0px; - display: inline-block; - max-width: calc(100% - 43px); } .in-band > code { @@ -403,7 +401,7 @@ h4 > code, h3 > code, .invisible > code { font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } -.content table { +.content table:not(.table-display) { border-spacing: 0 5px; border-collapse: separate; } @@ -470,7 +468,6 @@ h4 > code, h3 > code, .invisible > code { .content .methods > div:not(.important-traits) { margin-left: 40px; } .content .impl-items .docblock, .content .impl-items .stability { - margin-left: 40px; margin-bottom: .6em; } .content .impl-items .method, .content .impl-items > .type, .impl-items > .associatedconstant { @@ -1254,3 +1251,28 @@ kbd { /* important because of conflicting rule for small screens */ display: none !important; } + +#implementations-list > h3 > span.in-band { + width: 100%; +} + +.table-display { + width: 100%; + border: 0; + border-collapse: collapse; + border-spacing: 0; + font-size: 16px; +} + +.table-display tr td:first-child { + padding-right: 0; +} + +.table-display tr td:last-child { + float: right; +} +.table-display .out-of-band { + position: relative; + font-size: 19px; + display: block; +} diff --git a/src/test/rustdoc/synthetic_auto/complex.rs b/src/test/rustdoc/synthetic_auto/complex.rs index 531798c30c65..a4ebf6d3a7e8 100644 --- a/src/test/rustdoc/synthetic_auto/complex.rs +++ b/src/test/rustdoc/synthetic_auto/complex.rs @@ -30,7 +30,7 @@ mod foo { } // @has complex/struct.NotOuter.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'a, T, K: \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'a, T, K: \ // ?Sized> Send for NotOuter<'a, T, K> where K: for<'b> Fn((&'b bool, &'a u8)) \ // -> &'b i8, T: MyTrait<'a>, >::MyItem: Copy, 'a: 'static" diff --git a/src/test/rustdoc/synthetic_auto/lifetimes.rs b/src/test/rustdoc/synthetic_auto/lifetimes.rs index 272925e5db54..1c1e7bc25052 100644 --- a/src/test/rustdoc/synthetic_auto/lifetimes.rs +++ b/src/test/rustdoc/synthetic_auto/lifetimes.rs @@ -18,10 +18,10 @@ where {} // @has lifetimes/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Send \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Send \ // for Foo<'c, K> where K: for<'b> Fn(&'b bool) -> &'c u8, 'c: 'static" // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Sync \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Sync \ // for Foo<'c, K> where K: Sync" pub struct Foo<'c, K: 'c> { inner_field: Inner<'c, K>, diff --git a/src/test/rustdoc/synthetic_auto/manual.rs b/src/test/rustdoc/synthetic_auto/manual.rs index d81e6309dff6..ef6797ecf3c5 100644 --- a/src/test/rustdoc/synthetic_auto/manual.rs +++ b/src/test/rustdoc/synthetic_auto/manual.rs @@ -9,10 +9,10 @@ // except according to those terms. // @has manual/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' 'impl Sync for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' 'impl Sync for \ // Foo where T: Sync' // -// @has - '//*[@id="implementations-list"]/*[@class="impl"]/*/code' \ +// @has - '//*[@id="implementations-list"]/*[@class="impl"]//*/code' \ // 'impl Send for Foo' // // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 1 diff --git a/src/test/rustdoc/synthetic_auto/negative.rs b/src/test/rustdoc/synthetic_auto/negative.rs index ec9cb710f1f8..64480d28240b 100644 --- a/src/test/rustdoc/synthetic_auto/negative.rs +++ b/src/test/rustdoc/synthetic_auto/negative.rs @@ -13,10 +13,10 @@ pub struct Inner { } // @has negative/struct.Outer.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl !Send for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl !Send for \ // Outer" // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl \ // !Sync for Outer" pub struct Outer { inner_field: Inner, diff --git a/src/test/rustdoc/synthetic_auto/nested.rs b/src/test/rustdoc/synthetic_auto/nested.rs index 1f33a8b13cbf..ccdbe159b6c5 100644 --- a/src/test/rustdoc/synthetic_auto/nested.rs +++ b/src/test/rustdoc/synthetic_auto/nested.rs @@ -18,10 +18,10 @@ where } // @has nested/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' 'impl Send for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' 'impl Send for \ // Foo where T: Copy' // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' \ // 'impl Sync for Foo where T: Sync' pub struct Foo { inner_field: Inner, diff --git a/src/test/rustdoc/synthetic_auto/no-redundancy.rs b/src/test/rustdoc/synthetic_auto/no-redundancy.rs index 0b37f2ed3179..24fba221b993 100644 --- a/src/test/rustdoc/synthetic_auto/no-redundancy.rs +++ b/src/test/rustdoc/synthetic_auto/no-redundancy.rs @@ -19,7 +19,7 @@ where } // @has no_redundancy/struct.Outer.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl Send for \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl Send for \ // Outer where T: Copy + Send" pub struct Outer { inner_field: Inner, diff --git a/src/test/rustdoc/synthetic_auto/project.rs b/src/test/rustdoc/synthetic_auto/project.rs index 977607fb1482..d588190c4f9d 100644 --- a/src/test/rustdoc/synthetic_auto/project.rs +++ b/src/test/rustdoc/synthetic_auto/project.rs @@ -33,10 +33,10 @@ where } // @has project/struct.Foo.html -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Send \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Send \ // for Foo<'c, K> where K: MyTrait, 'c: 'static" // -// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]/*/code' "impl<'c, K> Sync \ +// @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<'c, K> Sync \ // for Foo<'c, K> where K: MyTrait, ::MyItem: OtherTrait, 'c: 'static," pub struct Foo<'c, K: 'c> { inner_field: Inner<'c, K>, From d9bf37a5ae75c06da4ab80a008b06de1a5e13f64 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 28 Mar 2018 13:54:05 +0200 Subject: [PATCH 699/830] use --edition for doctests, rather than just the crate --- src/librustdoc/lib.rs | 2 +- src/librustdoc/markdown.rs | 5 +++-- src/librustdoc/test.rs | 18 +++++++++++++----- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c22269cbab42..9704a0369476 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -446,7 +446,7 @@ pub fn main_args(args: &[String]) -> isize { match (should_test, markdown_input) { (true, true) => { return markdown::test(input, cfgs, libs, externs, test_args, maybe_sysroot, - display_warnings, linker) + display_warnings, linker, edition) } (true, false) => { return test::run(Path::new(input), cfgs, libs, externs, test_args, crate_name, diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 3a55b279b5cc..daa8966b104e 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -18,6 +18,7 @@ use testing; use rustc::session::search_paths::SearchPaths; use rustc::session::config::Externs; use syntax::codemap::DUMMY_SP; +use syntax::edition::Edition; use externalfiles::{ExternalHtml, LoadStringError, load_string}; @@ -139,7 +140,7 @@ pub fn render(input: &Path, mut output: PathBuf, matches: &getopts::Matches, /// Run any tests/code examples in the markdown file `input`. pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, mut test_args: Vec, maybe_sysroot: Option, - display_warnings: bool, linker: Option) -> isize { + display_warnings: bool, linker: Option, edition: Edition) -> isize { let input_str = match load_string(input) { Ok(s) => s, Err(LoadStringError::ReadFail) => return 1, @@ -151,7 +152,7 @@ pub fn test(input: &str, cfgs: Vec, libs: SearchPaths, externs: Externs, let mut collector = Collector::new(input.to_owned(), cfgs, libs, externs, true, opts, maybe_sysroot, None, Some(PathBuf::from(input)), - linker); + linker, edition); find_testable_code(&input_str, &mut collector, DUMMY_SP, None); test_args.insert(0, "rustdoctest".to_string()); testing::test_main(&test_args, collector.tests, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index ba0060521b7b..e2923df16999 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -123,7 +123,8 @@ pub fn run(input_path: &Path, maybe_sysroot, Some(codemap), None, - linker); + linker, + edition); { let map = hir::map::map_crate(&sess, &cstore, &mut hir_forest, &defs); @@ -183,8 +184,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, externs: Externs, should_panic: bool, no_run: bool, as_test_harness: bool, compile_fail: bool, mut error_codes: Vec, opts: &TestOptions, - maybe_sysroot: Option, - linker: Option) { + maybe_sysroot: Option, linker: Option, edition: Edition) { // the test harness wants its own `main` & top level functions, so // never wrap the test in `fn main() { ... }` let (test, line_offset) = make_test(test, Some(cratename), as_test_harness, opts); @@ -210,6 +210,10 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize, }, test: as_test_harness, unstable_features: UnstableFeatures::from_environment(), + debugging_opts: config::DebuggingOptions { + edition, + ..config::basic_debugging_options() + }, ..config::basic_options().clone() }; @@ -473,13 +477,14 @@ pub struct Collector { codemap: Option>, filename: Option, linker: Option, + edition: Edition, } impl Collector { pub fn new(cratename: String, cfgs: Vec, libs: SearchPaths, externs: Externs, use_headers: bool, opts: TestOptions, maybe_sysroot: Option, codemap: Option>, filename: Option, - linker: Option) -> Collector { + linker: Option, edition: Edition) -> Collector { Collector { tests: Vec::new(), names: Vec::new(), @@ -494,6 +499,7 @@ impl Collector { codemap, filename, linker, + edition, } } @@ -513,6 +519,7 @@ impl Collector { let opts = self.opts.clone(); let maybe_sysroot = self.maybe_sysroot.clone(); let linker = self.linker.clone(); + let edition = self.edition; debug!("Creating test {}: {}", name, test); self.tests.push(testing::TestDescAndFn { desc: testing::TestDesc { @@ -543,7 +550,8 @@ impl Collector { error_codes, &opts, maybe_sysroot, - linker) + linker, + edition) })) } { Ok(()) => (), From 0d15a3ee5402284450c312318871971f41603f80 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 28 Mar 2018 14:10:18 +0200 Subject: [PATCH 700/830] Clarify "length" wording in `Vec::with_capacity`. --- src/liballoc/vec.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 953f95876be1..f8fc3f2bda10 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -334,9 +334,10 @@ impl Vec { /// The vector will be able to hold exactly `capacity` elements without /// reallocating. If `capacity` is 0, the vector will not allocate. /// - /// It is important to note that this function does not specify the *length* - /// of the returned vector, but only the *capacity*. For an explanation of - /// the difference between length and capacity, see *[Capacity and reallocation]*. + /// It is important to note that although the returned vector has the + /// *capacity* specified, the vector will have a zero *length*. For an + /// explanation of the difference between length and capacity, see + /// *[Capacity and reallocation]*. /// /// [Capacity and reallocation]: #capacity-and-reallocation /// From 49fd71bea7bd3d8d11818503ca048227ffa1e758 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 22 Mar 2018 22:25:57 -0400 Subject: [PATCH 701/830] [incremental] Don't panic if decoding the cache fails If the cached data can't be loaded from disk, just issue a warning to the user so they know why compilation is taking longer than usual but don't fail the entire compilation since we can recover by ignorning the on disk cache. In the same way, if the disk cache can't be deserialized (because it has been corrupted for some reason), report the issue as a warning and continue without failing the compilation. `Decodable::decode()` tends to panic with various errors like "entered unreachable code" or "index out of range" if the input data is corrupted. Work around this by catching panics from the `decode()` calls when joining the thread and continuing without the cached data. Fixes #48847 --- src/librustc_driver/driver.rs | 4 +++- src/librustc_incremental/lib.rs | 1 + src/librustc_incremental/persist/load.rs | 3 ++- src/librustc_incremental/persist/mod.rs | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index a3115544f30b..c6ebc9926805 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -901,7 +901,9 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session, Some(future) => { let prev_graph = time(sess, "blocked while dep-graph loading finishes", || { future.open() - .expect("Could not join with background dep_graph thread") + .unwrap_or_else(|e| rustc_incremental::LoadResult::Error { + message: format!("could not decode incremental cache: {:?}", e) + }) .open(sess) }); DepGraph::new(prev_graph) diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs index d7ccf9d5562e..4b524287ca1c 100644 --- a/src/librustc_incremental/lib.rs +++ b/src/librustc_incremental/lib.rs @@ -39,6 +39,7 @@ pub use assert_dep_graph::assert_dep_graph; pub use persist::dep_graph_tcx_init; pub use persist::load_dep_graph; pub use persist::load_query_result_cache; +pub use persist::LoadResult; pub use persist::save_dep_graph; pub use persist::save_trans_partition; pub use persist::save_work_products; diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index 38468e29427b..44d6e532f79b 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -89,7 +89,8 @@ impl LoadResult { pub fn open(self, sess: &Session) -> PreviousDepGraph { match self { LoadResult::Error { message } => { - sess.fatal(&message) /* never returns */ + sess.warn(&message); + PreviousDepGraph::new(SerializedDepGraph::new()) }, LoadResult::DataOutOfDate => { if let Err(err) = delete_all_session_dir_contents(sess) { diff --git a/src/librustc_incremental/persist/mod.rs b/src/librustc_incremental/persist/mod.rs index 2f864aaefba8..755a550b5bca 100644 --- a/src/librustc_incremental/persist/mod.rs +++ b/src/librustc_incremental/persist/mod.rs @@ -27,6 +27,7 @@ pub use self::fs::prepare_session_directory; pub use self::load::dep_graph_tcx_init; pub use self::load::load_dep_graph; pub use self::load::load_query_result_cache; +pub use self::load::LoadResult; pub use self::save::save_dep_graph; pub use self::save::save_work_products; pub use self::work_product::save_trans_partition; From 0600d0f38d4998f1cacb3b97408224a0ee350db4 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Tue, 27 Mar 2018 10:20:27 -0700 Subject: [PATCH 702/830] Stabilize fs::read and fs::write --- src/libstd/fs.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 5caa703ee97e..b5476e9326db 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -251,8 +251,6 @@ fn initial_buffer_size(file: &File) -> usize { /// # Examples /// /// ```no_run -/// #![feature(fs_read_write)] -/// /// use std::fs; /// use std::net::SocketAddr; /// @@ -261,7 +259,7 @@ fn initial_buffer_size(file: &File) -> usize { /// # Ok(()) /// # } /// ``` -#[unstable(feature = "fs_read_write", issue = "46588")] +#[stable(feature = "fs_read_write_bytes", since = "1.27.0")] pub fn read>(path: P) -> io::Result> { let mut file = File::open(path)?; let mut bytes = Vec::with_capacity(initial_buffer_size(&file)); @@ -325,8 +323,6 @@ pub fn read_string>(path: P) -> io::Result { /// # Examples /// /// ```no_run -/// #![feature(fs_read_write)] -/// /// use std::fs; /// /// # fn foo() -> std::io::Result<()> { @@ -334,7 +330,7 @@ pub fn read_string>(path: P) -> io::Result { /// # Ok(()) /// # } /// ``` -#[unstable(feature = "fs_read_write", issue = "46588")] +#[stable(feature = "fs_read_write_bytes", since = "1.27.0")] pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> { File::create(path)?.write_all(contents.as_ref()) } From 9942012f41620e097d37a6d737584a3790f6b88b Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 27 Mar 2018 13:49:06 -0700 Subject: [PATCH 703/830] Run make tests for file resolution --- .../run-make-fulldeps/resolve-rename/Makefile | 7 +++++++ src/test/run-make-fulldeps/resolve-rename/bar.rs | 15 +++++++++++++++ src/test/run-make-fulldeps/resolve-rename/baz.rs | 15 +++++++++++++++ src/test/run-make-fulldeps/resolve-rename/foo.rs | 13 +++++++++++++ 4 files changed, 50 insertions(+) create mode 100644 src/test/run-make-fulldeps/resolve-rename/Makefile create mode 100644 src/test/run-make-fulldeps/resolve-rename/bar.rs create mode 100644 src/test/run-make-fulldeps/resolve-rename/baz.rs create mode 100644 src/test/run-make-fulldeps/resolve-rename/foo.rs diff --git a/src/test/run-make-fulldeps/resolve-rename/Makefile b/src/test/run-make-fulldeps/resolve-rename/Makefile new file mode 100644 index 000000000000..4b0c36d01b7a --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/Makefile @@ -0,0 +1,7 @@ +-include ../tools.mk + +all: + $(RUSTC) -C extra-filename=-hash foo.rs + $(RUSTC) bar.rs + mv $(TMPDIR)/libfoo-hash.rlib $(TMPDIR)/libfoo-another-hash.rlib + $(RUSTC) baz.rs diff --git a/src/test/run-make-fulldeps/resolve-rename/bar.rs b/src/test/run-make-fulldeps/resolve-rename/bar.rs new file mode 100644 index 000000000000..1552b45f2fc1 --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/bar.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +extern crate foo; + +pub fn bar() { foo::foo() } diff --git a/src/test/run-make-fulldeps/resolve-rename/baz.rs b/src/test/run-make-fulldeps/resolve-rename/baz.rs new file mode 100644 index 000000000000..27d801490e42 --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/baz.rs @@ -0,0 +1,15 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +extern crate bar; + +pub fn baz() { bar::bar() } diff --git a/src/test/run-make-fulldeps/resolve-rename/foo.rs b/src/test/run-make-fulldeps/resolve-rename/foo.rs new file mode 100644 index 000000000000..830c289b65f1 --- /dev/null +++ b/src/test/run-make-fulldeps/resolve-rename/foo.rs @@ -0,0 +1,13 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "rlib"] + +pub fn foo() {} From d8352af934ef751bb75d9ca310ed5b02ea0753cb Mon Sep 17 00:00:00 2001 From: bobtwinkles Date: Wed, 28 Mar 2018 14:43:05 -0400 Subject: [PATCH 704/830] Fix up tidy errors --- src/librustc_typeck/check/method/confirm.rs | 3 ++- src/librustc_typeck/check/mod.rs | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 8a37c11f191e..9c8c7d4df74f 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -17,7 +17,8 @@ use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, Ty}; use rustc::ty::subst::Subst; -use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, OverloadedDeref}; +use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref}; +use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::fold::TypeFoldable; use rustc::infer::{self, InferOk}; use syntax_pos::Span; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a377ff4d29d2..9ae7a74954b2 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2648,8 +2648,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // to, which is `expected_ty` if `rvalue_hint` returns an // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise. let coerce_ty = expected.and_then(|e| e.only_has_type(self)); - // We're processing function arguments so we definitely want to use two-phase borrows. - self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty), AllowTwoPhase::Yes); + // We're processing function arguments so we definitely want to use + // two-phase borrows. + self.demand_coerce(&arg, + checked_ty, + coerce_ty.unwrap_or(formal_ty), + AllowTwoPhase::Yes); // 3. Relate the expected type and the formal one, // if the expected type was used for the coercion. From 93f96be7d974de1b98e37b03a2ae5464b7a9564a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Mar 2018 10:48:00 +0200 Subject: [PATCH 705/830] Fix tooltip position --- src/librustdoc/html/static/rustdoc.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 9b899dd4517e..591645b73505 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -109,7 +109,6 @@ h3.impl, h3.method, h4.method, h3.type, h4.type, h4.associatedconstant { position: relative; } h3.impl, h3.method, h3.type { - margin-top: 15px; padding-left: 15px; } @@ -467,7 +466,10 @@ h4 > code, h3 > code, .invisible > code { font-size: 0.8em; } -.content .methods > div:not(.important-traits) { margin-left: 40px; } +.content .methods > div:not(.important-traits) { + margin-left: 40px; + margin-bottom: 15px; +} .content .impl-items .docblock, .content .impl-items .stability { margin-left: 40px; From 082e50d9869a3c159bb0ce1570b71ad0d86ea23d Mon Sep 17 00:00:00 2001 From: tinaun Date: Wed, 28 Mar 2018 17:39:27 -0400 Subject: [PATCH 706/830] Don't mention unstable constructors in release notes --- RELEASES.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 100de005990c..c44c501305f5 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -47,8 +47,6 @@ eg. `static MINUTE: Duration = Duration::from_secs(60);` - [`Duration::new`][47300] - [`Duration::from_secs`][47300] - [`Duration::from_millis`][47300] -- [`Duration::from_micros`][47300] -- [`Duration::from_nanos`][47300] Cargo ----- From 77c70a8c47f569481a364df42b2eae72733e7d4c Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 28 Mar 2018 22:43:23 +0100 Subject: [PATCH 707/830] rustbuild: Don't leak file handles when creating junctions on Windows This fixes building the compiler docs because stage1-rustc\x86_64-pc-windows-msvc\doc is used twice which doesn't work if we still have a handle from the first time. --- src/bootstrap/util.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 07941e588387..492eceef05c7 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -288,6 +288,7 @@ pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> { nOutBufferSize: DWORD, lpBytesReturned: LPDWORD, lpOverlapped: LPOVERLAPPED) -> BOOL; + fn CloseHandle(hObject: HANDLE) -> BOOL; } fn to_u16s>(s: S) -> io::Result> { @@ -341,11 +342,13 @@ pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> { &mut ret, ptr::null_mut()); - if res == 0 { + let out = if res == 0 { Err(io::Error::last_os_error()) } else { Ok(()) - } + }; + CloseHandle(h); + out } } } From d2b9a77bdfd3451f5e55f96d383f97aefb76e97e Mon Sep 17 00:00:00 2001 From: tinaun Date: Sat, 3 Mar 2018 17:07:48 -0500 Subject: [PATCH 708/830] check impl trait first --- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/mod.rs | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index b777ac30920c..c7cebda95a1c 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -309,7 +309,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { // variables. let method_generics = self.tcx.generics_of(pick.item.def_id); let mut fn_segment = Some((segment, method_generics)); - self.fcx.check_path_parameter_count(self.span, &mut fn_segment, true); + self.fcx.check_path_parameter_count(self.span, &mut fn_segment, true, false); // Create subst for early-bound lifetime parameters, combining // parameters from the type and those from the method. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index db5a458bb8ce..36ed6864f3af 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4764,9 +4764,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // variables. If the user provided some types, we may still need // to add defaults. If the user provided *too many* types, that's // a problem. - self.check_path_parameter_count(span, &mut type_segment, false); - self.check_path_parameter_count(span, &mut fn_segment, false); - self.check_impl_trait(span, &mut fn_segment); + let supress_mismatch = self.check_impl_trait(span, &mut fn_segment); + self.check_path_parameter_count(span, &mut type_segment, false, supress_mismatch); + self.check_path_parameter_count(span, &mut fn_segment, false, supress_mismatch); let (fn_start, has_self) = match (type_segment, fn_segment) { (_, Some((_, generics))) => { @@ -4919,7 +4919,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn check_path_parameter_count(&self, span: Span, segment: &mut Option<(&hir::PathSegment, &ty::Generics)>, - is_method_call: bool) { + is_method_call: bool, + supress_mismatch_error: bool) { let (lifetimes, types, infer_types, bindings) = segment.map_or( (&[][..], &[][..], true, &[][..]), |(s, _)| s.parameters.as_ref().map_or( @@ -4959,7 +4960,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // type parameters, we force instantiate_value_path to // use inference variables instead of the provided types. *segment = None; - } else if types.len() < required_len && !infer_types { + } else if types.len() < required_len && !infer_types && !supress_mismatch_error { let expected_text = count_type_params(required_len); let actual_text = count_type_params(types.len()); struct_span_err!(self.tcx.sess, span, E0089, @@ -5026,10 +5027,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// Report error if there is an explicit type parameter when using `impl Trait`. fn check_impl_trait(&self, span: Span, - segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) { + segment: &mut Option<(&hir::PathSegment, &ty::Generics)>) + -> bool { use hir::SyntheticTyParamKind::*; - segment.map(|(path_segment, generics)| { + let segment = segment.map(|(path_segment, generics)| { let explicit = !path_segment.infer_types; let impl_trait = generics.types.iter() .any(|ty_param| { @@ -5050,7 +5052,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err.emit(); } + + impl_trait }); + + segment.unwrap_or(false) } // Resolves `typ` by a single level if `typ` is a type variable. From 97e0dc330fb4dfc3fc5161fbba1f0b4193d80bc9 Mon Sep 17 00:00:00 2001 From: tinaun Date: Sat, 3 Mar 2018 17:32:47 -0500 Subject: [PATCH 709/830] added test --- .../ui/impl-trait/universal-issue-48703.rs | 19 +++++++++++++++++++ .../impl-trait/universal-issue-48703.stderr | 9 +++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/impl-trait/universal-issue-48703.rs create mode 100644 src/test/ui/impl-trait/universal-issue-48703.stderr diff --git a/src/test/ui/impl-trait/universal-issue-48703.rs b/src/test/ui/impl-trait/universal-issue-48703.rs new file mode 100644 index 000000000000..e017b37b7b73 --- /dev/null +++ b/src/test/ui/impl-trait/universal-issue-48703.rs @@ -0,0 +1,19 @@ +// 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. + +#![feature(universal_impl_trait)] + +use std::fmt::Debug; + +fn foo(x: impl Debug) { } + +fn main() { + foo::('a'); //~ ERROR cannot provide explicit type parameters +} diff --git a/src/test/ui/impl-trait/universal-issue-48703.stderr b/src/test/ui/impl-trait/universal-issue-48703.stderr new file mode 100644 index 000000000000..ea509684f9ef --- /dev/null +++ b/src/test/ui/impl-trait/universal-issue-48703.stderr @@ -0,0 +1,9 @@ +error[E0632]: cannot provide explicit type parameters when `impl Trait` is used in argument position. + --> $DIR/universal-issue-48703.rs:18:5 + | +LL | foo::('a'); //~ ERROR cannot provide explicit type parameters + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0632`. From e6e6bd27d563b9a53687433feb3d4d4672dafd66 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Wed, 28 Mar 2018 17:25:39 +0200 Subject: [PATCH 710/830] Stabilize underscore lifetimes --- src/librustc/lib.rs | 2 +- src/librustc_data_structures/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_traits/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 13 +++++------- .../expect-fn-supply-fn-multiple.rs | 1 - .../expect-fn-supply-fn.rs | 2 -- .../underscore-lifetime-binders.rs | 2 -- .../underscore-lifetime-elison-mismatch.rs | 2 -- src/test/run-pass/impl-trait/lifetimes.rs | 1 - src/test/run-pass/underscore-lifetimes.rs | 2 -- src/test/ui/error-codes/E0637.rs | 1 - src/test/ui/error-codes/E0637.stderr | 6 +++--- .../ui/feature-gate-in_band_lifetimes-impl.rs | 1 - ...feature-gate-in_band_lifetimes-impl.stderr | 4 ++-- .../ui/feature-gate-underscore-lifetimes.rs | 20 ------------------- .../feature-gate-underscore-lifetimes.stderr | 11 ---------- .../ui/in-band-lifetimes/impl/assoc-type.rs | 1 - .../in-band-lifetimes/impl/assoc-type.stderr | 4 ++-- .../ui/in-band-lifetimes/impl/dyn-trait.rs | 1 - .../in-band-lifetimes/impl/dyn-trait.stderr | 6 +++--- .../ui/in-band-lifetimes/impl/path-elided.rs | 1 - .../in-band-lifetimes/impl/path-elided.stderr | 2 +- .../in-band-lifetimes/impl/path-underscore.rs | 1 - .../in-band-lifetimes/impl/ref-underscore.rs | 1 - .../ui/in-band-lifetimes/impl/trait-elided.rs | 1 - .../impl/trait-elided.stderr | 2 +- .../impl/trait-underscore.rs | 1 - .../dyn-trait-underscore-in-struct.rs | 1 - .../dyn-trait-underscore-in-struct.stderr | 4 ++-- .../dyn-trait-underscore.rs | 1 - .../dyn-trait-underscore.stderr | 8 ++++---- 32 files changed, 27 insertions(+), 82 deletions(-) delete mode 100644 src/test/ui/feature-gate-underscore-lifetimes.rs delete mode 100644 src/test/ui/feature-gate-underscore-lifetimes.stderr diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index ae8ae9404bc8..dcad8132c2b2 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -68,7 +68,7 @@ #![feature(slice_patterns)] #![feature(specialization)] #![feature(unboxed_closures)] -#![feature(underscore_lifetimes)] +#![cfg_attr(stage0, feature(underscore_lifetimes))] #![cfg_attr(stage0, feature(universal_impl_trait))] #![feature(trace_macros)] #![feature(trusted_len)] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 378a06dd9120..622fb423b51e 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -30,7 +30,7 @@ #![cfg_attr(stage0, feature(i128_type, i128))] #![feature(specialization)] #![feature(optin_builtin_traits)] -#![feature(underscore_lifetimes)] +#![cfg_attr(stage0, feature(underscore_lifetimes))] #![feature(macro_vis_matcher)] #![feature(allow_internal_unstable)] #![cfg_attr(stage0, feature(universal_impl_trait))] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 262e5f608ca6..7af3a397666e 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -37,7 +37,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(placement_in_syntax)] #![feature(collection_placement)] #![feature(nonzero)] -#![feature(underscore_lifetimes)] +#![cfg_attr(stage0, feature(underscore_lifetimes))] #![cfg_attr(stage0, feature(never_type))] #![feature(inclusive_range_fields)] diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs index 0a21cc597e63..90f368edeeca 100644 --- a/src/librustc_traits/lib.rs +++ b/src/librustc_traits/lib.rs @@ -15,7 +15,7 @@ #![feature(crate_visibility_modifier)] #![cfg_attr(stage0, feature(match_default_bindings))] -#![feature(underscore_lifetimes)] +#![cfg_attr(stage0, feature(underscore_lifetimes))] #[macro_use] extern crate log; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ce8c613dc8bb..526608d07aae 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -385,6 +385,9 @@ declare_features! ( // allow `'_` placeholder lifetimes (active, underscore_lifetimes, "1.22.0", Some(44524), None), + // Default match binding modes (RFC 2005) + (active, match_default_bindings, "1.22.0", Some(42640), None), + // Trait object syntax with `dyn` prefix (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), @@ -562,6 +565,8 @@ declare_features! ( (accepted, i128_type, "1.26.0", Some(35118), None), // Default match binding modes (RFC 2005) (accepted, match_default_bindings, "1.26.0", Some(42640), None), + // allow `'_` placeholder lifetimes + (accepted, underscore_lifetimes, "1.26.0", Some(44524), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1792,14 +1797,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_generic_param(self, param) } - - fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) { - if lt.ident.name == keywords::UnderscoreLifetime.name() { - gate_feature_post!(&self, underscore_lifetimes, lt.span, - "underscore lifetimes are unstable"); - } - visit::walk_lifetime(self, lt) - } } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], diff --git a/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn-multiple.rs b/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn-multiple.rs index f1b198a05917..124e55ea23a0 100644 --- a/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn-multiple.rs +++ b/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn-multiple.rs @@ -10,7 +10,6 @@ // must-compile-successfully -#![feature(underscore_lifetimes)] #![allow(warnings)] type Different<'a, 'b> = &'a mut (&'a (), &'b ()); diff --git a/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs b/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs index 645fd1f80bab..63284c98020f 100644 --- a/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs +++ b/src/test/compile-fail/closure-expected-type/expect-fn-supply-fn.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(underscore_lifetimes)] - fn with_closure_expecting_fn_with_free_region(_: F) where F: for<'a> FnOnce(fn(&'a u32), &i32) { diff --git a/src/test/compile-fail/underscore-lifetime-binders.rs b/src/test/compile-fail/underscore-lifetime-binders.rs index 99b6e036f33e..eb00ab5f67af 100644 --- a/src/test/compile-fail/underscore-lifetime-binders.rs +++ b/src/test/compile-fail/underscore-lifetime-binders.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(underscore_lifetimes)] - struct Foo<'a>(&'a u8); struct Baz<'a>(&'_ &'a u8); //~ ERROR missing lifetime specifier diff --git a/src/test/compile-fail/underscore-lifetime-elison-mismatch.rs b/src/test/compile-fail/underscore-lifetime-elison-mismatch.rs index a1c4e4a1fd93..b36c8eb324e1 100644 --- a/src/test/compile-fail/underscore-lifetime-elison-mismatch.rs +++ b/src/test/compile-fail/underscore-lifetime-elison-mismatch.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(underscore_lifetimes)] - fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); } //~ ERROR lifetime mismatch fn main() {} diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs index 1b50ceefbe1a..d126d795d909 100644 --- a/src/test/run-pass/impl-trait/lifetimes.rs +++ b/src/test/run-pass/impl-trait/lifetimes.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(underscore_lifetimes)] #![allow(warnings)] use std::fmt::Debug; diff --git a/src/test/run-pass/underscore-lifetimes.rs b/src/test/run-pass/underscore-lifetimes.rs index ed0369353bcd..4dd1a565c9f1 100644 --- a/src/test/run-pass/underscore-lifetimes.rs +++ b/src/test/run-pass/underscore-lifetimes.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(underscore_lifetimes)] - struct Foo<'a>(&'a u8); fn foo(x: &u8) -> Foo<'_> { diff --git a/src/test/ui/error-codes/E0637.rs b/src/test/ui/error-codes/E0637.rs index 455529b088a2..ee6a978d169a 100644 --- a/src/test/ui/error-codes/E0637.rs +++ b/src/test/ui/error-codes/E0637.rs @@ -7,7 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(underscore_lifetimes)] struct Foo<'a: '_>(&'a u8); //~ ERROR invalid lifetime bound name: `'_` fn foo<'a: '_>(_: &'a u8) {} //~ ERROR invalid lifetime bound name: `'_` diff --git a/src/test/ui/error-codes/E0637.stderr b/src/test/ui/error-codes/E0637.stderr index b8c926efb45a..245729376df3 100644 --- a/src/test/ui/error-codes/E0637.stderr +++ b/src/test/ui/error-codes/E0637.stderr @@ -1,17 +1,17 @@ error[E0637]: invalid lifetime bound name: `'_` - --> $DIR/E0637.rs:12:16 + --> $DIR/E0637.rs:11:16 | LL | struct Foo<'a: '_>(&'a u8); //~ ERROR invalid lifetime bound name: `'_` | ^^ `'_` is a reserved lifetime name error[E0637]: invalid lifetime bound name: `'_` - --> $DIR/E0637.rs:13:12 + --> $DIR/E0637.rs:12:12 | LL | fn foo<'a: '_>(_: &'a u8) {} //~ ERROR invalid lifetime bound name: `'_` | ^^ `'_` is a reserved lifetime name error[E0637]: invalid lifetime bound name: `'_` - --> $DIR/E0637.rs:16:10 + --> $DIR/E0637.rs:15:10 | LL | impl<'a: '_> Bar<'a> { //~ ERROR invalid lifetime bound name: `'_` | ^^ `'_` is a reserved lifetime name diff --git a/src/test/ui/feature-gate-in_band_lifetimes-impl.rs b/src/test/ui/feature-gate-in_band_lifetimes-impl.rs index a02b3e800097..3eb2ac1b0085 100644 --- a/src/test/ui/feature-gate-in_band_lifetimes-impl.rs +++ b/src/test/ui/feature-gate-in_band_lifetimes-impl.rs @@ -9,7 +9,6 @@ // except according to those terms. #![allow(warnings)] -#![feature(underscore_lifetimes)] trait MyTrait<'a> { } diff --git a/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr b/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr index e32a06c3ce45..95bf81f41f80 100644 --- a/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr +++ b/src/test/ui/feature-gate-in_band_lifetimes-impl.stderr @@ -1,11 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/feature-gate-in_band_lifetimes-impl.rs:16:26 + --> $DIR/feature-gate-in_band_lifetimes-impl.rs:15:26 | LL | impl<'a> MyTrait<'a> for &u32 { } | ^ expected lifetime parameter error[E0106]: missing lifetime specifier - --> $DIR/feature-gate-in_band_lifetimes-impl.rs:19:18 + --> $DIR/feature-gate-in_band_lifetimes-impl.rs:18:18 | LL | impl<'a> MyTrait<'_> for &'a f32 { } | ^^ expected lifetime parameter diff --git a/src/test/ui/feature-gate-underscore-lifetimes.rs b/src/test/ui/feature-gate-underscore-lifetimes.rs deleted file mode 100644 index 9da50c5c8771..000000000000 --- a/src/test/ui/feature-gate-underscore-lifetimes.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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. - -struct Foo<'a>(&'a u8); - -fn foo(x: &u8) -> Foo<'_> { //~ ERROR underscore lifetimes are unstable - Foo(x) -} - -fn main() { - let x = 5; - let _ = foo(&x); -} diff --git a/src/test/ui/feature-gate-underscore-lifetimes.stderr b/src/test/ui/feature-gate-underscore-lifetimes.stderr deleted file mode 100644 index c1cddcd763eb..000000000000 --- a/src/test/ui/feature-gate-underscore-lifetimes.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: underscore lifetimes are unstable (see issue #44524) - --> $DIR/feature-gate-underscore-lifetimes.rs:13:23 - | -LL | fn foo(x: &u8) -> Foo<'_> { //~ ERROR underscore lifetimes are unstable - | ^^ - | - = help: add #![feature(underscore_lifetimes)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/in-band-lifetimes/impl/assoc-type.rs b/src/test/ui/in-band-lifetimes/impl/assoc-type.rs index 54f38b2e729b..ab35331b279b 100644 --- a/src/test/ui/in-band-lifetimes/impl/assoc-type.rs +++ b/src/test/ui/in-band-lifetimes/impl/assoc-type.rs @@ -14,7 +14,6 @@ #![allow(warnings)] #![feature(in_band_lifetimes)] -#![feature(underscore_lifetimes)] trait MyTrait { type Output; diff --git a/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr b/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr index 909b86daef0f..59b2cfd2226d 100644 --- a/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr +++ b/src/test/ui/in-band-lifetimes/impl/assoc-type.stderr @@ -1,11 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/assoc-type.rs:24:19 + --> $DIR/assoc-type.rs:23:19 | LL | type Output = &i32; | ^ expected lifetime parameter error[E0106]: missing lifetime specifier - --> $DIR/assoc-type.rs:29:20 + --> $DIR/assoc-type.rs:28:20 | LL | type Output = &'_ i32; | ^^ expected lifetime parameter diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs b/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs index e839248b0e31..a504bae2e600 100644 --- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs +++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.rs @@ -15,7 +15,6 @@ #![feature(dyn_trait)] #![feature(in_band_lifetimes)] -#![feature(underscore_lifetimes)] use std::fmt::Debug; diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr index 0054ca3d1a5b..9d6a318c0751 100644 --- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr +++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.stderr @@ -1,11 +1,11 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/dyn-trait.rs:34:16 + --> $DIR/dyn-trait.rs:33:16 | LL | static_val(x); //~ ERROR cannot infer | ^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 33:1... - --> $DIR/dyn-trait.rs:33:1 +note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 32:1... + --> $DIR/dyn-trait.rs:32:1 | LL | fn with_dyn_debug_static<'a>(x: Box) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/in-band-lifetimes/impl/path-elided.rs b/src/test/ui/in-band-lifetimes/impl/path-elided.rs index fa1b45238895..8a758b124ba5 100644 --- a/src/test/ui/in-band-lifetimes/impl/path-elided.rs +++ b/src/test/ui/in-band-lifetimes/impl/path-elided.rs @@ -10,7 +10,6 @@ #![allow(warnings)] #![feature(in_band_lifetimes)] -#![feature(underscore_lifetimes)] trait MyTrait { } diff --git a/src/test/ui/in-band-lifetimes/impl/path-elided.stderr b/src/test/ui/in-band-lifetimes/impl/path-elided.stderr index 19e69c61a033..6c1d72411bf5 100644 --- a/src/test/ui/in-band-lifetimes/impl/path-elided.stderr +++ b/src/test/ui/in-band-lifetimes/impl/path-elided.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/path-elided.rs:19:18 + --> $DIR/path-elided.rs:18:18 | LL | impl MyTrait for Foo { | ^^^ expected lifetime parameter diff --git a/src/test/ui/in-band-lifetimes/impl/path-underscore.rs b/src/test/ui/in-band-lifetimes/impl/path-underscore.rs index 56f2d93d9e0a..756991d97a53 100644 --- a/src/test/ui/in-band-lifetimes/impl/path-underscore.rs +++ b/src/test/ui/in-band-lifetimes/impl/path-underscore.rs @@ -15,7 +15,6 @@ #![allow(warnings)] #![feature(in_band_lifetimes)] -#![feature(underscore_lifetimes)] trait MyTrait { } diff --git a/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs b/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs index 1b1035abeba3..99708afff351 100644 --- a/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs +++ b/src/test/ui/in-band-lifetimes/impl/ref-underscore.rs @@ -15,7 +15,6 @@ #![allow(warnings)] #![feature(in_band_lifetimes)] -#![feature(underscore_lifetimes)] trait MyTrait { } diff --git a/src/test/ui/in-band-lifetimes/impl/trait-elided.rs b/src/test/ui/in-band-lifetimes/impl/trait-elided.rs index 7594d66e0783..e0709ab6dd07 100644 --- a/src/test/ui/in-band-lifetimes/impl/trait-elided.rs +++ b/src/test/ui/in-band-lifetimes/impl/trait-elided.rs @@ -10,7 +10,6 @@ #![allow(warnings)] #![feature(in_band_lifetimes)] -#![feature(underscore_lifetimes)] trait MyTrait<'a> { } diff --git a/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr b/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr index bb301882868a..fe3ded8e04c3 100644 --- a/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr +++ b/src/test/ui/in-band-lifetimes/impl/trait-elided.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/trait-elided.rs:17:6 + --> $DIR/trait-elided.rs:16:6 | LL | impl MyTrait for u32 { | ^^^^^^^ expected lifetime parameter diff --git a/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs b/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs index 077e33c1efde..971fd1fe759b 100644 --- a/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs +++ b/src/test/ui/in-band-lifetimes/impl/trait-underscore.rs @@ -16,7 +16,6 @@ #![allow(warnings)] #![feature(in_band_lifetimes)] -#![feature(underscore_lifetimes)] trait MyTrait<'a> { } diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs index d10541ad33b5..e573ad8fc1f0 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.rs @@ -14,7 +14,6 @@ // cc #48468 #![feature(dyn_trait)] -#![feature(underscore_lifetimes)] use std::fmt::Debug; diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr index a88ecb18dd6f..6d777841f031 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore-in-struct.stderr @@ -1,11 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/dyn-trait-underscore-in-struct.rs:22:24 + --> $DIR/dyn-trait-underscore-in-struct.rs:21:24 | LL | x: Box, //~ ERROR missing lifetime specifier | ^^ expected lifetime parameter error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound - --> $DIR/dyn-trait-underscore-in-struct.rs:22:12 + --> $DIR/dyn-trait-underscore-in-struct.rs:21:12 | LL | x: Box, //~ ERROR missing lifetime specifier | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs b/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs index c24762201004..9640d3465978 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.rs @@ -14,7 +14,6 @@ // cc #48468 #![feature(dyn_trait)] -#![feature(underscore_lifetimes)] fn a(items: &[T]) -> Box> { // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index cb3035f42a04..f1e59aed54a3 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -1,11 +1,11 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements - --> $DIR/dyn-trait-underscore.rs:21:20 + --> $DIR/dyn-trait-underscore.rs:20:20 | LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime | ^^^^ | -note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 19:1... - --> $DIR/dyn-trait-underscore.rs:19:1 +note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 18:1... + --> $DIR/dyn-trait-underscore.rs:18:1 | LL | / fn a(items: &[T]) -> Box> { LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` @@ -13,7 +13,7 @@ LL | | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime LL | | } | |_^ note: ...so that reference does not outlive borrowed content - --> $DIR/dyn-trait-underscore.rs:21:14 + --> $DIR/dyn-trait-underscore.rs:20:14 | LL | Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime | ^^^^^ From 262be13643cf5e3ff4f4e880b2dee601d4740fd8 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 29 Mar 2018 09:34:39 +0900 Subject: [PATCH 711/830] Use f{32,64}::to_bits for is_zero test in vec::SpecFromElem vec::SpecFromElem provides an optimization to use calloc to fill a Vec when the element given to fill the Vec is represented by 0. For floats, the test for that currently used is `x == 0. && x.is_sign_positive()`. When compiled in a standalone function, rustc generates the following assembly: ``` xorps xmm1, xmm1 ucomisd xmm0, xmm1 setnp al sete cl and cl, al movq rax, xmm0 test rax, rax setns al and al, cl ret ``` A simpler test telling us whether the value is represented by 0, is `x.to_bits() == 0`, which rustc compiles to: ``` movq rax, xmm0 test rax, rax sete al ret ``` Not that the test is hot in any way, but it also makes it clearer what the intent in the rust code is. --- src/liballoc/vec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 953f95876be1..3c2f91d08e35 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1574,8 +1574,8 @@ impl_spec_from_elem!(u64, |x| x == 0); impl_spec_from_elem!(u128, |x| x == 0); impl_spec_from_elem!(usize, |x| x == 0); -impl_spec_from_elem!(f32, |x: f32| x == 0. && x.is_sign_positive()); -impl_spec_from_elem!(f64, |x: f64| x == 0. && x.is_sign_positive()); +impl_spec_from_elem!(f32, |x: f32| x.to_bits() == 0); +impl_spec_from_elem!(f64, |x: f64| x.to_bits() == 0); //////////////////////////////////////////////////////////////////////////////// // Common trait implementations for Vec From 6462c0bd7f03c9f1310ea9e4d259462e753e967e Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 29 Mar 2018 11:51:52 +0900 Subject: [PATCH 712/830] Remove unnecessary use core::hash in liballoc/boxed.rs It' only used for hash::Hasher, but Hasher is also imported. --- src/liballoc/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index bfd806f99e78..fdc3ef4efb86 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -62,7 +62,7 @@ use core::any::Any; use core::borrow; use core::cmp::Ordering; use core::fmt; -use core::hash::{self, Hash, Hasher}; +use core::hash::{Hash, Hasher}; use core::iter::FusedIterator; use core::marker::{self, Unpin, Unsize}; use core::mem::{self, Pin}; @@ -508,7 +508,7 @@ impl Eq for Box {} #[stable(feature = "rust1", since = "1.0.0")] impl Hash for Box { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { (**self).hash(state); } } From bd8154784ea205d78c30c18a5908e97718f7a489 Mon Sep 17 00:00:00 2001 From: Chris Manchester Date: Tue, 13 Mar 2018 11:58:53 -0700 Subject: [PATCH 713/830] Take the original extra-filename passed to a crate into account when resolving it as a dependency. Fixes #46816 --- src/librustc/dep_graph/dep_node.rs | 1 + src/librustc/ty/maps/config.rs | 6 ++++++ src/librustc/ty/maps/mod.rs | 1 + src/librustc/ty/maps/plumbing.rs | 1 + src/librustc_metadata/creader.rs | 22 +++++++++++++------- src/librustc_metadata/cstore_impl.rs | 3 +++ src/librustc_metadata/encoder.rs | 2 ++ src/librustc_metadata/locator.rs | 30 ++++++++++++++++++++++------ src/librustc_metadata/schema.rs | 5 ++++- 9 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 42cda6a05a1a..d1f3736556c5 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -589,6 +589,7 @@ define_dep_nodes!( <'tcx> [input] CrateDisambiguator(CrateNum), [input] CrateHash(CrateNum), [input] OriginalCrateName(CrateNum), + [input] ExtraFileName(CrateNum), [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId }, [] AllTraitImplementations(CrateNum), diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index bb9467305e33..a08cd57b1f7e 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -466,6 +466,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::original_crate_name<'tcx> { } } +impl<'tcx> QueryDescription<'tcx> for queries::extra_filename<'tcx> { + fn describe(_tcx: TyCtxt, _: CrateNum) -> String { + format!("looking up the extra filename for a crate") + } +} + impl<'tcx> QueryDescription<'tcx> for queries::implementations_of_trait<'tcx> { fn describe(_tcx: TyCtxt, _: (CrateNum, DefId)) -> String { format!("looking up implementations of a trait in a crate") diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2bfb68703292..8651619705b4 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -328,6 +328,7 @@ define_maps! { <'tcx> [] fn crate_disambiguator: CrateDisambiguator(CrateNum) -> CrateDisambiguator, [] fn crate_hash: CrateHash(CrateNum) -> Svh, [] fn original_crate_name: OriginalCrateName(CrateNum) -> Symbol, + [] fn extra_filename: ExtraFileName(CrateNum) -> String, [] fn implementations_of_trait: implementations_of_trait_node((CrateNum, DefId)) -> Lrc>, diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 50a19526ba8c..fa69eb8e5bc6 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -881,6 +881,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CrateDisambiguator => { force!(crate_disambiguator, krate!()); } DepKind::CrateHash => { force!(crate_hash, krate!()); } DepKind::OriginalCrateName => { force!(original_crate_name, krate!()); } + DepKind::ExtraFileName => { force!(extra_filename, krate!()); } DepKind::AllTraitImplementations => { force!(all_trait_implementations, krate!()); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 13ebb5f61660..86f495c5fac3 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -262,6 +262,7 @@ impl<'a> CrateLoader<'a> { ident: Symbol, name: Symbol, hash: Option<&Svh>, + extra_filename: Option<&str>, span: Span, path_kind: PathKind, mut dep_kind: DepKind) @@ -277,6 +278,7 @@ impl<'a> CrateLoader<'a> { ident, crate_name: name, hash: hash.map(|a| &*a), + extra_filename: extra_filename, filesearch: self.sess.target_filesearch(path_kind), target: &self.sess.target.target, triple: &self.sess.opts.target_triple, @@ -409,7 +411,8 @@ impl<'a> CrateLoader<'a> { ::std::iter::once(krate).chain(crate_root.crate_deps .decode(metadata) .map(|dep| { - debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash); + info!("resolving dep crate {} hash: `{}` extra filename: `{}`", dep.name, dep.hash, + dep.extra_filename); if dep.kind == DepKind::UnexportedMacrosOnly { return krate; } @@ -418,7 +421,8 @@ impl<'a> CrateLoader<'a> { _ => dep.kind, }; let (local_cnum, ..) = self.resolve_crate( - root, dep.name, dep.name, Some(&dep.hash), span, PathKind::Dependency, dep_kind, + root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span, + PathKind::Dependency, dep_kind, ); local_cnum })).collect() @@ -437,6 +441,7 @@ impl<'a> CrateLoader<'a> { ident: orig_name, crate_name: rename, hash: None, + extra_filename: None, filesearch: self.sess.host_filesearch(PathKind::Crate), target: &self.sess.host, triple: &host_triple, @@ -664,7 +669,7 @@ impl<'a> CrateLoader<'a> { let dep_kind = DepKind::Implicit; let (cnum, data) = - self.resolve_crate(&None, name, name, None, DUMMY_SP, PathKind::Crate, dep_kind); + self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind); // Sanity check the loaded crate to ensure it is indeed a panic runtime // and the panic strategy is indeed what we thought it was. @@ -771,7 +776,7 @@ impl<'a> CrateLoader<'a> { let symbol = Symbol::intern(name); let dep_kind = DepKind::Explicit; let (_, data) = - self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, + self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP, PathKind::Crate, dep_kind); // Sanity check the loaded crate to ensure it is indeed a sanitizer runtime @@ -794,7 +799,7 @@ impl<'a> CrateLoader<'a> { let symbol = Symbol::intern("profiler_builtins"); let dep_kind = DepKind::Implicit; let (_, data) = - self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP, + self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP, PathKind::Crate, dep_kind); // Sanity check the loaded crate to ensure it is indeed a profiler runtime @@ -909,6 +914,7 @@ impl<'a> CrateLoader<'a> { name, name, None, + None, DUMMY_SP, PathKind::Crate, DepKind::Implicit); @@ -1059,7 +1065,8 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { }; let (cnum, ..) = self.resolve_crate( - &None, item.ident.name, orig_name, None, item.span, PathKind::Crate, dep_kind, + &None, item.ident.name, orig_name, None, None, + item.span, PathKind::Crate, dep_kind, ); let def_id = definitions.opt_local_def_id(item.id).unwrap(); @@ -1074,6 +1081,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { } fn resolve_crate_from_path(&mut self, name: Symbol, span: Span) -> CrateNum { - self.resolve_crate(&None, name, name, None, span, PathKind::Crate, DepKind::Explicit).0 + self.resolve_crate(&None, name, name, None, None, span, PathKind::Crate, + DepKind::Explicit).0 } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 5fd8ebaa9b4a..f63edf07fa8b 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -213,6 +213,9 @@ provide! { <'tcx> tcx, def_id, other, cdata, crate_hash => { cdata.hash() } original_crate_name => { cdata.name() } + extra_filename => { cdata.root.extra_filename.clone() } + + implementations_of_trait => { let mut result = vec![]; let filter = Some(other); diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 39de1ec852ec..0da6fc5b9eda 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -462,6 +462,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let has_global_allocator = tcx.sess.has_global_allocator.get(); let root = self.lazy(&CrateRoot { name: tcx.crate_name(LOCAL_CRATE), + extra_filename: tcx.sess.opts.cg.extra_filename.clone(), triple: tcx.sess.opts.target_triple.clone(), hash: link_meta.crate_hash, disambiguator: tcx.sess.local_crate_disambiguator(), @@ -1357,6 +1358,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { name: self.tcx.original_crate_name(cnum), hash: self.tcx.crate_hash(cnum), kind: self.tcx.dep_kind(cnum), + extra_filename: self.tcx.extra_filename(cnum), }; (cnum, dep) }) diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 41e10b4755d0..f553c55ae56f 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -83,7 +83,10 @@ //! 1. Does the filename match an rlib/dylib pattern? That is to say, does the //! filename have the right prefix/suffix? //! 2. Does the filename have the right prefix for the crate name being queried? -//! This is filtering for files like `libfoo*.rlib` and such. +//! This is filtering for files like `libfoo*.rlib` and such. If the crate +//! we're looking for was originally compiled with -C extra-filename, the +//! extra filename will be included in this prefix to reduce reading +//! metadata from crates that would otherwise share our prefix. //! 3. Is the file an actual rust library? This is done by loading the metadata //! from the library and making sure it's actually there. //! 4. Does the name in the metadata agree with the name of the library? @@ -236,6 +239,7 @@ use syntax_pos::Span; use rustc_back::target::{Target, TargetTriple}; use std::cmp; +use std::collections::HashSet; use std::fmt; use std::fs; use std::io::{self, Read}; @@ -256,6 +260,7 @@ pub struct Context<'a> { pub ident: Symbol, pub crate_name: Symbol, pub hash: Option<&'a Svh>, + pub extra_filename: Option<&'a str>, // points to either self.sess.target.target or self.sess.host, must match triple pub target: &'a Target, pub triple: &'a TargetTriple, @@ -303,7 +308,12 @@ impl CratePaths { impl<'a> Context<'a> { pub fn maybe_load_library_crate(&mut self) -> Option { - self.find_library_crate() + let mut seen_paths = HashSet::new(); + match self.extra_filename { + Some(s) => self.find_library_crate(s, &mut seen_paths) + .or_else(|| self.find_library_crate("", &mut seen_paths)), + None => self.find_library_crate("", &mut seen_paths) + } } pub fn report_errs(&mut self) -> ! { @@ -419,7 +429,10 @@ impl<'a> Context<'a> { unreachable!(); } - fn find_library_crate(&mut self) -> Option { + fn find_library_crate(&mut self, + extra_prefix: &str, + seen_paths: &mut HashSet) + -> Option { // If an SVH is specified, then this is a transitive dependency that // must be loaded via -L plus some filtering. if self.hash.is_none() { @@ -434,9 +447,9 @@ impl<'a> Context<'a> { let staticpair = self.staticlibname(); // want: crate_name.dir_part() + prefix + crate_name.file_part + "-" - let dylib_prefix = format!("{}{}", dypair.0, self.crate_name); - let rlib_prefix = format!("lib{}", self.crate_name); - let staticlib_prefix = format!("{}{}", staticpair.0, self.crate_name); + let dylib_prefix = format!("{}{}{}", dypair.0, self.crate_name, extra_prefix); + let rlib_prefix = format!("lib{}{}", self.crate_name, extra_prefix); + let staticlib_prefix = format!("{}{}{}", staticpair.0, self.crate_name, extra_prefix); let mut candidates = FxHashMap(); let mut staticlibs = vec![]; @@ -476,6 +489,7 @@ impl<'a> Context<'a> { } return FileDoesntMatch; }; + info!("lib candidate: {}", path.display()); let hash_str = hash.to_string(); @@ -484,6 +498,10 @@ impl<'a> Context<'a> { let (ref mut rlibs, ref mut rmetas, ref mut dylibs) = *slot; fs::canonicalize(path) .map(|p| { + if seen_paths.contains(&p) { + return FileDoesntMatch + }; + seen_paths.insert(p.clone()); match found_kind { CrateFlavor::Rlib => { rlibs.insert(p, kind); } CrateFlavor::Rmeta => { rmetas.insert(p, kind); } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index d04a4001c502..a7ee0e7e9a96 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -188,6 +188,7 @@ pub enum LazyState { pub struct CrateRoot { pub name: Symbol, pub triple: TargetTriple, + pub extra_filename: String, pub hash: hir::svh::Svh, pub disambiguator: CrateDisambiguator, pub panic_strategy: PanicStrategy, @@ -216,12 +217,14 @@ pub struct CrateDep { pub name: ast::Name, pub hash: hir::svh::Svh, pub kind: DepKind, + pub extra_filename: String, } impl_stable_hash_for!(struct CrateDep { name, hash, - kind + kind, + extra_filename }); #[derive(RustcEncodable, RustcDecodable)] From b70cc5380452676e4044ca289d177781d6b42035 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 21 Mar 2018 15:48:56 -0700 Subject: [PATCH 714/830] Add easy edition feature flag --- src/libsyntax/edition.rs | 7 +++++++ src/libsyntax/feature_gate.rs | 36 ++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/edition.rs b/src/libsyntax/edition.rs index 61246d4493ca..e579fc74b426 100644 --- a/src/libsyntax/edition.rs +++ b/src/libsyntax/edition.rs @@ -55,6 +55,13 @@ impl Edition { Edition::Edition2018 => "edition_2018", } } + + pub fn feature_name(&self) -> &'static str { + match *self { + Edition::Edition2015 => "rust_2015_preview", + Edition::Edition2018 => "rust_2018_preview", + } + } } impl FromStr for Edition { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 69612054ae3d..be5ebcbd13a6 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -28,7 +28,7 @@ use self::AttributeGate::*; use abi::Abi; use ast::{self, NodeId, PatKind, RangeEnd}; use attr; -use edition::Edition; +use edition::{ALL_EDITIONS, Edition}; use codemap::Spanned; use syntax_pos::{Span, DUMMY_SP}; use errors::{DiagnosticBuilder, Handler, FatalError}; @@ -1818,21 +1818,15 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - edition: Edition) -> Features { + crate_edition: Edition) -> Features { + fn feature_removed(span_handler: &Handler, span: Span) { + span_err!(span_handler, span, E0557, "feature has been removed"); + } + let mut features = Features::new(); let mut feature_checker = FeatureChecker::default(); - for &(.., f_edition, set) in ACTIVE_FEATURES.iter() { - if let Some(f_edition) = f_edition { - if edition >= f_edition { - // FIXME(Manishearth) there is currently no way to set - // lang features by edition - set(&mut features, DUMMY_SP); - } - } - } - for attr in krate_attrs { if !attr.check_name("feature") { continue @@ -1845,6 +1839,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } Some(list) => { for mi in list { + let name = if let Some(word) = mi.word() { word.name() } else { @@ -1862,11 +1857,26 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], .find(|& &(n, _, _)| name == n) .or_else(|| STABLE_REMOVED_FEATURES.iter() .find(|& &(n, _, _)| name == n)) { - span_err!(span_handler, mi.span, E0557, "feature has been removed"); + feature_removed(span_handler, mi.span); } else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter() .find(|& &(n, _, _)| name == n) { features.declared_stable_lang_features.push((name, mi.span)); + } else if let Some(&edition) = ALL_EDITIONS.iter() + .find(|e| name == e.feature_name()) { + if edition <= crate_edition { + feature_removed(span_handler, mi.span); + } else { + for &(.., f_edition, set) in ACTIVE_FEATURES.iter() { + if let Some(f_edition) = f_edition { + if edition >= f_edition { + // FIXME(Manishearth) there is currently no way to set + // lib features by edition + set(&mut features, DUMMY_SP); + } + } + } + } } else { features.declared_lib_features.push((name, mi.span)); } From 195c6b4789858b7fa23735a67facf2bd0749729b Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 21 Mar 2018 15:49:42 -0700 Subject: [PATCH 715/830] Fix test --- src/test/run-pass/epoch-gate-feature.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/epoch-gate-feature.rs b/src/test/run-pass/epoch-gate-feature.rs index f3d8f216e113..e3cd1edd2098 100644 --- a/src/test/run-pass/epoch-gate-feature.rs +++ b/src/test/run-pass/epoch-gate-feature.rs @@ -11,7 +11,7 @@ // Checks if the correct registers are being used to pass arguments // when the sysv64 ABI is specified. -// compile-flags: -Zedition=2018 +#![feature(rust_2018_preview)] pub trait Foo {} From 97aead0c6c1e3e7e5c442f729c441d31e66342d2 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 29 Mar 2018 09:12:24 +0200 Subject: [PATCH 716/830] tidy --- src/librustdoc/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 9704a0369476..13b58f6807b4 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -535,8 +535,14 @@ fn parse_externs(matches: &getopts::Matches) -> Result { /// generated from the cleaned AST of the crate. /// /// This form of input will run all of the plug/cleaning passes -fn rust_input(cratefile: PathBuf, externs: Externs, edition: Edition, matches: &getopts::Matches, f: F) -> R -where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R { +fn rust_input(cratefile: PathBuf, + externs: Externs, + edition: Edition, + matches: &getopts::Matches, + f: F) -> R +where R: 'static + Send, + F: 'static + Send + FnOnce(Output) -> R +{ let mut default_passes = !matches.opt_present("no-defaults"); let mut passes = matches.opt_strs("passes"); let mut plugins = matches.opt_strs("plugins"); From 850156aa2700735183059ad48a0c56e271d1e602 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 29 Mar 2018 10:34:55 +0300 Subject: [PATCH 717/830] Update Cargo This includes rust-lang/cargo#5255 which fixed regression in `cargo rustdoc` command. --- src/Cargo.lock | 15 ++++++++++++++- src/tools/cargo | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 8ace51ddac2b..1f7cf84cedbd 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -201,7 +201,7 @@ dependencies = [ "serde_json 1.0.13 (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.14 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2302,6 +2302,18 @@ dependencies = [ "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tempfile" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "term" version = "0.0.0" @@ -2763,6 +2775,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syntex_syntax 0.52.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76a302e717e348aa372ff577791c3832395650073b8d8432f8b3cb170b34afde" "checksum tar 0.4.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1605d3388ceb50252952ffebab4b5dc43017ead7e4481b175961c283bb951195" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +"checksum tempfile 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "439d9a7c00f98b1b5ee730039bf5b1f9203d508690e3c76b509e7ad59f8f7c99" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" diff --git a/src/tools/cargo b/src/tools/cargo index 311a5eda6f90..d63299b6eafa 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 311a5eda6f90d660bb23e97c8ee77090519b9eda +Subproject commit d63299b6eafae99bfe1fd5ddc75bc7cf67ed58f9 From 1ef1b92379c302c769be2240050080ad0bd763b6 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 29 Mar 2018 02:43:14 -0400 Subject: [PATCH 718/830] add `#[inline(never)]` annotations --- src/librustc_mir/borrow_check/nll/region_infer/dfs.rs | 1 + src/librustc_mir/borrow_check/nll/region_infer/mod.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs b/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs index d55b60182324..e1d17508b7dc 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/dfs.rs @@ -34,6 +34,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// - `Ok(false)` if the walk was completed with no changes; /// - `Err(early)` if the walk was existed early by `op`. `earlyelem` is the /// value that `op` returned. + #[inline(never)] // ensure dfs is identifiable in profiles pub(super) fn dfs(&self, mir: &Mir<'tcx>, mut op: C) -> Result where C: DfsOp, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 66776a94ff01..0ae4fda430d3 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -452,6 +452,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.inferred_values = Some(inferred_values); } + #[inline(never)] // ensure dfs is identifiable in profiles fn compute_region_values(&self, mir: &Mir<'tcx>, track_causes: TrackCauses) -> RegionValues { debug!("compute_region_values()"); debug!("compute_region_values: constraints={:#?}", { From 39fe29bf0ca4d105a6118b4a1ca5ce17a59b71b1 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 29 Mar 2018 09:43:26 +0200 Subject: [PATCH 719/830] src/libcore/ptr.rs: Fix documentation for size of `Option>` Seems more useful to say that it has the same size as `*mut T`. --- src/libcore/ptr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index aebd50d9c6b3..5a54de06b5ef 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2653,7 +2653,7 @@ impl<'a, T: ?Sized> From> for Unique { /// /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer /// is never dereferenced. This is so that enums may use this forbidden value -/// as a discriminant -- `Option>` has the same size as `NonNull`. +/// as a discriminant -- `Option>` has the same size as `*mut T`. /// However the pointer may still dangle if it isn't dereferenced. /// /// Unlike `*mut T`, `NonNull` is covariant over `T`. If this is incorrect From c3a63970dee2422e2fcc79d8b99303b4b046f444 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 19 Mar 2018 09:01:17 +0100 Subject: [PATCH 720/830] Move alloc::Bound to {core,std}::ops The stable reexport `std::collections::Bound` is now deprecated. Another deprecated reexport could be added in `alloc`, but that crate is unstable. --- src/liballoc/btree/map.rs | 4 +- src/liballoc/btree/set.rs | 2 +- src/liballoc/lib.rs | 51 ------------------- src/liballoc/range.rs | 2 +- src/liballoc/string.rs | 2 +- src/liballoc/tests/btree/map.rs | 2 +- src/liballoc/vec.rs | 2 +- src/liballoc/vec_deque.rs | 2 +- src/libcore/ops/mod.rs | 2 +- src/libcore/ops/range.rs | 51 +++++++++++++++++++ src/librustc_data_structures/array_vec.rs | 2 +- src/libstd/collections/mod.rs | 3 +- .../sync-send-iterators-in-libcollections.rs | 2 +- 13 files changed, 64 insertions(+), 63 deletions(-) diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index cada190032aa..2ba56063e366 100644 --- a/src/liballoc/btree/map.rs +++ b/src/liballoc/btree/map.rs @@ -13,11 +13,11 @@ use core::fmt::Debug; use core::hash::{Hash, Hasher}; use core::iter::{FromIterator, Peekable, FusedIterator}; use core::marker::PhantomData; +use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::Index; use core::{fmt, intrinsics, mem, ptr}; use borrow::Borrow; -use Bound::{Excluded, Included, Unbounded}; use range::RangeArgument; use super::node::{self, Handle, NodeRef, marker}; @@ -804,7 +804,7 @@ impl BTreeMap { /// /// ``` /// use std::collections::BTreeMap; - /// use std::collections::Bound::Included; + /// use std::ops::Bound::Included; /// /// let mut map = BTreeMap::new(); /// map.insert(3, "a"); diff --git a/src/liballoc/btree/set.rs b/src/liballoc/btree/set.rs index 2e3157147a08..d488dd6cbbd7 100644 --- a/src/liballoc/btree/set.rs +++ b/src/liballoc/btree/set.rs @@ -240,7 +240,7 @@ impl BTreeSet { /// /// ``` /// use std::collections::BTreeSet; - /// use std::collections::Bound::Included; + /// use std::ops::Bound::Included; /// /// let mut set = BTreeSet::new(); /// set.insert(3); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 19d64d8fea9e..eddbd50ea038 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -204,57 +204,6 @@ mod std { pub use core::ops; // RangeFull } -/// An endpoint of a range of keys. -/// -/// # Examples -/// -/// `Bound`s are range endpoints: -/// -/// ``` -/// #![feature(collections_range)] -/// -/// use std::collections::range::RangeArgument; -/// use std::collections::Bound::*; -/// -/// assert_eq!((..100).start(), Unbounded); -/// assert_eq!((1..12).start(), Included(&1)); -/// assert_eq!((1..12).end(), Excluded(&12)); -/// ``` -/// -/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`]. -/// Note that in most cases, it's better to use range syntax (`1..5`) instead. -/// -/// ``` -/// use std::collections::BTreeMap; -/// use std::collections::Bound::{Excluded, Included, Unbounded}; -/// -/// let mut map = BTreeMap::new(); -/// map.insert(3, "a"); -/// map.insert(5, "b"); -/// map.insert(8, "c"); -/// -/// for (key, value) in map.range((Excluded(3), Included(8))) { -/// println!("{}: {}", key, value); -/// } -/// -/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next()); -/// ``` -/// -/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range -#[stable(feature = "collections_bound", since = "1.17.0")] -#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] -pub enum Bound { - /// An inclusive bound. - #[stable(feature = "collections_bound", since = "1.17.0")] - Included(#[stable(feature = "collections_bound", since = "1.17.0")] T), - /// An exclusive bound. - #[stable(feature = "collections_bound", since = "1.17.0")] - Excluded(#[stable(feature = "collections_bound", since = "1.17.0")] T), - /// An infinite endpoint. Indicates that there is no bound in this direction. - #[stable(feature = "collections_bound", since = "1.17.0")] - Unbounded, -} - /// An intermediate trait for specialization of `Extend`. #[doc(hidden)] trait SpecExtend { diff --git a/src/liballoc/range.rs b/src/liballoc/range.rs index b03abc851808..7cadbf3c90a0 100644 --- a/src/liballoc/range.rs +++ b/src/liballoc/range.rs @@ -15,7 +15,7 @@ //! Range syntax. use core::ops::{RangeFull, Range, RangeTo, RangeFrom, RangeInclusive, RangeToInclusive}; -use Bound::{self, Excluded, Included, Unbounded}; +use core::ops::Bound::{self, Excluded, Included, Unbounded}; /// `RangeArgument` is implemented by Rust's built-in range types, produced /// by range syntax like `..`, `a..`, `..b` or `c..d`. diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 23c12bef3aa7..754c78f77799 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -59,6 +59,7 @@ use core::fmt; use core::hash; use core::iter::{FromIterator, FusedIterator}; +use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{self, Add, AddAssign, Index, IndexMut}; use core::ptr; use core::str::pattern::Pattern; @@ -67,7 +68,6 @@ use std_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER}; use borrow::{Cow, ToOwned}; use range::RangeArgument; -use Bound::{Excluded, Included, Unbounded}; use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; use vec::Vec; use boxed::Box; diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 2393101040d9..6ebdb86cc4a9 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -9,8 +9,8 @@ // except according to those terms. use std::collections::BTreeMap; -use std::collections::Bound::{self, Excluded, Included, Unbounded}; use std::collections::btree_map::Entry::{Occupied, Vacant}; +use std::ops::Bound::{self, Excluded, Included, Unbounded}; use std::rc::Rc; use std::iter::FromIterator; diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index bcc999d73863..280570ecd65c 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -75,6 +75,7 @@ use core::marker::PhantomData; use core::mem; #[cfg(not(test))] use core::num::Float; +use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{InPlace, Index, IndexMut, Place, Placer}; use core::ops; use core::ptr; @@ -87,7 +88,6 @@ use boxed::Box; use raw_vec::RawVec; use super::range::RangeArgument; use super::allocator::CollectionAllocErr; -use Bound::{Excluded, Included, Unbounded}; /// A contiguous growable array type, written `Vec` but pronounced 'vector'. /// diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index be6e8d0f22f0..9efd730790d3 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -21,6 +21,7 @@ use core::cmp::Ordering; use core::fmt; use core::iter::{repeat, FromIterator, FusedIterator}; use core::mem; +use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{Index, IndexMut, Place, Placer, InPlace}; use core::ptr; use core::ptr::NonNull; @@ -33,7 +34,6 @@ use raw_vec::RawVec; use super::allocator::CollectionAllocErr; use super::range::RangeArgument; -use Bound::{Excluded, Included, Unbounded}; use super::vec::Vec; const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs index 234970a81faf..b0e751352826 100644 --- a/src/libcore/ops/mod.rs +++ b/src/libcore/ops/mod.rs @@ -192,7 +192,7 @@ pub use self::index::{Index, IndexMut}; pub use self::range::{Range, RangeFrom, RangeFull, RangeTo}; #[stable(feature = "inclusive_range", since = "1.26.0")] -pub use self::range::{RangeInclusive, RangeToInclusive}; +pub use self::range::{RangeInclusive, RangeToInclusive, Bound}; #[unstable(feature = "try_trait", issue = "42327")] pub use self::try::Try; diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index be51f5239b0c..dd44aedd09f5 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -442,3 +442,54 @@ impl> RangeToInclusive { // RangeToInclusive cannot impl From> // because underflow would be possible with (..0).into() + +/// An endpoint of a range of keys. +/// +/// # Examples +/// +/// `Bound`s are range endpoints: +/// +/// ``` +/// #![feature(collections_range)] +/// +/// use std::collections::range::RangeArgument; +/// use std::ops::Bound::*; +/// +/// assert_eq!((..100).start(), Unbounded); +/// assert_eq!((1..12).start(), Included(&1)); +/// assert_eq!((1..12).end(), Excluded(&12)); +/// ``` +/// +/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`]. +/// Note that in most cases, it's better to use range syntax (`1..5`) instead. +/// +/// ``` +/// use std::collections::BTreeMap; +/// use std::ops::Bound::{Excluded, Included, Unbounded}; +/// +/// let mut map = BTreeMap::new(); +/// map.insert(3, "a"); +/// map.insert(5, "b"); +/// map.insert(8, "c"); +/// +/// for (key, value) in map.range((Excluded(3), Included(8))) { +/// println!("{}: {}", key, value); +/// } +/// +/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next()); +/// ``` +/// +/// [`BTreeMap::range`]: ../../std/collections/btree_map/struct.BTreeMap.html#method.range +#[stable(feature = "collections_bound", since = "1.17.0")] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] +pub enum Bound { + /// An inclusive bound. + #[stable(feature = "collections_bound", since = "1.17.0")] + Included(#[stable(feature = "collections_bound", since = "1.17.0")] T), + /// An exclusive bound. + #[stable(feature = "collections_bound", since = "1.17.0")] + Excluded(#[stable(feature = "collections_bound", since = "1.17.0")] T), + /// An infinite endpoint. Indicates that there is no bound in this direction. + #[stable(feature = "collections_bound", since = "1.17.0")] + Unbounded, +} diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index 511c407d45a7..b40f2f922379 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -19,8 +19,8 @@ use std::slice; use std::fmt; use std::mem; use std::collections::range::RangeArgument; -use std::collections::Bound::{Excluded, Included, Unbounded}; use std::mem::ManuallyDrop; +use std::ops::Bound::{Excluded, Included, Unbounded}; pub unsafe trait Array { type Element; diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index be88f4e268aa..e6f15a6119e0 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -420,7 +420,8 @@ #![stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")] -pub use alloc::Bound; +#[rustc_deprecated(reason = "moved to `std::ops::Bound`", since = "1.26.0")] +pub use ops::Bound; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc::{BinaryHeap, BTreeMap, BTreeSet}; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/test/run-pass/sync-send-iterators-in-libcollections.rs b/src/test/run-pass/sync-send-iterators-in-libcollections.rs index 903532e9bc80..e096fb3bbaef 100644 --- a/src/test/run-pass/sync-send-iterators-in-libcollections.rs +++ b/src/test/run-pass/sync-send-iterators-in-libcollections.rs @@ -18,8 +18,8 @@ use std::collections::VecDeque; use std::collections::HashMap; use std::collections::HashSet; -use std::collections::Bound::Included; use std::mem; +use std::ops::Bound::Included; fn is_sync(_: T) where T: Sync {} fn is_send(_: T) where T: Send {} From 16d3ba1b23195da2d53e058c58c2a41def914dec Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 19 Mar 2018 09:26:29 +0100 Subject: [PATCH 721/830] Move RangeArguments to {core::std}::ops and rename to RangeBounds These unstable items are deprecated: * The `std::collections::range::RangeArgument` reexport * The `std::collections::range` module. --- src/liballoc/btree/map.rs | 8 +- src/liballoc/btree/set.rs | 5 +- src/liballoc/lib.rs | 2 +- src/liballoc/range.rs | 152 ----------------- src/liballoc/string.rs | 7 +- src/liballoc/vec.rs | 7 +- src/liballoc/vec_deque.rs | 5 +- src/libcore/ops/mod.rs | 2 +- src/libcore/ops/range.rs | 155 +++++++++++++++++- .../accumulate_vec.rs | 5 +- src/librustc_data_structures/array_vec.rs | 4 +- src/librustc_data_structures/indexed_vec.rs | 7 +- src/libstd/collections/mod.rs | 8 +- 13 files changed, 183 insertions(+), 184 deletions(-) delete mode 100644 src/liballoc/range.rs diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index 2ba56063e366..c604df7049e0 100644 --- a/src/liballoc/btree/map.rs +++ b/src/liballoc/btree/map.rs @@ -15,10 +15,10 @@ use core::iter::{FromIterator, Peekable, FusedIterator}; use core::marker::PhantomData; use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::Index; +use core::ops::RangeBounds; use core::{fmt, intrinsics, mem, ptr}; use borrow::Borrow; -use range::RangeArgument; use super::node::{self, Handle, NodeRef, marker}; use super::search; @@ -817,7 +817,7 @@ impl BTreeMap { /// ``` #[stable(feature = "btree_range", since = "1.17.0")] pub fn range(&self, range: R) -> Range - where T: Ord, K: Borrow, R: RangeArgument + where T: Ord, K: Borrow, R: RangeBounds { let root1 = self.root.as_ref(); let root2 = self.root.as_ref(); @@ -857,7 +857,7 @@ impl BTreeMap { /// ``` #[stable(feature = "btree_range", since = "1.17.0")] pub fn range_mut(&mut self, range: R) -> RangeMut - where T: Ord, K: Borrow, R: RangeArgument + where T: Ord, K: Borrow, R: RangeBounds { let root1 = self.root.as_mut(); let root2 = unsafe { ptr::read(&root1) }; @@ -1812,7 +1812,7 @@ fn last_leaf_edge } } -fn range_search>( +fn range_search>( root1: NodeRef, root2: NodeRef, range: R diff --git a/src/liballoc/btree/set.rs b/src/liballoc/btree/set.rs index d488dd6cbbd7..2aad476d3153 100644 --- a/src/liballoc/btree/set.rs +++ b/src/liballoc/btree/set.rs @@ -16,12 +16,11 @@ use core::cmp::{min, max}; use core::fmt::Debug; use core::fmt; use core::iter::{Peekable, FromIterator, FusedIterator}; -use core::ops::{BitOr, BitAnd, BitXor, Sub}; +use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds}; use borrow::Borrow; use btree_map::{BTreeMap, Keys}; use super::Recover; -use range::RangeArgument; // FIXME(conventions): implement bounded iterators @@ -253,7 +252,7 @@ impl BTreeSet { /// ``` #[stable(feature = "btree_range", since = "1.17.0")] pub fn range(&self, range: R) -> Range - where K: Ord, T: Borrow, R: RangeArgument + where K: Ord, T: Borrow, R: RangeBounds { Range { iter: self.map.range(range) } } diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index eddbd50ea038..e98b58994bfb 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -88,6 +88,7 @@ #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] +#![feature(collections_range)] #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(custom_attribute)] @@ -178,7 +179,6 @@ mod btree; pub mod borrow; pub mod fmt; pub mod linked_list; -pub mod range; pub mod slice; pub mod str; pub mod string; diff --git a/src/liballoc/range.rs b/src/liballoc/range.rs deleted file mode 100644 index 7cadbf3c90a0..000000000000 --- a/src/liballoc/range.rs +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2015 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. - -#![unstable(feature = "collections_range", - reason = "waiting for dust to settle on inclusive ranges", - issue = "30877")] - -//! Range syntax. - -use core::ops::{RangeFull, Range, RangeTo, RangeFrom, RangeInclusive, RangeToInclusive}; -use core::ops::Bound::{self, Excluded, Included, Unbounded}; - -/// `RangeArgument` is implemented by Rust's built-in range types, produced -/// by range syntax like `..`, `a..`, `..b` or `c..d`. -pub trait RangeArgument { - /// Start index bound. - /// - /// Returns the start value as a `Bound`. - /// - /// # Examples - /// - /// ``` - /// #![feature(alloc)] - /// #![feature(collections_range)] - /// - /// extern crate alloc; - /// - /// # fn main() { - /// use alloc::range::RangeArgument; - /// use alloc::Bound::*; - /// - /// assert_eq!((..10).start(), Unbounded); - /// assert_eq!((3..10).start(), Included(&3)); - /// # } - /// ``` - fn start(&self) -> Bound<&T>; - - /// End index bound. - /// - /// Returns the end value as a `Bound`. - /// - /// # Examples - /// - /// ``` - /// #![feature(alloc)] - /// #![feature(collections_range)] - /// - /// extern crate alloc; - /// - /// # fn main() { - /// use alloc::range::RangeArgument; - /// use alloc::Bound::*; - /// - /// assert_eq!((3..).end(), Unbounded); - /// assert_eq!((3..10).end(), Excluded(&10)); - /// # } - /// ``` - fn end(&self) -> Bound<&T>; -} - -// FIXME add inclusive ranges to RangeArgument - -impl RangeArgument for RangeFull { - fn start(&self) -> Bound<&T> { - Unbounded - } - fn end(&self) -> Bound<&T> { - Unbounded - } -} - -impl RangeArgument for RangeFrom { - fn start(&self) -> Bound<&T> { - Included(&self.start) - } - fn end(&self) -> Bound<&T> { - Unbounded - } -} - -impl RangeArgument for RangeTo { - fn start(&self) -> Bound<&T> { - Unbounded - } - fn end(&self) -> Bound<&T> { - Excluded(&self.end) - } -} - -impl RangeArgument for Range { - fn start(&self) -> Bound<&T> { - Included(&self.start) - } - fn end(&self) -> Bound<&T> { - Excluded(&self.end) - } -} - -#[stable(feature = "inclusive_range", since = "1.26.0")] -impl RangeArgument for RangeInclusive { - fn start(&self) -> Bound<&T> { - Included(&self.start) - } - fn end(&self) -> Bound<&T> { - Included(&self.end) - } -} - -#[stable(feature = "inclusive_range", since = "1.26.0")] -impl RangeArgument for RangeToInclusive { - fn start(&self) -> Bound<&T> { - Unbounded - } - fn end(&self) -> Bound<&T> { - Included(&self.end) - } -} - -impl RangeArgument for (Bound, Bound) { - fn start(&self) -> Bound<&T> { - match *self { - (Included(ref start), _) => Included(start), - (Excluded(ref start), _) => Excluded(start), - (Unbounded, _) => Unbounded, - } - } - - fn end(&self) -> Bound<&T> { - match *self { - (_, Included(ref end)) => Included(end), - (_, Excluded(ref end)) => Excluded(end), - (_, Unbounded) => Unbounded, - } - } -} - -impl<'a, T: ?Sized + 'a> RangeArgument for (Bound<&'a T>, Bound<&'a T>) { - fn start(&self) -> Bound<&T> { - self.0 - } - - fn end(&self) -> Bound<&T> { - self.1 - } -} diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 754c78f77799..aa202e236289 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -60,14 +60,13 @@ use core::fmt; use core::hash; use core::iter::{FromIterator, FusedIterator}; use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{self, Add, AddAssign, Index, IndexMut}; +use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds}; use core::ptr; use core::str::pattern::Pattern; use std_unicode::lossy; use std_unicode::char::{decode_utf16, REPLACEMENT_CHARACTER}; use borrow::{Cow, ToOwned}; -use range::RangeArgument; use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars}; use vec::Vec; use boxed::Box; @@ -1484,7 +1483,7 @@ impl String { /// ``` #[stable(feature = "drain", since = "1.6.0")] pub fn drain(&mut self, range: R) -> Drain - where R: RangeArgument + where R: RangeBounds { // Memory safety // @@ -1548,7 +1547,7 @@ impl String { /// ``` #[unstable(feature = "splice", reason = "recently added", issue = "44643")] pub fn splice(&mut self, range: R, replace_with: &str) - where R: RangeArgument + where R: RangeBounds { // Memory safety // diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 280570ecd65c..df08e46fe25f 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -76,7 +76,7 @@ use core::mem; #[cfg(not(test))] use core::num::Float; use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{InPlace, Index, IndexMut, Place, Placer}; +use core::ops::{InPlace, Index, IndexMut, Place, Placer, RangeBounds}; use core::ops; use core::ptr; use core::ptr::NonNull; @@ -86,7 +86,6 @@ use borrow::ToOwned; use borrow::Cow; use boxed::Box; use raw_vec::RawVec; -use super::range::RangeArgument; use super::allocator::CollectionAllocErr; /// A contiguous growable array type, written `Vec` but pronounced 'vector'. @@ -1176,7 +1175,7 @@ impl Vec { /// ``` #[stable(feature = "drain", since = "1.6.0")] pub fn drain(&mut self, range: R) -> Drain - where R: RangeArgument + where R: RangeBounds { // Memory safety // @@ -1950,7 +1949,7 @@ impl Vec { #[inline] #[stable(feature = "vec_splice", since = "1.21.0")] pub fn splice(&mut self, range: R, replace_with: I) -> Splice - where R: RangeArgument, I: IntoIterator + where R: RangeBounds, I: IntoIterator { Splice { drain: self.drain(range), diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index 9efd730790d3..94d042a45aa3 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -22,7 +22,7 @@ use core::fmt; use core::iter::{repeat, FromIterator, FusedIterator}; use core::mem; use core::ops::Bound::{Excluded, Included, Unbounded}; -use core::ops::{Index, IndexMut, Place, Placer, InPlace}; +use core::ops::{Index, IndexMut, Place, Placer, InPlace, RangeBounds}; use core::ptr; use core::ptr::NonNull; use core::slice; @@ -33,7 +33,6 @@ use core::cmp; use raw_vec::RawVec; use super::allocator::CollectionAllocErr; -use super::range::RangeArgument; use super::vec::Vec; const INITIAL_CAPACITY: usize = 7; // 2^3 - 1 @@ -969,7 +968,7 @@ impl VecDeque { #[inline] #[stable(feature = "drain", since = "1.6.0")] pub fn drain(&mut self, range: R) -> Drain - where R: RangeArgument + where R: RangeBounds { // Memory safety // diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs index b0e751352826..0b480b618fcb 100644 --- a/src/libcore/ops/mod.rs +++ b/src/libcore/ops/mod.rs @@ -192,7 +192,7 @@ pub use self::index::{Index, IndexMut}; pub use self::range::{Range, RangeFrom, RangeFull, RangeTo}; #[stable(feature = "inclusive_range", since = "1.26.0")] -pub use self::range::{RangeInclusive, RangeToInclusive, Bound}; +pub use self::range::{RangeInclusive, RangeToInclusive, RangeBounds, Bound}; #[unstable(feature = "try_trait", issue = "42327")] pub use self::try::Try; diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index dd44aedd09f5..b5aa81e36c43 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -452,8 +452,8 @@ impl> RangeToInclusive { /// ``` /// #![feature(collections_range)] /// -/// use std::collections::range::RangeArgument; /// use std::ops::Bound::*; +/// use std::ops::RangeBounds; /// /// assert_eq!((..100).start(), Unbounded); /// assert_eq!((1..12).start(), Included(&1)); @@ -493,3 +493,156 @@ pub enum Bound { #[stable(feature = "collections_bound", since = "1.17.0")] Unbounded, } + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +/// `RangeBounds` is implemented by Rust's built-in range types, produced +/// by range syntax like `..`, `a..`, `..b` or `c..d`. +pub trait RangeBounds { + /// Start index bound. + /// + /// Returns the start value as a `Bound`. + /// + /// # Examples + /// + /// ``` + /// #![feature(collections_range)] + /// + /// # fn main() { + /// use std::ops::Bound::*; + /// use std::ops::RangeBounds; + /// + /// assert_eq!((..10).start(), Unbounded); + /// assert_eq!((3..10).start(), Included(&3)); + /// # } + /// ``` + fn start(&self) -> Bound<&T>; + + /// End index bound. + /// + /// Returns the end value as a `Bound`. + /// + /// # Examples + /// + /// ``` + /// #![feature(collections_range)] + /// + /// # fn main() { + /// use std::ops::Bound::*; + /// use std::ops::RangeBounds; + /// + /// assert_eq!((3..).end(), Unbounded); + /// assert_eq!((3..10).end(), Excluded(&10)); + /// # } + /// ``` + fn end(&self) -> Bound<&T>; +} + +use self::Bound::{Excluded, Included, Unbounded}; + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl RangeBounds for RangeFull { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Unbounded + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl RangeBounds for RangeFrom { + fn start(&self) -> Bound<&T> { + Included(&self.start) + } + fn end(&self) -> Bound<&T> { + Unbounded + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl RangeBounds for RangeTo { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Excluded(&self.end) + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl RangeBounds for Range { + fn start(&self) -> Bound<&T> { + Included(&self.start) + } + fn end(&self) -> Bound<&T> { + Excluded(&self.end) + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl RangeBounds for RangeInclusive { + fn start(&self) -> Bound<&T> { + Included(&self.start) + } + fn end(&self) -> Bound<&T> { + Included(&self.end) + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl RangeBounds for RangeToInclusive { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Included(&self.end) + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl RangeBounds for (Bound, Bound) { + fn start(&self) -> Bound<&T> { + match *self { + (Included(ref start), _) => Included(start), + (Excluded(ref start), _) => Excluded(start), + (Unbounded, _) => Unbounded, + } + } + + fn end(&self) -> Bound<&T> { + match *self { + (_, Included(ref end)) => Included(end), + (_, Excluded(ref end)) => Excluded(end), + (_, Unbounded) => Unbounded, + } + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl<'a, T: ?Sized + 'a> RangeBounds for (Bound<&'a T>, Bound<&'a T>) { + fn start(&self) -> Bound<&T> { + self.0 + } + + fn end(&self) -> Bound<&T> { + self.1 + } +} diff --git a/src/librustc_data_structures/accumulate_vec.rs b/src/librustc_data_structures/accumulate_vec.rs index 52306de74cb8..f50b8cadf15a 100644 --- a/src/librustc_data_structures/accumulate_vec.rs +++ b/src/librustc_data_structures/accumulate_vec.rs @@ -15,11 +15,10 @@ //! //! The N above is determined by Array's implementor, by way of an associated constant. -use std::ops::{Deref, DerefMut}; +use std::ops::{Deref, DerefMut, RangeBounds}; use std::iter::{self, IntoIterator, FromIterator}; use std::slice; use std::vec; -use std::collections::range::RangeArgument; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; @@ -74,7 +73,7 @@ impl AccumulateVec { } pub fn drain(&mut self, range: R) -> Drain - where R: RangeArgument + where R: RangeBounds { match *self { AccumulateVec::Array(ref mut v) => { diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index b40f2f922379..db1cfb5c7676 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -18,9 +18,9 @@ use std::hash::{Hash, Hasher}; use std::slice; use std::fmt; use std::mem; -use std::collections::range::RangeArgument; use std::mem::ManuallyDrop; use std::ops::Bound::{Excluded, Included, Unbounded}; +use std::ops::RangeBounds; pub unsafe trait Array { type Element; @@ -106,7 +106,7 @@ impl ArrayVec { } pub fn drain(&mut self, range: R) -> Drain - where R: RangeArgument + where R: RangeBounds { // Memory safety // diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs index cbb3ff517159..1fb63afc72fa 100644 --- a/src/librustc_data_structures/indexed_vec.rs +++ b/src/librustc_data_structures/indexed_vec.rs @@ -8,12 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::collections::range::RangeArgument; use std::fmt::Debug; use std::iter::{self, FromIterator}; use std::slice; use std::marker::PhantomData; -use std::ops::{Index, IndexMut, Range}; +use std::ops::{Index, IndexMut, Range, RangeBounds}; use std::fmt; use std::vec; use std::u32; @@ -448,13 +447,13 @@ impl IndexVec { } #[inline] - pub fn drain<'a, R: RangeArgument>( + pub fn drain<'a, R: RangeBounds>( &'a mut self, range: R) -> impl Iterator + 'a { self.raw.drain(range) } #[inline] - pub fn drain_enumerated<'a, R: RangeArgument>( + pub fn drain_enumerated<'a, R: RangeBounds>( &'a mut self, range: R) -> impl Iterator + 'a { self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index e6f15a6119e0..47ea3bc26bf6 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -436,8 +436,12 @@ pub use self::hash_map::HashMap; #[stable(feature = "rust1", since = "1.0.0")] pub use self::hash_set::HashSet; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc::range; +#[unstable(feature = "collections_range", issue = "30877")] +#[rustc_deprecated(reason = "renamed and moved to `std::ops::RangeBounds`", since = "1.26.0")] +/// Range syntax +pub mod range { + pub use ops::RangeBounds as RangeArgument; +} #[unstable(feature = "try_reserve", reason = "new API", issue="48043")] pub use alloc::allocator::CollectionAllocErr; From 124453e6fe03242233ab5f8c8e2360a8b9fcf831 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 20 Mar 2018 19:46:11 +0100 Subject: [PATCH 722/830] impl RangeBounds for Range{,From,To,Inclusive,ToInclusive}<&T> --- src/libcore/ops/range.rs | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index b5aa81e36c43..3f6674071256 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -646,3 +646,63 @@ impl<'a, T: ?Sized + 'a> RangeBounds for (Bound<&'a T>, Bound<&'a T>) { self.1 } } + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl<'a, T> RangeBounds for RangeFrom<&'a T> { + fn start(&self) -> Bound<&T> { + Included(self.start) + } + fn end(&self) -> Bound<&T> { + Unbounded + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl<'a, T> RangeBounds for RangeTo<&'a T> { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Excluded(self.end) + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl<'a, T> RangeBounds for Range<&'a T> { + fn start(&self) -> Bound<&T> { + Included(self.start) + } + fn end(&self) -> Bound<&T> { + Excluded(self.end) + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl<'a, T> RangeBounds for RangeInclusive<&'a T> { + fn start(&self) -> Bound<&T> { + Included(self.start) + } + fn end(&self) -> Bound<&T> { + Included(self.end) + } +} + +#[unstable(feature = "collections_range", + reason = "might be replaced with `Into<_>` and a type containing two `Bound` values", + issue = "30877")] +impl<'a, T> RangeBounds for RangeToInclusive<&'a T> { + fn start(&self) -> Bound<&T> { + Unbounded + } + fn end(&self) -> Bound<&T> { + Included(self.end) + } +} From 6960a960f10e95d750daca14cd0a103edaca6105 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 23 Mar 2018 19:44:51 +0100 Subject: [PATCH 723/830] Hide the deprecated std::collections::range module from docs --- src/libstd/collections/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 47ea3bc26bf6..426949d65df9 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -438,6 +438,7 @@ pub use self::hash_set::HashSet; #[unstable(feature = "collections_range", issue = "30877")] #[rustc_deprecated(reason = "renamed and moved to `std::ops::RangeBounds`", since = "1.26.0")] +#[doc(hidden)] /// Range syntax pub mod range { pub use ops::RangeBounds as RangeArgument; From 3542ff8e396af4a1be7854e1ce028465c4366fc4 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 27 Mar 2018 22:05:32 +0200 Subject: [PATCH 724/830] Hide the Bound type in docs at its deprecated location in std::collections --- src/libstd/collections/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 426949d65df9..c7ad27d8d267 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -421,6 +421,7 @@ #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(reason = "moved to `std::ops::Bound`", since = "1.26.0")] +#[doc(hidden)] pub use ops::Bound; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc::{BinaryHeap, BTreeMap, BTreeSet}; From 6c9b3cccbcef8918829e173a2ea9c5d975cd2777 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 29 Mar 2018 13:13:49 +0200 Subject: [PATCH 725/830] Update clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index eafd09010815..b75618206cec 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit eafd09010815da43302ac947afee45b0f5219e6b +Subproject commit b75618206cec71bd87ff7b07f0a8698ee854a2d1 From 19eedf98ffa8df52f7be7c003957ef11521551f4 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Thu, 29 Mar 2018 07:03:24 -0400 Subject: [PATCH 726/830] Fix escaped backslash in windows file not found message When a module is declared, but no matching file exists, rustc gives an error like 'help: name the file either foo.rs or foo/mod.rs inside the directory "src/bar"'. However, at on windows, the backslash was double-escaped when naming the directory. It did this because the string was printed in debug mode ( "{:?}" ) to surround it with quotes. However, it should just be printed like any other directory in an error message and surrounded by escaped quotes, rather than relying on the debug print to add quotes ( "\"{}\"" ). --- src/libsyntax/parse/parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 98e2528d30f2..6fde67aeb855 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -460,7 +460,7 @@ impl Error { ref dir_path } => { let mut err = struct_span_err!(handler, sp, E0583, "file not found for module `{}`", mod_name); - err.help(&format!("name the file either {} or {} inside the directory {:?}", + err.help(&format!("name the file either {} or {} inside the directory \"{}\"", default_path, secondary_path, dir_path)); From 561e8efb7d221cc2f9274f3756cdf4c30556ae4b Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Mar 2018 17:32:15 +0200 Subject: [PATCH 727/830] Add primitive intra-links --- src/librustdoc/clean/mod.rs | 85 +++++++++++++++++++++++++----- src/test/rustdoc/primitive-link.rs | 19 +++++++ 2 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 src/test/rustdoc/primitive-link.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 42c9d9e52f35..62e5f730cae8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -19,6 +19,7 @@ pub use self::SelfTy::*; pub use self::FunctionRetTy::*; pub use self::Visibility::*; +use syntax; use syntax::abi::Abi; use syntax::ast::{self, AttrStyle}; use syntax::attr; @@ -64,6 +65,7 @@ use std::u32; use core::{self, DocContext}; use doctree; use visit_ast; +use html::render::{cache, ExternalLocation}; use html::item_type::ItemType; use html::markdown::markdown_links; @@ -346,7 +348,7 @@ impl Item { } pub fn links(&self) -> Vec<(String, String)> { - self.attrs.links() + self.attrs.links(&self.def_id.krate) } pub fn is_crate(&self) -> bool { @@ -697,7 +699,7 @@ pub struct Attributes { pub cfg: Option>, pub span: Option, /// map from Rust paths to resolved defs and potential URL fragments - pub links: Vec<(String, DefId, Option)>, + pub links: Vec<(String, Option, Option)>, } impl Attributes { @@ -869,17 +871,41 @@ impl Attributes { /// Get links as a vector /// /// Cache must be populated before call - pub fn links(&self) -> Vec<(String, String)> { + pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> { use html::format::href; self.links.iter().filter_map(|&(ref s, did, ref fragment)| { - if let Some((mut href, ..)) = href(did) { - if let Some(ref fragment) = *fragment { - href.push_str("#"); - href.push_str(fragment); + match did { + Some(did) => { + if let Some((mut href, ..)) = href(did) { + if let Some(ref fragment) = *fragment { + href.push_str("#"); + href.push_str(fragment); + } + Some((s.clone(), href)) + } else { + None + } + } + None => { + if let Some(ref fragment) = *fragment { + let cache = cache(); + let url = match cache.extern_locations.get(krate) { + Some(&(_, ref src, ExternalLocation::Local)) => + src.to_str().expect("invalid file path"), + Some(&(_, _, ExternalLocation::Remote(ref s))) => s, + Some(&(_, _, ExternalLocation::Unknown)) | None => + "https://doc.rust-lang.org/nightly", + }; + // This is a primitive so the url is done "by hand". + Some((s.clone(), + format!("{}{}std/primitive.{}.html", + url, + if !url.ends_with('/') { "/" } else { "" }, + fragment))) + } else { + panic!("This isn't a primitive?!"); + } } - Some((s.clone(), href)) - } else { - None } }).collect() } @@ -959,6 +985,34 @@ fn handle_variant(cx: &DocContext, def: Def) -> Result<(Def, Option), () Ok((parent_def, Some(format!("{}.v", variant.name)))) } +const PRIMITIVES: &[(&str, Def)] = &[ + ("u8", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U8))), + ("u16", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U16))), + ("u32", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U32))), + ("u64", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U64))), + ("u128", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::U128))), + ("usize", Def::PrimTy(hir::PrimTy::TyUint(syntax::ast::UintTy::Usize))), + ("i8", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I8))), + ("i16", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I16))), + ("i32", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I32))), + ("i64", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I64))), + ("i128", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::I128))), + ("isize", Def::PrimTy(hir::PrimTy::TyInt(syntax::ast::IntTy::Isize))), + ("f32", Def::PrimTy(hir::PrimTy::TyFloat(syntax::ast::FloatTy::F32))), + ("f64", Def::PrimTy(hir::PrimTy::TyFloat(syntax::ast::FloatTy::F64))), + ("str", Def::PrimTy(hir::PrimTy::TyStr)), + ("bool", Def::PrimTy(hir::PrimTy::TyBool)), + ("char", Def::PrimTy(hir::PrimTy::TyChar)), +]; + +fn is_primitive(path_str: &str, is_val: bool) -> Option { + if is_val { + None + } else { + PRIMITIVES.iter().find(|x| x.0 == path_str).map(|x| x.1) + } +} + /// Resolve a given string as a path, along with whether or not it is /// in the value namespace. Also returns an optional URL fragment in the case /// of variants and methods @@ -987,6 +1041,8 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option if value != is_val { return Err(()) } + } else if let Some(prim) = is_primitive(path_str, is_val) { + return Ok((prim, Some(path_str.to_owned()))) } else { // If resolution failed, it may still be a method // because methods are not handled by the resolver @@ -1051,7 +1107,6 @@ fn resolve(cx: &DocContext, path_str: &str, is_val: bool) -> Result<(Def, Option } _ => Err(()) } - } else { Err(()) } @@ -1218,8 +1273,12 @@ impl Clean for [ast::Attribute] { } }; - let id = register_def(cx, def); - attrs.links.push((ori_link, id, fragment)); + if let Def::PrimTy(_) = def { + attrs.links.push((ori_link, None, fragment)); + } else { + let id = register_def(cx, def); + attrs.links.push((ori_link, Some(id), fragment)); + } } cx.sess().abort_if_errors(); diff --git a/src/test/rustdoc/primitive-link.rs b/src/test/rustdoc/primitive-link.rs new file mode 100644 index 000000000000..b0cf8acc7c02 --- /dev/null +++ b/src/test/rustdoc/primitive-link.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_name = "foo"] + +// ignore-tidy-linelength + +// @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.u32.html"]' 'u32' +// @has foo/struct.Foo.html '//*[@class="docblock"]/p/a[@href="https://doc.rust-lang.org/nightly/std/primitive.i64.html"]' 'i64' + +/// It contains [`u32`] and [i64]. +pub struct Foo; From 772a8028ffbb3386d8da8cf5a17517b453eed767 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Mar 2018 11:18:45 +0200 Subject: [PATCH 728/830] Rename main theme into light theme --- src/doc/rustdoc/src/unstable-features.md | 6 +++--- src/librustdoc/html/layout.rs | 2 +- src/librustdoc/html/render.rs | 12 ++++++------ src/librustdoc/html/static/storage.js | 2 +- .../html/static/themes/{main.css => light.css} | 0 src/librustdoc/lib.rs | 8 ++++---- src/tools/error_index_generator/main.rs | 4 ++-- src/tools/rustdoc-themes/main.rs | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) rename src/librustdoc/html/static/themes/{main.css => light.css} (100%) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 16356c20c706..44b9145a8c2e 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -305,7 +305,7 @@ $ rustdoc src/lib.rs -Z unstable-options --themes theme.css Giving this flag to `rustdoc` will make it copy your theme into the generated crate docs and enable it in the theme selector. Note that `rustdoc` will reject your theme file if it doesn't style -everything the "main" theme does. See `--theme-checker` below for details. +everything the "light" theme does. See `--theme-checker` below for details. ### `--theme-checker`: verify theme CSS for validity @@ -316,7 +316,7 @@ $ rustdoc -Z unstable-options --theme-checker theme.css ``` Before including your theme in crate docs, `rustdoc` will compare all the CSS rules it contains -against the "main" theme included by default. Using this flag will allow you to see which rules are +against the "light" theme included by default. Using this flag will allow you to see which rules are missing if `rustdoc` rejects your theme. ### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs @@ -330,7 +330,7 @@ $ rustdoc src/lib.rs -Z unstable-options --resource-suffix suf When rendering docs, `rustdoc` creates several CSS and JavaScript files as part of the output. Since all these files are linked from every page, changing where they are can be cumbersome if you need to specially cache them. This flag will rename all these files in the output to include the suffix in -the filename. For example, `main.css` would become `main-suf.css` with the above command. +the filename. For example, `light.css` would become `light-suf.css` with the above command. ### `--display-warnings`: display warnings when documenting or running documentation tests diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 0151a8c3ab71..aac5d0d2601d 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -53,7 +53,7 @@ r##" id="mainThemeStyle"> {themes} - + {css_extension} diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 678e1762a551..6d71b0ec8ec7 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -129,8 +129,8 @@ pub struct SharedContext { pub sort_modules_alphabetically: bool, /// Additional themes to be added to the generated docs. pub themes: Vec, - /// Suffix to be added on resource files (if suffix is "-v2" then "main.css" becomes - /// "main-v2.css"). + /// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes + /// "light-v2.css"). pub resource_suffix: String, } @@ -743,7 +743,7 @@ fn write_shared(cx: &Context, write(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)), include_bytes!("static/rustdoc.css"))?; - // To avoid "main.css" to be overwritten, we'll first run over the received themes and only + // To avoid "light.css" to be overwritten, we'll first run over the received themes and only // then we'll run over the "official" styles. let mut themes: HashSet = HashSet::new(); @@ -761,9 +761,9 @@ fn write_shared(cx: &Context, write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)), include_bytes!("static/brush.svg"))?; - write(cx.dst.join(&format!("main{}.css", cx.shared.resource_suffix)), - include_bytes!("static/themes/main.css"))?; - themes.insert("main".to_owned()); + write(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)), + include_bytes!("static/themes/light.css"))?; + themes.insert("light".to_owned()); write(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)), include_bytes!("static/themes/dark.css"))?; themes.insert("dark".to_owned()); diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index c8571e4cf918..2f4e203ebc5c 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -67,4 +67,4 @@ function switchTheme(styleElem, mainStyleElem, newTheme) { } } -switchTheme(currentTheme, mainTheme, getCurrentValue('rustdoc-theme') || 'main'); +switchTheme(currentTheme, mainTheme, getCurrentValue('rustdoc-theme') || 'light'); diff --git a/src/librustdoc/html/static/themes/main.css b/src/librustdoc/html/static/themes/light.css similarity index 100% rename from src/librustdoc/html/static/themes/main.css rename to src/librustdoc/html/static/themes/light.css diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bec25a98227a..9f6e0c2944e3 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -266,8 +266,8 @@ pub fn opts() -> Vec { unstable("resource-suffix", |o| { o.optopt("", "resource-suffix", - "suffix to add to CSS and JavaScript files, e.g. \"main.css\" will become \ - \"main-suffix.css\"", + "suffix to add to CSS and JavaScript files, e.g. \"light.css\" will become \ + \"light-suffix.css\"", "PATH") }), ] @@ -321,7 +321,7 @@ pub fn main_args(args: &[String]) -> isize { let to_check = matches.opt_strs("theme-checker"); if !to_check.is_empty() { - let paths = theme::load_css_paths(include_bytes!("html/static/themes/main.css")); + let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css")); let mut errors = 0; println!("rustdoc: [theme-checker] Starting tests!"); @@ -392,7 +392,7 @@ pub fn main_args(args: &[String]) -> isize { let mut themes = Vec::new(); if matches.opt_present("themes") { - let paths = theme::load_css_paths(include_bytes!("html/static/themes/main.css")); + let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css")); for (theme_file, theme_s) in matches.opt_strs("themes") .iter() diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index cdeb60156725..ade7ae0a4aee 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -61,8 +61,8 @@ impl Formatter for HTMLFormatter { Rust Compiler Error Index - - + + -This page is an overview of the documentation included with your Rust install. -Other unofficial documentation may exist elsewhere; for example, the [Rust -Learning] project collects documentation from the community, and [Docs.rs] -builds documentation for individual Rust packages. +Welcome to an overview of the documentation provided by the Rust project. +All of these projects are managed by the Docs Team; there are other +unofficial documentation resources as well! -# API Documentation +Many of these resources take the form of "books"; we collectively call these +"The Rust Bookshelf." Some are large, some are small. -Rust provides a standard library with a number of features; [we host its -documentation here][api]. +## Learn Rust -# Extended Error Documentation +If you'd like to learn Rust, this is the spot for you! All of these resources +assume that you have programmed before, but not in any specific language: + +### The Rust Programming Language + +Affectionately nicknamed "the book," [The Rust Programming +Language](book/index.html) will give you an overview of the language from +first principles. You'll build a few projects along the way, and by the end, +you'll have a solid grasp of the language. + +### Rust By Example + +If reading multiple hundreds of pages about a language isn't your style, then +[Rust By Example](rust-by-example/index.html) has you covered. While the book talks about code with +a lot of words, RBE shows off a bunch of code, and keeps the talking to a +minimum. It also includes exercises! + +## Use Rust + +Once you've gotten familliar with the language, these resources can help you +when you're actually using it day-to-day. + +### The Standard Library + +Rust's standard library has [extensive API documentation](std/index.html), +with explanations of how to use various things, as well as example code for +accomplishing various tasks. + +### The Cargo Book + +[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and dependency manager. + +### The Rustdoc Book + +[The Rustdoc Book](rustdoc/index.html) describes our documentation tool, `rustdoc`. + +### Extended Error Listing Many of Rust's errors come with error codes, and you can request extended -diagnostics from the compiler on those errors. We also [have the text of those -extended errors on the web][err], if you prefer to read them that way. +diagnostics from the compiler on those errors. You can also [read them +here](error-index.html), if you prefer to read them that way. -# The Rust Bookshelf +## Master Rust -Rust provides a number of book-length sets of documentation, collectively -nicknamed 'The Rust Bookshelf.' +Once you're quite familiar with the language, you may find these advanced +resources useful. -* [The Rust Programming Language][book] teaches you how to program in Rust. -* [Rust By Example][rbe] teaches you how to program in Rust using editable examples. -* [The Cargo Book][cargo-book] is a guide to Cargo, Rust's build tool and dependency manager. -* [The Unstable Book][unstable-book] has documentation for unstable features. -* [The Rustonomicon][nomicon] is your guidebook to the dark arts of unsafe Rust. -* [The Reference][ref] is not a formal spec, but is more detailed and comprehensive than the book. -* [The Rustdoc Book][rustdoc-book] describes our documentation tool, `rustdoc`. +### The Reference -Initially, documentation lands in the Unstable Book, and then, as part of the -stabilization process, is moved into the Book, Nomicon, or Reference. +[The Reference](reference/index.html) is not a formal spec, but is more detailed and +comprehensive than the book. -Another few words about the reference: it is guaranteed to be accurate, but not -complete. We have a policy that features must have documentation to be stabilized, -but we did not always have this policy, and so there are some stable things that -are not yet in the reference. We're working on back-filling things that landed -before this policy was put into place. That work is being tracked -[here][refchecklist]. +### The Rustonomicon -[Rust Learning]: https://github.com/ctjhoa/rust-learning -[Docs.rs]: https://docs.rs/ -[api]: std/index.html -[ref]: reference/index.html -[refchecklist]: https://github.com/rust-lang-nursery/reference/issues/9 -[err]: error-index.html -[book]: book/index.html -[rbe]: rust-by-example/index.html -[nomicon]: nomicon/index.html -[unstable-book]: unstable-book/index.html -[rustdoc-book]: rustdoc/index.html -[cargo-book]: cargo/index.html +[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of unsafe +Rust. It's also sometimes called "the 'nomicon." +### The Unstable Book + +[The Unstable Book](unstable-book/index.html) has documentation for unstable features. From 1ce98f34d38fa9338ff696f904bcb8c01856f935 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 2 Apr 2018 09:11:07 -0700 Subject: [PATCH 814/830] Cross-reference fs::read functions from io::Read docs --- src/libstd/io/mod.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 63b631ace969..3b8c42ddb39d 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -595,6 +595,11 @@ pub trait Read { /// Ok(()) /// } /// ``` + /// + /// (See also the [`std::fs::read`] convenience function for reading from a + /// file.) + /// + /// [`std::fs::read`]: ../fs/fn.read.html #[stable(feature = "rust1", since = "1.0.0")] fn read_to_end(&mut self, buf: &mut Vec) -> Result { read_to_end(self, buf) @@ -633,6 +638,11 @@ pub trait Read { /// Ok(()) /// } /// ``` + /// + /// (See also the [`std::fs::read_to_string`] convenience function for + /// reading from a file.) + /// + /// [`std::fs::read_to_string`]: ../fs/fn.read_to_string.html #[stable(feature = "rust1", since = "1.0.0")] fn read_to_string(&mut self, buf: &mut String) -> Result { // Note that we do *not* call `.read_to_end()` here. We are passing From 390f8367e74d72317ab4aa5097048243073968fa Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 2 Apr 2018 09:31:04 -0700 Subject: [PATCH 815/830] Add performance notes to BufReader/BufWriter docs --- src/libstd/io/buffered.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index cefff2f143ce..91f07ecc6639 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -25,6 +25,12 @@ use memchr; /// results in a system call. A `BufReader` performs large, infrequent reads on /// the underlying [`Read`] and maintains an in-memory buffer of the results. /// +/// `BufReader` can improve the speed of programs that make *small* and +/// *repeated* read calls to the same file or network socket. It does not +/// help when reading very large amounts at once, or reading just one or a few +/// times. It also provides no advantage when reading from a source that is +/// already in memory, like a `Vec`. +/// /// [`Read`]: ../../std/io/trait.Read.html /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read /// [`TcpStream`]: ../../std/net/struct.TcpStream.html @@ -359,6 +365,12 @@ impl Seek for BufReader { /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying /// writer in large, infrequent batches. /// +/// `BufWriter` can improve the speed of programs that make *small* and +/// *repeated* write calls to the same file or network socket. It does not +/// help when writing very large amounts at once, or writing just one or a few +/// times. It also provides no advantage when writing to a destination that is +/// in memory, like a `Vec`. +/// /// When the `BufWriter` is dropped, the contents of its buffer will be written /// out. However, any errors that happen in the process of flushing the buffer /// when the writer is dropped will be ignored. Code that wishes to handle such From 3627e43dc42446aef70997e9670811a1ae6bee42 Mon Sep 17 00:00:00 2001 From: lloydmeta Date: Wed, 4 Apr 2018 10:25:37 +0900 Subject: [PATCH 816/830] Add a test for the fix to issue #43058 Followed the instructions laid out here https://github.com/rust-lang/rust/issues/43058#issuecomment-378389971 --- src/test/ui/nll/issue-43058.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/ui/nll/issue-43058.rs diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs new file mode 100644 index 000000000000..ccea5279e072 --- /dev/null +++ b/src/test/ui/nll/issue-43058.rs @@ -0,0 +1,26 @@ +#![feature(nll)] + +use std::borrow::Cow; + +#[derive(Clone, Debug)] +struct S<'a> { + name: Cow<'a, str> +} + +#[derive(Clone, Debug)] +struct T<'a> { + s: Cow<'a, [S<'a>]> +} + +fn main() { + let s1 = [S { name: Cow::Borrowed("Test1") }, S { name: Cow::Borrowed("Test2") }]; + let b1 = T { s: Cow::Borrowed(&s1) }; + let s2 = [S { name: Cow::Borrowed("Test3") }, S { name: Cow::Borrowed("Test4") }]; + let b2 = T { s: Cow::Borrowed(&s2) }; + + let mut v = Vec::new(); + v.push(b1); + v.push(b2); + + println!("{:?}", v); +} \ No newline at end of file From f2cc501f5f982b18f3ecc4717820024d58065574 Mon Sep 17 00:00:00 2001 From: lloydmeta Date: Wed, 4 Apr 2018 10:33:52 +0900 Subject: [PATCH 817/830] Formatting --- src/test/ui/nll/issue-43058.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/test/ui/nll/issue-43058.rs b/src/test/ui/nll/issue-43058.rs index ccea5279e072..91ac7e400426 100644 --- a/src/test/ui/nll/issue-43058.rs +++ b/src/test/ui/nll/issue-43058.rs @@ -1,3 +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. + +// must-compile-successfully + #![feature(nll)] use std::borrow::Cow; @@ -23,4 +35,4 @@ fn main() { v.push(b2); println!("{:?}", v); -} \ No newline at end of file +} From 97ac479066a16d06ad4eb2cc2a4f58d1e7aa37b8 Mon Sep 17 00:00:00 2001 From: Thayne McCombs Date: Tue, 3 Apr 2018 19:47:37 -0600 Subject: [PATCH 818/830] Stabilize parent_id() Fixes #46104 --- src/libstd/sys/unix/ext/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs index 60309bec6d4f..7b4ec20d91fb 100644 --- a/src/libstd/sys/unix/ext/process.rs +++ b/src/libstd/sys/unix/ext/process.rs @@ -193,7 +193,7 @@ impl IntoRawFd for process::ChildStderr { } /// Returns the OS-assigned process identifier associated with this process's parent. -#[unstable(feature = "unix_ppid", issue = "46104")] +#[stable(feature = "unix_ppid", since = "1.27.0")] pub fn parent_id() -> u32 { ::sys::os::getppid() } From db859f5043e0e7a34be9fe67128133c5287ba039 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 4 Apr 2018 09:00:35 +0300 Subject: [PATCH 819/830] Update Cargo This includes at least two notable changes: * a regression is fixed where Cargo would update index on every operation https://github.com/rust-lang/cargo/pull/5288 * a new unstable `--out-dir` option is implemented https://github.com/rust-lang/cargo/pull/5203 --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index d63299b6eafa..b70ab13b3162 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit d63299b6eafae99bfe1fd5ddc75bc7cf67ed58f9 +Subproject commit b70ab13b31628e91b05961d55c07abf20ad49de6 From a98179937680377c10a0d61033daa85b156fbe21 Mon Sep 17 00:00:00 2001 From: Valentine Valyaeff Date: Wed, 4 Apr 2018 11:36:38 +0300 Subject: [PATCH 820/830] Regression test for #46314 --- src/test/ui/nll/decl-macro-illegal-copy.rs | 39 +++++++++++++++++++ .../ui/nll/decl-macro-illegal-copy.stderr | 14 +++++++ 2 files changed, 53 insertions(+) create mode 100644 src/test/ui/nll/decl-macro-illegal-copy.rs create mode 100644 src/test/ui/nll/decl-macro-illegal-copy.stderr diff --git a/src/test/ui/nll/decl-macro-illegal-copy.rs b/src/test/ui/nll/decl-macro-illegal-copy.rs new file mode 100644 index 000000000000..1525791c8811 --- /dev/null +++ b/src/test/ui/nll/decl-macro-illegal-copy.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. + +// Regression test for #46314 + +#![feature(nll)] +#![feature(decl_macro)] + +struct NonCopy(String); + +struct Wrapper { + inner: NonCopy, +} + +macro inner_copy($wrapper:ident) { + $wrapper.inner +} + +fn main() { + let wrapper = Wrapper { + inner: NonCopy("foo".into()), + }; + assert_two_non_copy( + inner_copy!(wrapper), + wrapper.inner, + //~^ ERROR use of moved value: `wrapper.inner` [E0382] + ); +} + +fn assert_two_non_copy(a: NonCopy, b: NonCopy) { + assert_eq!(a.0, b.0); +} diff --git a/src/test/ui/nll/decl-macro-illegal-copy.stderr b/src/test/ui/nll/decl-macro-illegal-copy.stderr new file mode 100644 index 000000000000..8bc25c23e017 --- /dev/null +++ b/src/test/ui/nll/decl-macro-illegal-copy.stderr @@ -0,0 +1,14 @@ +error[E0382]: use of moved value: `wrapper.inner` + --> $DIR/decl-macro-illegal-copy.rs:32:9 + | +LL | $wrapper.inner + | -------------- value moved here +... +LL | wrapper.inner, + | ^^^^^^^^^^^^^ value used here after move + | + = note: move occurs because `wrapper.inner` has type `NonCopy`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. From ac4f69bea4d41dffe9d56fb4117bd244a6b6acbe Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 3 Apr 2018 17:50:31 +0200 Subject: [PATCH 821/830] miri: add public alloc_kind accessor --- src/librustc_mir/interpret/memory.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3a28eae2d1c4..4823f654055f 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -352,6 +352,10 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> { .ok_or(EvalErrorKind::ExecuteMemory.into()) } + pub fn get_alloc_kind(&self, id: AllocId) -> Option> { + self.alloc_kind.get(&id).cloned() + } + /// For debugging, print an allocation and all allocations it points to, recursively. pub fn dump_alloc(&self, id: AllocId) { self.dump_allocs(vec![id]); From 9e9a987a0214609d6a1da4ce8b1dfd7870b40044 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 4 Apr 2018 16:09:01 +0100 Subject: [PATCH 822/830] Documenting private items in compiler docs. --- src/bootstrap/doc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 44073a5b0757..06340a4e98a4 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -696,6 +696,7 @@ impl Step for Rustc { t!(symlink_dir_force(&out, &out_dir)); let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc"); + cargo.env("RUSTDOCFLAGS", "--document-private-items"); compile::rustc_cargo(build, &mut cargo); // Only include compiler crates, no dependencies of those, such as `libc`. From 809d01c62ef25814abf8e490eb80128989985014 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 4 Apr 2018 16:09:58 +0100 Subject: [PATCH 823/830] Updated codeblocks to specify language where required. --- src/librustc/middle/region.rs | 4 ++-- src/librustc/traits/select.rs | 2 ++ src/librustc_resolve/lib.rs | 6 +++--- src/librustc_typeck/check/regionck.rs | 2 ++ src/librustc_typeck/impl_wf_check.rs | 12 ++++++------ 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index c7396b34c468..7e1b7c08c3da 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -353,8 +353,8 @@ pub struct ScopeTree { /// the result of `g()` occurs after the yield (and therefore /// doesn't). If we want to infer that, we can look at the /// postorder traversal: - /// ``` - /// `foo` `f` Call#1 `y` Yield `bar` `g` Call#3 Call#2 Call#0 + /// ```plain,ignore + /// `foo` `f` Call#1 `y` Yield `bar` `g` Call#3 Call#2 Call#0 /// ``` /// /// In which we can easily see that `Call#1` occurs before the yield, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 93ae101eb142..548296b77f9c 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -362,7 +362,9 @@ enum EvaluationResult { /// When checking `foo`, we have to prove `T: Trait`. This basically /// translates into this: /// + /// ```plain,ignore /// (T: Trait + Sized →_\impl T: Trait), T: Trait ⊢ T: Trait + /// ``` /// /// When we try to prove it, we first go the first option, which /// recurses. This shows us that the impl is "useless" - it won't diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 97dcf081f8c8..3a97d2767444 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -427,14 +427,14 @@ fn generate_fn_name_span(cm: &CodeMap, span: Span) -> Option { /// a new local type parameter. /// /// For instance: -/// ``` +/// ```rust,ignore (pseudo-Rust) /// // Given span /// fn my_function(param: T) -/// ^ Original span +/// // ^ Original span /// /// // Result /// fn my_function(param: T) -/// ^^^^^^^^^^^ Generated span with snippet `my_function` +/// // ^^^^^^^^^^^ Generated span with snippet `my_function` /// ``` /// /// Attention: The method used is very fragile since it essentially duplicates the work of the diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 9ed4ab45a1ba..b5e862fac958 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1164,10 +1164,12 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// constraint that `'z <= 'a`. Given this setup, let's clarify the /// parameters in (roughly) terms of the example: /// + /// ```plain,ignore (pseudo-Rust) /// A borrow of: `& 'z bk * r` where `r` has type `& 'a bk T` /// borrow_region ^~ ref_region ^~ /// borrow_kind ^~ ref_kind ^~ /// ref_cmt ^ + /// ``` /// /// Here `bk` stands for some borrow-kind (e.g., `mut`, `uniq`, etc). /// diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 1eed1bf4b71f..faf3ccb1133a 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -42,21 +42,21 @@ use syntax_pos::Span; /// /// Example: /// -/// ``` +/// ```rust,ignore (pseudo-Rust) /// impl Trait for Bar { ... } -/// ^ T does not appear in `Foo` or `Bar`, error! +/// // ^ T does not appear in `Foo` or `Bar`, error! /// /// impl Trait> for Bar { ... } -/// ^ T appears in `Foo`, ok. +/// // ^ T appears in `Foo`, ok. /// /// impl Trait for Bar where Bar: Iterator { ... } -/// ^ T is bound to `::Item`, ok. +/// // ^ T is bound to `::Item`, ok. /// /// impl<'a> Trait for Bar { } -/// ^ 'a is unused, but for back-compat we allow it +/// // ^ 'a is unused, but for back-compat we allow it /// /// impl<'a> Trait for Bar { type X = &'a i32; } -/// ^ 'a is unused and appears in assoc type, error +/// // ^ 'a is unused and appears in assoc type, error /// ``` pub fn impl_wf_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { // We will tag this as part of the WF check -- logically, it is, From 14768f9b636ef345320ded41da5e9f3da7af3a81 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 4 Apr 2018 19:24:57 +0200 Subject: [PATCH 824/830] create a nostd crate the goal is to build, in a single Cargo invocation, several no-std crates that we want to put in the rust-std component of no-std targets. The nostd crate builds these crates: - core - compiler-builtin (with the "c" and "mem" features enabled) - alloc - std_unicode --- src/Cargo.lock | 10 ++++++++++ src/Cargo.toml | 1 + src/bootstrap/compile.rs | 8 ++++---- src/libnostd/Cargo.toml | 17 +++++++++++++++++ src/libnostd/lib.rs | 3 +++ 5 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/libnostd/Cargo.toml create mode 100644 src/libnostd/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 1f7cf84cedbd..42ac9b3c49de 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1081,6 +1081,16 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nostd" +version = "0.0.0" +dependencies = [ + "alloc 0.0.0", + "compiler_builtins 0.0.0", + "core 0.0.0", + "std_unicode 0.0.0", +] + [[package]] name = "num" version = "0.1.42" diff --git a/src/Cargo.toml b/src/Cargo.toml index 814c054c51e4..babf35d570b5 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -2,6 +2,7 @@ members = [ "bootstrap", "rustc", + "libnostd", "libstd", "libtest", "librustc_trans", diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index eaf4ab272c68..a93b26ac2bae 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -145,10 +145,10 @@ pub fn std_cargo(build: &Builder, } if build.no_std(target) == Some(true) { - // for no-std targets we only compile core and compiler-builtins - cargo.arg("--features").arg("c mem") - .arg("--manifest-path") - .arg(build.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); + // for no-std targets we compile a minimal nostd crate that only depends on crates that work + // without an OS + cargo.arg("--manifest-path") + .arg(build.src.join("src/libnostd/Cargo.toml")); } else { let mut features = build.std_features(); diff --git a/src/libnostd/Cargo.toml b/src/libnostd/Cargo.toml new file mode 100644 index 000000000000..6919390d3e2a --- /dev/null +++ b/src/libnostd/Cargo.toml @@ -0,0 +1,17 @@ +[package] +authors = ["The Rust Project Developers"] +name = "nostd" +version = "0.0.0" +license = "MIT/Apache-2.0" +repository = "https://github.com/rust-lang/rust.git" +description = "(not) The Rust Standard Library" + +[lib] +name = "nostd" +path = "lib.rs" + +[dependencies] +alloc = { path = "../liballoc" } +compiler_builtins = { path = "../rustc/compiler_builtins_shim", features = ["c", "mem"] } +core = { path = "../libcore" } +std_unicode = { path = "../libstd_unicode" } \ No newline at end of file diff --git a/src/libnostd/lib.rs b/src/libnostd/lib.rs new file mode 100644 index 000000000000..d28afe2838e2 --- /dev/null +++ b/src/libnostd/lib.rs @@ -0,0 +1,3 @@ +#![feature(staged_api)] +#![no_std] +#![unstable(feature = "nostd", issue = "0")] From bca569f57c53e219270be72ed5976b8167fcd246 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 4 Apr 2018 22:23:33 +0200 Subject: [PATCH 825/830] Revert "create a nostd crate" This reverts commit 14768f9b636ef345320ded41da5e9f3da7af3a81. --- src/Cargo.lock | 10 ---------- src/Cargo.toml | 1 - src/bootstrap/compile.rs | 8 ++++---- src/libnostd/Cargo.toml | 17 ----------------- src/libnostd/lib.rs | 3 --- 5 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 src/libnostd/Cargo.toml delete mode 100644 src/libnostd/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 42ac9b3c49de..1f7cf84cedbd 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1081,16 +1081,6 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "nostd" -version = "0.0.0" -dependencies = [ - "alloc 0.0.0", - "compiler_builtins 0.0.0", - "core 0.0.0", - "std_unicode 0.0.0", -] - [[package]] name = "num" version = "0.1.42" diff --git a/src/Cargo.toml b/src/Cargo.toml index babf35d570b5..814c054c51e4 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -2,7 +2,6 @@ members = [ "bootstrap", "rustc", - "libnostd", "libstd", "libtest", "librustc_trans", diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index a93b26ac2bae..eaf4ab272c68 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -145,10 +145,10 @@ pub fn std_cargo(build: &Builder, } if build.no_std(target) == Some(true) { - // for no-std targets we compile a minimal nostd crate that only depends on crates that work - // without an OS - cargo.arg("--manifest-path") - .arg(build.src.join("src/libnostd/Cargo.toml")); + // for no-std targets we only compile core and compiler-builtins + cargo.arg("--features").arg("c mem") + .arg("--manifest-path") + .arg(build.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); } else { let mut features = build.std_features(); diff --git a/src/libnostd/Cargo.toml b/src/libnostd/Cargo.toml deleted file mode 100644 index 6919390d3e2a..000000000000 --- a/src/libnostd/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "nostd" -version = "0.0.0" -license = "MIT/Apache-2.0" -repository = "https://github.com/rust-lang/rust.git" -description = "(not) The Rust Standard Library" - -[lib] -name = "nostd" -path = "lib.rs" - -[dependencies] -alloc = { path = "../liballoc" } -compiler_builtins = { path = "../rustc/compiler_builtins_shim", features = ["c", "mem"] } -core = { path = "../libcore" } -std_unicode = { path = "../libstd_unicode" } \ No newline at end of file diff --git a/src/libnostd/lib.rs b/src/libnostd/lib.rs deleted file mode 100644 index d28afe2838e2..000000000000 --- a/src/libnostd/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![feature(staged_api)] -#![no_std] -#![unstable(feature = "nostd", issue = "0")] From b1015f5c5a4dcd6118b86ef5361371f04a7bce8b Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 4 Apr 2018 22:42:56 +0200 Subject: [PATCH 826/830] compile other no-std crates --- src/bootstrap/compile.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index eaf4ab272c68..51e7a7883158 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -145,8 +145,11 @@ pub fn std_cargo(build: &Builder, } if build.no_std(target) == Some(true) { - // for no-std targets we only compile core and compiler-builtins + // for no-std targets we only compile a few no_std crates cargo.arg("--features").arg("c mem") + .args(&["-p", "alloc"]) + .args(&["-p", "compiler_builtins"]) + .args(&["-p", "std_unicode"]) .arg("--manifest-path") .arg(build.src.join("src/rustc/compiler_builtins_shim/Cargo.toml")); } else { From 323795534f27e08b7adc9342d7ba66cd21e044a9 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 4 Apr 2018 13:58:38 -0700 Subject: [PATCH 827/830] Add more features to rust_2018_preview --- src/libsyntax/feature_gate.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e734a4e37353..1f4ad2dc8639 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -193,7 +193,7 @@ declare_features! ( (active, rustc_attrs, "1.0.0", Some(29642), None), // Allows the use of non lexical lifetimes; RFC 2094 - (active, nll, "1.0.0", Some(43234), None), + (active, nll, "1.0.0", Some(43234), Some(Edition::Edition2018)), // Allows the use of #[allow_internal_unstable]. This is an // attribute on macro_rules! and can't use the attribute handling @@ -391,7 +391,7 @@ declare_features! ( (active, dyn_trait, "1.22.0", Some(44662), Some(Edition::Edition2018)), // `crate` as visibility modifier, synonymous to `pub(crate)` - (active, crate_visibility_modifier, "1.23.0", Some(45388), None), + (active, crate_visibility_modifier, "1.23.0", Some(45388), Some(Edition::Edition2018)), // extern types (active, extern_types, "1.23.0", Some(43467), None), @@ -400,10 +400,10 @@ declare_features! ( (active, arbitrary_self_types, "1.23.0", Some(44874), None), // `crate` in paths - (active, crate_in_paths, "1.23.0", Some(45477), None), + (active, crate_in_paths, "1.23.0", Some(45477), Some(Edition::Edition2018)), // In-band lifetime bindings (e.g. `fn foo(x: &'a u8) -> &'a u8`) - (active, in_band_lifetimes, "1.23.0", Some(44524), None), + (active, in_band_lifetimes, "1.23.0", Some(44524), Some(Edition::Edition2018)), // generic associated types (RFC 1598) (active, generic_associated_types, "1.23.0", Some(44265), None), @@ -412,10 +412,10 @@ declare_features! ( (active, extern_absolute_paths, "1.24.0", Some(44660), None), // `foo.rs` as an alternative to `foo/mod.rs` - (active, non_modrs_mods, "1.24.0", Some(44660), None), + (active, non_modrs_mods, "1.24.0", Some(44660), Some(Edition::Edition2018)), // Termination trait in tests (RFC 1937) - (active, termination_trait_test, "1.24.0", Some(48854), None), + (active, termination_trait_test, "1.24.0", Some(48854), Some(Edition::Edition2018)), // Allows use of the :lifetime macro fragment specifier (active, macro_lifetime_matcher, "1.24.0", Some(46895), None), From ae86e83c526af80db2571e1b4acab2aee0d6bd09 Mon Sep 17 00:00:00 2001 From: Boris-Chengbiao Zhou Date: Mon, 2 Apr 2018 16:08:03 +0200 Subject: [PATCH 828/830] Update RLS --- src/Cargo.lock | 29 ++++------------------------- src/tools/rls | 2 +- 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 5b918a063b07..2f77d4125ab0 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -288,26 +288,6 @@ dependencies = [ name = "clippy-mini-macro-test" version = "0.2.0" -[[package]] -name = "clippy_lints" -version = "0.0.189" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clippy_lints" version = "0.0.191" @@ -910,7 +890,7 @@ dependencies = [ [[package]] name = "languageserver-types" -version = "0.31.0" +version = "0.35.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)", @@ -1459,12 +1439,12 @@ version = "0.126.0" dependencies = [ "cargo 0.27.0", "cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy_lints 0.0.189 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.191", "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "languageserver-types 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", + "languageserver-types 0.35.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2702,7 +2682,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ba5f60682a4c264e7f8d77b82e7788938a76befdf949d4a98026d19099c9d873" "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" -"checksum clippy_lints 0.0.189 (registry+https://github.com/rust-lang/crates.io-index)" = "fef652630bbf8c5e89601220abd000f5057e8fa9db608484b5ebaad98e9bce53" "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" @@ -2757,7 +2736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be" "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum languageserver-types 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d25086d59f44b80253d5ff96c66a692fb69de8485cf7a25b28677e89126de0d" +"checksum languageserver-types 0.35.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36e264ab825353617bbc80844717555be6e9e1d403474b1d0a3b8e190440b13e" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" diff --git a/src/tools/rls b/src/tools/rls index f5a0c91a3936..b17d799d1302 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit f5a0c91a39368395b1c1ad322e04be7b6074bc65 +Subproject commit b17d799d1302fd643a3dd19280f64c8ad162a4a2 From 1a2a23447e451faee7ffbffab2be8831f3098f6d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 8 Mar 2018 22:24:10 +0300 Subject: [PATCH 829/830] Stabilize attributes on generic parameters --- src/liballoc/lib.rs | 2 +- src/libarena/lib.rs | 2 +- src/librustc_typeck/diagnostics.rs | 1 - src/libstd/lib.rs | 2 +- src/libsyntax/feature_gate.rs | 20 +-- .../attrs-with-no-formal-in-generics-1.rs | 3 +- .../attrs-with-no-formal-in-generics-2.rs | 3 +- src/test/compile-fail/synthetic-param.rs | 2 +- .../end_region_destruction_extents_1.rs | 1 - src/test/run-pass/attr-on-generic-formals.rs | 2 +- .../auxiliary/dropck_eyepatch_extern_crate.rs | 1 - src/test/run-pass/dropck-eyepatch-reorder.rs | 1 - src/test/run-pass/dropck-eyepatch.rs | 1 - .../auxiliary/dropck_eyepatch_extern_crate.rs | 1 - .../dropck-eyepatch-implies-unsafe-impl.rs | 1 - ...dropck-eyepatch-implies-unsafe-impl.stderr | 4 +- src/test/ui/dropck/dropck-eyepatch-reorder.rs | 1 - .../ui/dropck/dropck-eyepatch-reorder.stderr | 8 +- src/test/ui/dropck/dropck-eyepatch.rs | 1 - src/test/ui/dropck/dropck-eyepatch.stderr | 8 +- src/test/ui/feature-gate-custom_attribute2.rs | 7 - .../ui/feature-gate-custom_attribute2.stderr | 34 ++--- .../feature-gate-generic_param_attrs.stderr | 139 ------------------ src/test/ui/feature-gate-may-dangle.rs | 2 - src/test/ui/feature-gate-may-dangle.stderr | 2 +- ..._param_attrs.rs => generic-param-attrs.rs} | 34 +---- src/test/ui/nll/drop-may-dangle.rs | 1 - src/test/ui/nll/drop-no-may-dangle.rs | 1 - src/test/ui/nll/drop-no-may-dangle.stderr | 4 +- 29 files changed, 45 insertions(+), 244 deletions(-) delete mode 100644 src/test/ui/feature-gate-generic_param_attrs.stderr rename src/test/ui/{feature-gate-generic_param_attrs.rs => generic-param-attrs.rs} (53%) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 2fad3b0bad4a..cbbea6c19c8d 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -97,7 +97,7 @@ #![feature(fmt_internals)] #![feature(from_ref)] #![feature(fundamental)] -#![feature(generic_param_attrs)] +#![cfg_attr(stage0, feature(generic_param_attrs))] #![cfg_attr(stage0, feature(i128_type))] #![feature(iter_rfold)] #![feature(lang_items)] diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 72fa3148fe54..7eaf67e6ea66 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -27,7 +27,7 @@ #![feature(alloc)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] -#![feature(generic_param_attrs)] +#![cfg_attr(stage0, feature(generic_param_attrs))] #![cfg_attr(test, feature(test))] #![allow(deprecated)] diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 99726bb65f38..79d7c8e72821 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3784,7 +3784,6 @@ that impl must be declared as an `unsafe impl. Erroneous code example: ```compile_fail,E0569 -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] struct Foo(X); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e18e055654bc..3f1fec4c3177 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -266,7 +266,7 @@ #![feature(float_from_str_radix)] #![feature(fn_traits)] #![feature(fnbox)] -#![feature(generic_param_attrs)] +#![cfg_attr(stage0, feature(generic_param_attrs))] #![feature(hashmap_internals)] #![feature(heap_api)] #![cfg_attr(stage0, feature(i128_type, i128))] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e734a4e37353..1cf62a8bf33f 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -288,9 +288,6 @@ declare_features! ( // rustc internal (active, compiler_builtins, "1.13.0", None, None), - // Allows attributes on lifetime/type formal parameters in generics (RFC 1327) - (active, generic_param_attrs, "1.11.0", Some(34761), None), - // Allows #[link(..., cfg(..))] (active, link_cfg, "1.14.0", Some(37406), None), @@ -566,6 +563,8 @@ declare_features! ( (accepted, match_default_bindings, "1.26.0", Some(42640), None), // allow `'_` placeholder lifetimes (accepted, underscore_lifetimes, "1.26.0", Some(44524), None), + // Allows attributes on lifetime/type formal parameters in generics (RFC 1327) + (accepted, generic_param_attrs, "1.26.0", Some(48848), None), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -1775,21 +1774,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } visit::walk_vis(self, vis); } - - fn visit_generic_param(&mut self, param: &'a ast::GenericParam) { - let (attrs, explain) = match *param { - ast::GenericParam::Lifetime(ref ld) => - (&ld.attrs, "attributes on lifetime bindings are experimental"), - ast::GenericParam::Type(ref t) => - (&t.attrs, "attributes on type parameter bindings are experimental"), - }; - - if !attrs.is_empty() { - gate_feature_post!(&self, generic_param_attrs, attrs[0].span, explain); - } - - visit::walk_generic_param(self, param) - } } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], diff --git a/src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs b/src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs index 53e287cda208..ec7885f1f44f 100644 --- a/src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs +++ b/src/test/compile-fail/attrs-with-no-formal-in-generics-1.rs @@ -12,8 +12,7 @@ // `#[oops]` is left dangling (that is, it is unattached, with no // formal binding following it). -#![feature(generic_param_attrs, rustc_attrs)] -#![allow(dead_code)] +#![feature(rustc_attrs)] struct RefIntPair<'a, 'b>(&'a u32, &'b u32); diff --git a/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs b/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs index 5e09473ab77d..efe2d5561a83 100644 --- a/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs +++ b/src/test/compile-fail/attrs-with-no-formal-in-generics-2.rs @@ -12,8 +12,7 @@ // `#[oops]` is left dangling (that is, it is unattached, with no // formal binding following it). -#![feature(generic_param_attrs, rustc_attrs)] -#![allow(dead_code)] +#![feature(rustc_attrs)] struct RefAny<'a, T>(&'a T); diff --git a/src/test/compile-fail/synthetic-param.rs b/src/test/compile-fail/synthetic-param.rs index a9762e383fe4..337cae1369ee 100644 --- a/src/test/compile-fail/synthetic-param.rs +++ b/src/test/compile-fail/synthetic-param.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs, rustc_attrs)] +#![feature(rustc_attrs)] fn func<#[rustc_synthetic] T>(_: T) {} diff --git a/src/test/mir-opt/end_region_destruction_extents_1.rs b/src/test/mir-opt/end_region_destruction_extents_1.rs index 69c5cdccf49d..e189f2e3b34a 100644 --- a/src/test/mir-opt/end_region_destruction_extents_1.rs +++ b/src/test/mir-opt/end_region_destruction_extents_1.rs @@ -14,7 +14,6 @@ // A scenario with significant destruction code extents (which have // suffix "dce" in current `-Z identify_regions` rendering). -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] fn main() { diff --git a/src/test/run-pass/attr-on-generic-formals.rs b/src/test/run-pass/attr-on-generic-formals.rs index 5985284d8496..e87b9e3d82a2 100644 --- a/src/test/run-pass/attr-on-generic-formals.rs +++ b/src/test/run-pass/attr-on-generic-formals.rs @@ -17,7 +17,7 @@ // using `rustc_attrs` feature. There is a separate compile-fail/ test // ensuring that the attribute feature-gating works in this context.) -#![feature(generic_param_attrs, rustc_attrs)] +#![feature(rustc_attrs)] #![allow(dead_code)] struct StLt<#[rustc_lt_struct] 'a>(&'a u32); diff --git a/src/test/run-pass/auxiliary/dropck_eyepatch_extern_crate.rs b/src/test/run-pass/auxiliary/dropck_eyepatch_extern_crate.rs index 1266e589b127..d89129434411 100644 --- a/src/test/run-pass/auxiliary/dropck_eyepatch_extern_crate.rs +++ b/src/test/run-pass/auxiliary/dropck_eyepatch_extern_crate.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] // The point of this test is to illustrate that the `#[may_dangle]` diff --git a/src/test/run-pass/dropck-eyepatch-reorder.rs b/src/test/run-pass/dropck-eyepatch-reorder.rs index bbf8bb8c3523..a99a7232e9eb 100644 --- a/src/test/run-pass/dropck-eyepatch-reorder.rs +++ b/src/test/run-pass/dropck-eyepatch-reorder.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] // The point of this test is to test uses of `#[may_dangle]` attribute diff --git a/src/test/run-pass/dropck-eyepatch.rs b/src/test/run-pass/dropck-eyepatch.rs index 4a09ba05dff5..c0c091d78eb1 100644 --- a/src/test/run-pass/dropck-eyepatch.rs +++ b/src/test/run-pass/dropck-eyepatch.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] // The point of this test is to illustrate that the `#[may_dangle]` diff --git a/src/test/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs b/src/test/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs index 1b00d88dcb3d..08722ca62ac4 100644 --- a/src/test/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs +++ b/src/test/ui/dropck/auxiliary/dropck_eyepatch_extern_crate.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] // This is a support file for ../dropck-eyepatch-extern-crate.rs diff --git a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs index f92c8703dc92..cba438b02a92 100644 --- a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs +++ b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] // This test ensures that a use of `#[may_dangle]` is rejected if diff --git a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr index f4ea7f1bc509..9d68ff13ef34 100644 --- a/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-implies-unsafe-impl.stderr @@ -1,5 +1,5 @@ error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attribute - --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:32:1 + --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:31:1 | LL | / impl<#[may_dangle] A, B: fmt::Debug> Drop for Pt { LL | | //~^ ERROR requires an `unsafe impl` declaration due to `#[may_dangle]` attribute @@ -10,7 +10,7 @@ LL | | } | |_^ error[E0569]: requires an `unsafe impl` declaration due to `#[may_dangle]` attribute - --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:38:1 + --> $DIR/dropck-eyepatch-implies-unsafe-impl.rs:37:1 | LL | / impl<#[may_dangle] 'a, 'b, B: fmt::Debug> Drop for Pr<'a, 'b, B> { LL | | //~^ ERROR requires an `unsafe impl` declaration due to `#[may_dangle]` attribute diff --git a/src/test/ui/dropck/dropck-eyepatch-reorder.rs b/src/test/ui/dropck/dropck-eyepatch-reorder.rs index 3bd9efb32b3b..eda8d85f6ec9 100644 --- a/src/test/ui/dropck/dropck-eyepatch-reorder.rs +++ b/src/test/ui/dropck/dropck-eyepatch-reorder.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] // The point of this test is to test uses of `#[may_dangle]` attribute diff --git a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr index e6ce53402f4f..1a35996a0cad 100644 --- a/src/test/ui/dropck/dropck-eyepatch-reorder.stderr +++ b/src/test/ui/dropck/dropck-eyepatch-reorder.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch-reorder.rs:57:20 + --> $DIR/dropck-eyepatch-reorder.rs:56:20 | LL | dt = Dt("dt", &c); | ^ borrowed value does not live long enough @@ -10,7 +10,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are created error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch-reorder.rs:59:20 + --> $DIR/dropck-eyepatch-reorder.rs:58:20 | LL | dr = Dr("dr", &c); | ^ borrowed value does not live long enough @@ -21,7 +21,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are created error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch-reorder.rs:67:29 + --> $DIR/dropck-eyepatch-reorder.rs:66:29 | LL | pt = Pt("pt", &c_long, &c); | ^ borrowed value does not live long enough @@ -32,7 +32,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are created error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch-reorder.rs:69:29 + --> $DIR/dropck-eyepatch-reorder.rs:68:29 | LL | pr = Pr("pr", &c_long, &c); | ^ borrowed value does not live long enough diff --git a/src/test/ui/dropck/dropck-eyepatch.rs b/src/test/ui/dropck/dropck-eyepatch.rs index abaae47189f8..af173a2e9791 100644 --- a/src/test/ui/dropck/dropck-eyepatch.rs +++ b/src/test/ui/dropck/dropck-eyepatch.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(generic_param_attrs)] #![feature(dropck_eyepatch)] // The point of this test is to illustrate that the `#[may_dangle]` diff --git a/src/test/ui/dropck/dropck-eyepatch.stderr b/src/test/ui/dropck/dropck-eyepatch.stderr index 5e0a4a744212..4d2916420229 100644 --- a/src/test/ui/dropck/dropck-eyepatch.stderr +++ b/src/test/ui/dropck/dropck-eyepatch.stderr @@ -1,5 +1,5 @@ error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch.rs:80:20 + --> $DIR/dropck-eyepatch.rs:79:20 | LL | dt = Dt("dt", &c); | ^ borrowed value does not live long enough @@ -10,7 +10,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are created error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch.rs:82:20 + --> $DIR/dropck-eyepatch.rs:81:20 | LL | dr = Dr("dr", &c); | ^ borrowed value does not live long enough @@ -21,7 +21,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are created error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch.rs:90:29 + --> $DIR/dropck-eyepatch.rs:89:29 | LL | pt = Pt("pt", &c_long, &c); | ^ borrowed value does not live long enough @@ -32,7 +32,7 @@ LL | } = note: values in a scope are dropped in the opposite order they are created error[E0597]: `c` does not live long enough - --> $DIR/dropck-eyepatch.rs:92:29 + --> $DIR/dropck-eyepatch.rs:91:29 | LL | pr = Pr("pr", &c_long, &c); | ^ borrowed value does not live long enough diff --git a/src/test/ui/feature-gate-custom_attribute2.rs b/src/test/ui/feature-gate-custom_attribute2.rs index 0d89c52d885f..30fd89f091b4 100644 --- a/src/test/ui/feature-gate-custom_attribute2.rs +++ b/src/test/ui/feature-gate-custom_attribute2.rs @@ -10,16 +10,9 @@ // This test ensures that attributes on formals in generic parameter // lists are included when we are checking for unstable attributes. -// -// Note that feature(generic_param_attrs) *is* enabled here. We are -// checking feature-gating of the attributes themselves, not the -// capability to parse such attributes in that context. // gate-test-custom_attribute -#![feature(generic_param_attrs)] -#![allow(dead_code)] - struct StLt<#[lt_struct] 'a>(&'a u32); //~^ ERROR The attribute `lt_struct` is currently unknown to the compiler struct StTy<#[ty_struct] I>(I); diff --git a/src/test/ui/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gate-custom_attribute2.stderr index 90be45a33eac..1c1f50366d64 100644 --- a/src/test/ui/feature-gate-custom_attribute2.stderr +++ b/src/test/ui/feature-gate-custom_attribute2.stderr @@ -1,5 +1,5 @@ error[E0658]: The attribute `lt_struct` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:23:13 + --> $DIR/feature-gate-custom_attribute2.rs:16:13 | LL | struct StLt<#[lt_struct] 'a>(&'a u32); | ^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | struct StLt<#[lt_struct] 'a>(&'a u32); = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_struct` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:25:13 + --> $DIR/feature-gate-custom_attribute2.rs:18:13 | LL | struct StTy<#[ty_struct] I>(I); | ^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | struct StTy<#[ty_struct] I>(I); = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_enum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:28:11 + --> $DIR/feature-gate-custom_attribute2.rs:21:11 | LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } | ^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_enum` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:30:11 + --> $DIR/feature-gate-custom_attribute2.rs:23:11 | LL | enum EnTy<#[ty_enum] J> { A(J), B } | ^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | enum EnTy<#[ty_enum] J> { A(J), B } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_trait` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:33:12 + --> $DIR/feature-gate-custom_attribute2.rs:26:12 | LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } | ^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_trait` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:35:12 + --> $DIR/feature-gate-custom_attribute2.rs:28:12 | LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } | ^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_type` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:38:11 + --> $DIR/feature-gate-custom_attribute2.rs:31:11 | LL | type TyLt<#[lt_type] 'd> = &'d u32; | ^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | type TyLt<#[lt_type] 'd> = &'d u32; = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_type` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:40:11 + --> $DIR/feature-gate-custom_attribute2.rs:33:11 | LL | type TyTy<#[ty_type] L> = (L, ); | ^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | type TyTy<#[ty_type] L> = (L, ); = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_inherent` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:43:6 + --> $DIR/feature-gate-custom_attribute2.rs:36:6 | LL | impl<#[lt_inherent] 'e> StLt<'e> { } | ^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | impl<#[lt_inherent] 'e> StLt<'e> { } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_inherent` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:45:6 + --> $DIR/feature-gate-custom_attribute2.rs:38:6 | LL | impl<#[ty_inherent] M> StTy { } | ^^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | impl<#[ty_inherent] M> StTy { } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_impl_for` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:48:6 + --> $DIR/feature-gate-custom_attribute2.rs:41:6 | LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { | ^^^^^^^^^^^^^^ @@ -87,7 +87,7 @@ LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> { = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_impl_for` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:52:6 + --> $DIR/feature-gate-custom_attribute2.rs:45:6 | LL | impl<#[ty_impl_for] N> TrTy for StTy { | ^^^^^^^^^^^^^^ @@ -95,7 +95,7 @@ LL | impl<#[ty_impl_for] N> TrTy for StTy { = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_fn` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:57:9 + --> $DIR/feature-gate-custom_attribute2.rs:50:9 | LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } | ^^^^^^^^ @@ -103,7 +103,7 @@ LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_fn` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:59:9 + --> $DIR/feature-gate-custom_attribute2.rs:52:9 | LL | fn f_ty<#[ty_fn] O>(_: O) { } | ^^^^^^^^ @@ -111,7 +111,7 @@ LL | fn f_ty<#[ty_fn] O>(_: O) { } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_meth` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:63:13 + --> $DIR/feature-gate-custom_attribute2.rs:56:13 | LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } | ^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `ty_meth` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:65:13 + --> $DIR/feature-gate-custom_attribute2.rs:58:13 | LL | fn m_ty<#[ty_meth] P>(_: P) { } | ^^^^^^^^^^ @@ -127,7 +127,7 @@ LL | fn m_ty<#[ty_meth] P>(_: P) { } = help: add #![feature(custom_attribute)] to the crate attributes to enable error[E0658]: The attribute `lt_hof` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) - --> $DIR/feature-gate-custom_attribute2.rs:70:19 + --> $DIR/feature-gate-custom_attribute2.rs:63:19 | LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 | ^^^^^^^^^ diff --git a/src/test/ui/feature-gate-generic_param_attrs.stderr b/src/test/ui/feature-gate-generic_param_attrs.stderr deleted file mode 100644 index 7b449242c326..000000000000 --- a/src/test/ui/feature-gate-generic_param_attrs.stderr +++ /dev/null @@ -1,139 +0,0 @@ -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:22:13 - | -LL | struct StLt<#[rustc_lt_struct] 'a>(&'a u32); - | ^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:24:13 - | -LL | struct StTy<#[rustc_ty_struct] I>(I); - | ^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:27:11 - | -LL | enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:29:11 - | -LL | enum EnTy<#[rustc_ty_enum] J> { A(J), B } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:32:12 - | -LL | trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } - | ^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:34:12 - | -LL | trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); } - | ^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:37:11 - | -LL | type TyLt<#[rustc_lt_type] 'd> = &'d u32; - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:39:11 - | -LL | type TyTy<#[rustc_ty_type] L> = (L, ); - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:42:6 - | -LL | impl<#[rustc_lt_inherent] 'e> StLt<'e> { } - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:44:6 - | -LL | impl<#[rustc_ty_inherent] M> StTy { } - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:47:6 - | -LL | impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:51:6 - | -LL | impl<#[rustc_ty_impl_for] N> TrTy for StTy { - | ^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:56:9 - | -LL | fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } - | ^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:58:9 - | -LL | fn f_ty<#[rustc_ty_fn] O>(_: O) { } - | ^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:62:13 - | -LL | fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on type parameter bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:64:13 - | -LL | fn m_ty<#[rustc_ty_meth] P>(_: P) { } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error[E0658]: attributes on lifetime bindings are experimental (see issue #34761) - --> $DIR/feature-gate-generic_param_attrs.rs:69:19 - | -LL | where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - | ^^^^^^^^^^^^^^^ - | - = help: add #![feature(generic_param_attrs)] to the crate attributes to enable - -error: aborting due to 17 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gate-may-dangle.rs b/src/test/ui/feature-gate-may-dangle.rs index ace9fe9ab275..a67ece044883 100644 --- a/src/test/ui/feature-gate-may-dangle.rs +++ b/src/test/ui/feature-gate-may-dangle.rs @@ -12,8 +12,6 @@ // Check that `may_dangle` is rejected if `dropck_eyepatch` feature gate is absent. -#![feature(generic_param_attrs)] - struct Pt(A); impl<#[may_dangle] A> Drop for Pt { //~^ ERROR may_dangle has unstable semantics and may be removed in the future diff --git a/src/test/ui/feature-gate-may-dangle.stderr b/src/test/ui/feature-gate-may-dangle.stderr index 85707f6e9212..aad725dfe65e 100644 --- a/src/test/ui/feature-gate-may-dangle.stderr +++ b/src/test/ui/feature-gate-may-dangle.stderr @@ -1,5 +1,5 @@ error[E0658]: may_dangle has unstable semantics and may be removed in the future (see issue #34761) - --> $DIR/feature-gate-may-dangle.rs:18:6 + --> $DIR/feature-gate-may-dangle.rs:16:6 | LL | impl<#[may_dangle] A> Drop for Pt { | ^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gate-generic_param_attrs.rs b/src/test/ui/generic-param-attrs.rs similarity index 53% rename from src/test/ui/feature-gate-generic_param_attrs.rs rename to src/test/ui/generic-param-attrs.rs index 944802f450a6..37fabcd7e1e9 100644 --- a/src/test/ui/feature-gate-generic_param_attrs.rs +++ b/src/test/ui/generic-param-attrs.rs @@ -8,69 +8,47 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// This test ensures that attributes on formals in generic parameter -// lists are rejected if feature(generic_param_attrs) is not enabled. +// This test previously ensured that attributes on formals in generic parameter +// lists are rejected without a feature gate. // // (We are prefixing all tested features with `rustc_`, to ensure that // the attributes themselves won't be rejected by the compiler when // using `rustc_attrs` feature. There is a separate compile-fail/ test // ensuring that the attribute feature-gating works in this context.) +// must-compile-successfully + #![feature(rustc_attrs)] #![allow(dead_code)] struct StLt<#[rustc_lt_struct] 'a>(&'a u32); -//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) struct StTy<#[rustc_ty_struct] I>(I); -//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) - enum EnLt<#[rustc_lt_enum] 'b> { A(&'b u32), B } -//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) enum EnTy<#[rustc_ty_enum] J> { A(J), B } -//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) - trait TrLt<#[rustc_lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; } -//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) trait TrTy<#[rustc_ty_trait] K> { fn foo(&self, _: K); } -//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) - type TyLt<#[rustc_lt_type] 'd> = &'d u32; -//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) type TyTy<#[rustc_ty_type] L> = (L, ); -//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) impl<#[rustc_lt_inherent] 'e> StLt<'e> { } -//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) impl<#[rustc_ty_inherent] M> StTy { } -//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) - impl<#[rustc_lt_impl_for] 'f> TrLt<'f> for StLt<'f> { - //~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } } } impl<#[rustc_ty_impl_for] N> TrTy for StTy { - //~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) fn foo(&self, _: N) { } } fn f_lt<#[rustc_lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } } -//~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) fn f_ty<#[rustc_ty_fn] O>(_: O) { } -//~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) impl StTy { fn m_lt<#[rustc_lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } } - //~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) fn m_ty<#[rustc_ty_meth] P>(_: P) { } - //~^ ERROR attributes on type parameter bindings are experimental (see issue #34761) } fn hof_lt(_: Q) where Q: for <#[rustc_lt_hof] 'i> Fn(&'i [u32]) -> &'i u32 - //~^ ERROR attributes on lifetime bindings are experimental (see issue #34761) -{ -} +{} -fn main() { - -} +fn main() {} diff --git a/src/test/ui/nll/drop-may-dangle.rs b/src/test/ui/nll/drop-may-dangle.rs index 2780b3474637..55c9f5de3020 100644 --- a/src/test/ui/nll/drop-may-dangle.rs +++ b/src/test/ui/nll/drop-may-dangle.rs @@ -17,7 +17,6 @@ #![allow(warnings)] #![feature(dropck_eyepatch)] -#![feature(generic_param_attrs)] fn use_x(_: usize) -> bool { true } diff --git a/src/test/ui/nll/drop-no-may-dangle.rs b/src/test/ui/nll/drop-no-may-dangle.rs index 3d9a5456cbb3..e5478e39fecc 100644 --- a/src/test/ui/nll/drop-no-may-dangle.rs +++ b/src/test/ui/nll/drop-no-may-dangle.rs @@ -17,7 +17,6 @@ #![allow(warnings)] #![feature(dropck_eyepatch)] -#![feature(generic_param_attrs)] fn use_x(_: usize) -> bool { true } diff --git a/src/test/ui/nll/drop-no-may-dangle.stderr b/src/test/ui/nll/drop-no-may-dangle.stderr index 6454413901be..a35271bdcfef 100644 --- a/src/test/ui/nll/drop-no-may-dangle.stderr +++ b/src/test/ui/nll/drop-no-may-dangle.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `v[..]` because it is borrowed - --> $DIR/drop-no-may-dangle.rs:31:9 + --> $DIR/drop-no-may-dangle.rs:30:9 | LL | let p: WrapMayNotDangle<&usize> = WrapMayNotDangle { value: &v[0] }; | ----- borrow of `v[..]` occurs here @@ -11,7 +11,7 @@ LL | } | - borrow later used here, when `p` is dropped error[E0506]: cannot assign to `v[..]` because it is borrowed - --> $DIR/drop-no-may-dangle.rs:34:5 + --> $DIR/drop-no-may-dangle.rs:33:5 | LL | let p: WrapMayNotDangle<&usize> = WrapMayNotDangle { value: &v[0] }; | ----- borrow of `v[..]` occurs here From 621ccf8917b25d66aff3beb45c540afbda29e980 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 4 Apr 2018 17:35:42 -0700 Subject: [PATCH 830/830] ci: Remove x86_64-gnu-incremental builder This builder is starting to time out frequently causing PRs to bounce and otherwise doesn't seem to be catching too many bugs, so this commit removes it entirely. We've had a number of timeouts in the last few weeks related to this builder: * https://travis-ci.org/rust-lang/rust/jobs/360947582 * https://travis-ci.org/rust-lang/rust/jobs/360464190 * https://travis-ci.org/rust-lang/rust/jobs/359946975 * https://travis-ci.org/rust-lang/rust/jobs/361213241 * https://travis-ci.org/rust-lang/rust/jobs/362346279 * https://travis-ci.org/rust-lang/rust/jobs/362072331 On a good run this builder takes about 2h15m, which is already too long for Travis and the variable build times end up pushing it beyond the 3h limit occasionally. The timeouts here are somewhat expected in that an incrementally compiled rustc compiler isn't optimized like a normal rustc, disallowing inlining between codegen units and losing lots of optimization opportunities. --- .travis.yml | 2 -- .../docker/x86_64-gnu-incremental/Dockerfile | 22 ------------------- 2 files changed, 24 deletions(-) delete mode 100644 src/ci/docker/x86_64-gnu-incremental/Dockerfile diff --git a/.travis.yml b/.travis.yml index f465ba422817..36329ab91143 100644 --- a/.travis.yml +++ b/.travis.yml @@ -171,8 +171,6 @@ matrix: if: branch = auto - env: IMAGE=x86_64-gnu-distcheck if: branch = auto - - env: IMAGE=x86_64-gnu-incremental - if: branch = auto - stage: publish toolstate if: branch = master AND type = push diff --git a/src/ci/docker/x86_64-gnu-incremental/Dockerfile b/src/ci/docker/x86_64-gnu-incremental/Dockerfile deleted file mode 100644 index 7304ed6015cc..000000000000 --- a/src/ci/docker/x86_64-gnu-incremental/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -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 \ - sudo \ - gdb \ - xz-utils - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu -ENV RUSTFLAGS -Zincremental=/tmp/rust-incr-cache -ENV RUST_CHECK_TARGET check -ENV CARGO_INCREMENTAL 0