From 7e57f0a6a8fd4e5df7890613918f4a2c3b5a1fb7 Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Sun, 2 Sep 2018 22:26:38 -0700 Subject: [PATCH 01/75] Doc total order requirement of sort(_unstable)_by I took the definition of what a total order is from the Ord trait docs. I specifically put "elements of the slice" because if you have a slice of f64s, but know none are NaN, then sorting by partial ord is total in this case. I'm not sure if I should give such an example in the docs or not. --- src/liballoc/slice.rs | 7 +++++++ src/libcore/slice/mod.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 33d28bef2d70..2ded376b395a 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -211,6 +211,13 @@ pub fn sort(&mut self) /// /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case. /// + /// The comparator function must define a total ordering for the elements in the slice. If + /// the ordering is not total, the order of the elements is unspecified. An order is a + /// total order if it is (for all a, b and c): + /// + /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and + /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. + /// /// 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`](#method.sort_unstable_by). diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index a50426ba886b..c22ea0a01f8e 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1339,6 +1339,13 @@ pub fn sort_unstable(&mut self) /// This sort is unstable (i.e. may reorder equal elements), in-place (i.e. does not allocate), /// and `O(n log n)` worst-case. /// + /// The comparator function must define a total ordering for the elements in the slice. If + /// the ordering is not total, the order of the elements is unspecified. An order is a + /// total order if it is (for all a, b and c): + /// + /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and + /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. + /// /// # Current implementation /// /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, From e36bbc82f2fc49945b4ef42ddeca8c1443c3bac4 Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Mon, 3 Sep 2018 23:11:15 -0700 Subject: [PATCH 02/75] Example of total ord of elements for sort_by --- src/liballoc/slice.rs | 6 ++++++ src/libcore/slice/mod.rs | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 2ded376b395a..ad47eb4b70bb 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -242,6 +242,12 @@ pub fn sort(&mut self) /// // reverse sorting /// v.sort_by(|a, b| b.cmp(a)); /// assert!(v == [5, 4, 3, 2, 1]); + /// + /// // While f64 doesn't implement Ord because NaN != NaN, we can use + /// // partial_cmp here because we know none of the elements are NaN. + /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; + /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap()); + /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index c22ea0a01f8e..a6e0389e66f1 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1367,6 +1367,12 @@ pub fn sort_unstable(&mut self) /// // reverse sorting /// v.sort_unstable_by(|a, b| b.cmp(a)); /// assert!(v == [5, 4, 3, 2, 1]); + /// + /// // While f64 doesn't implement Ord because NaN != NaN, we can use + /// // partial_cmp here because we know none of the elements are NaN. + /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; + /// floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap()); + /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); /// ``` /// /// [pdqsort]: https://github.com/orlp/pdqsort From b911dba40b441a65d8566e2013256612a15d27a4 Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Sun, 9 Sep 2018 22:07:17 -0700 Subject: [PATCH 03/75] Slice total example: Move closer to total defn --- src/liballoc/slice.rs | 15 +++++++++------ src/libcore/slice/mod.rs | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index ad47eb4b70bb..0802dc3e5007 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -218,6 +218,15 @@ pub fn sort(&mut self) /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. /// + /// For example, while `f64` doesn't implement `Ord` because `NaN != NaN`, we can use + /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. + /// + /// ``` + /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; + /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap()); + /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); + /// ``` + /// /// 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`](#method.sort_unstable_by). @@ -242,12 +251,6 @@ pub fn sort(&mut self) /// // reverse sorting /// v.sort_by(|a, b| b.cmp(a)); /// assert!(v == [5, 4, 3, 2, 1]); - /// - /// // While f64 doesn't implement Ord because NaN != NaN, we can use - /// // partial_cmp here because we know none of the elements are NaN. - /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; - /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap()); - /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index a6e0389e66f1..f6695d876f8d 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1346,6 +1346,15 @@ pub fn sort_unstable(&mut self) /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. /// + /// For example, while `f64` doesn't implement `Ord` because `NaN != NaN`, we can use + /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. + /// + /// ``` + /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; + /// floats.sort_by(|a, b| a.partial_cmp(b).unwrap()); + /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); + /// ``` + /// /// # Current implementation /// /// The current algorithm is based on [pattern-defeating quicksort][pdqsort] by Orson Peters, @@ -1367,12 +1376,6 @@ pub fn sort_unstable(&mut self) /// // reverse sorting /// v.sort_unstable_by(|a, b| b.cmp(a)); /// assert!(v == [5, 4, 3, 2, 1]); - /// - /// // While f64 doesn't implement Ord because NaN != NaN, we can use - /// // partial_cmp here because we know none of the elements are NaN. - /// let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0]; - /// floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap()); - /// assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]); /// ``` /// /// [pdqsort]: https://github.com/orlp/pdqsort From 99bed21101ef098393c9e6c8eb64f21892dbc8be Mon Sep 17 00:00:00 2001 From: "Havvy (Ryan Scheel)" Date: Mon, 10 Sep 2018 15:38:37 -0700 Subject: [PATCH 04/75] Linkify types in docs --- src/liballoc/slice.rs | 2 +- src/libcore/slice/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 0802dc3e5007..5f992795531e 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -218,7 +218,7 @@ pub fn sort(&mut self) /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. /// - /// For example, while `f64` doesn't implement `Ord` because `NaN != NaN`, we can use + /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. /// /// ``` diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index f6695d876f8d..a9d76376c07b 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1346,7 +1346,7 @@ pub fn sort_unstable(&mut self) /// * total and antisymmetric: exactly one of a < b, a == b or a > b is true; and /// * transitive, a < b and b < c implies a < c. The same must hold for both == and >. /// - /// For example, while `f64` doesn't implement `Ord` because `NaN != NaN`, we can use + /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`. /// /// ``` From bc1885703cb46a462a4be1eea7c4e0f9abbe7a95 Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Mon, 29 Oct 2018 14:44:15 -0400 Subject: [PATCH 05/75] Return &T / &mut T in ManuallyDrop Deref(Mut) impl Without this change the generated documentation looks like this: fn deref(&self) -> & as Deref>::Target Returning the actual type directly makes the generated docs more clear: fn deref(&self) -> &T --- src/libcore/mem.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 22016e8cf417..1f1df51919c4 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1018,7 +1018,7 @@ pub unsafe fn drop(slot: &mut ManuallyDrop) { impl Deref for ManuallyDrop { type Target = T; #[inline] - fn deref(&self) -> &Self::Target { + fn deref(&self) -> &T { &self.value } } @@ -1026,7 +1026,7 @@ fn deref(&self) -> &Self::Target { #[stable(feature = "manually_drop", since = "1.20.0")] impl DerefMut for ManuallyDrop { #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { + fn deref_mut(&mut self) -> &mut T { &mut self.value } } From b937be87cb89f08235a57e07e9c73b4489dc50a1 Mon Sep 17 00:00:00 2001 From: Meltinglava Date: Thu, 8 Nov 2018 15:33:10 +0100 Subject: [PATCH 06/75] Clarifying documentation for collections::hash_map::Entry::or_insert Previous version does not show that or_insert does not insert the passed value, as the passed value was the same value as what was already in the map. --- src/libstd/collections/hash/map.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 8de415e8aed5..f84e03ae765f 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2030,7 +2030,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// /// assert_eq!(map["poneyland"], 12); /// - /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 12).1 += 10; + /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 += 10; /// assert_eq!(map["poneyland"], 22); /// ``` #[unstable(feature = "hash_raw_entry", issue = "54043")] @@ -2652,7 +2652,7 @@ impl<'a, K, V> Entry<'a, K, V> { /// /// assert_eq!(map["poneyland"], 12); /// - /// *map.entry("poneyland").or_insert(12) += 10; + /// *map.entry("poneyland").or_insert(10) += 10; /// assert_eq!(map["poneyland"], 22); /// ``` pub fn or_insert(self, default: V) -> &'a mut V { From efad877c4478d8e9b9627c312f84b5138faf2aec Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Sun, 4 Nov 2018 17:48:30 +0000 Subject: [PATCH 07/75] Updated RELEASES.md for 1.31.0 --- RELEASES.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 15ab97e26fc7..6f5f45aed210 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,76 @@ +Version 1.31.0 (2018-12-06) +========================== + +Language +-------- +- 🎉 [This version marks the release of the 2018 edition of Rust.][54057] 🎉 +- [New lifetime elision rules now allow for eliding lifetimes in functions and + impl headers.][54778] E.g. `impl<'a> Reader for BufReader<'a> {}` can now be + `impl Reader for BufReader<'_> {}`. Lifetimes are still required to be defined + in structs. +- [You can now define and use `const` functions.][54835] These are currently + a strict minimal subset of the [const fn RFC][RFC-911]. Refer to the + [language reference][const-reference] for what exactly is available. +- [You can now use tool lints, which allow you to scope lints from external + tools using attributes.][54870] E.g. `#[allow(clippy::filter_map)]`. +- [`#[no_mangle]` and `#[export_name]` attributes can now be located anywhere in + a crate, not just in exported functions.][54451] +- [You can now use parentheses in pattern matches.][54497] + +Compiler +-------- +- [Updated musl to 1.1.20][54430] + +Libraries +--------- +- [You can now convert `num::NonZero*` types to their raw equivalvents using the + `From` trait.][54240] E.g. `u8` now implements `From`. +- [You can now convert a `&Option` into `Option<&T>` and `&mut Option` + into `Option<&mut T>` using the `From` trait.][53218] +- [You can now multiply (`*`) a `time::Duration` by a `u32`.][52813] + + +Stabilized APIs +--------------- +- [`slice::align_to`] +- [`slice::align_to_mut`] +- [`slice::chunks_exact`] +- [`slice::chunks_exact_mut`] +- [`slice::rchunks`] +- [`slice::rchunks_mut`] +- [`slice::rchunks_exact`] +- [`slice::rchunks_exact_mut`] +- [`Option::replace`] + +Cargo +----- +- [Cargo will now download crates in parallel using HTTP/2.][cargo/6005] + +[52813]: https://github.com/rust-lang/rust/pull/52813/ +[53218]: https://github.com/rust-lang/rust/pull/53218/ +[53555]: https://github.com/rust-lang/rust/issues/53555/ +[54057]: https://github.com/rust-lang/rust/pull/54057/ +[54240]: https://github.com/rust-lang/rust/pull/54240/ +[54430]: https://github.com/rust-lang/rust/pull/54430/ +[54451]: https://github.com/rust-lang/rust/pull/54451/ +[54497]: https://github.com/rust-lang/rust/pull/54497/ +[54778]: https://github.com/rust-lang/rust/pull/54778/ +[54835]: https://github.com/rust-lang/rust/pull/54835/ +[54870]: https://github.com/rust-lang/rust/pull/54870/ +[RFC-911]: https://github.com/rust-lang/rfcs/pull/911 +[`Option::replace`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.replace +[`slice::align_to_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.align_to_mut +[`slice::align_to`]: https://doc.rust-lang.org/std/primitive.slice.html#method.align_to +[`slice::chunks_exact_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact_mut +[`slice::chunks_exact`]: https://doc.rust-lang.org/std/primitive.slice.html#method.chunks_exact +[`slice::rchunks_exact_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_mut +[`slice::rchunks_exact`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_exact +[`slice::rchunks_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_mut +[`slice::rchunks`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks +[cargo/6005]: https://github.com/rust-lang/cargo/pull/6005/ +[const-reference]: https://doc.rust-lang.org/reference/items/functions.html#const-functions + + Version 1.30.0 (2018-10-25) ========================== From 8b750a77fc73290635499494779f77848a8e2b09 Mon Sep 17 00:00:00 2001 From: Meltinglava Date: Tue, 13 Nov 2018 12:20:23 +0100 Subject: [PATCH 08/75] The example values are now easyer to differenciate --- src/libstd/collections/hash/map.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f84e03ae765f..8ebf9b2fdf56 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2026,12 +2026,12 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> { /// use std::collections::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 12); /// - /// assert_eq!(map["poneyland"], 12); + /// map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 3); + /// assert_eq!(map["poneyland"], 3); /// - /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 += 10; - /// assert_eq!(map["poneyland"], 22); + /// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2; + /// assert_eq!(map["poneyland"], 6); /// ``` #[unstable(feature = "hash_raw_entry", issue = "54043")] pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V) @@ -2648,12 +2648,12 @@ impl<'a, K, V> Entry<'a, K, V> { /// use std::collections::HashMap; /// /// let mut map: HashMap<&str, u32> = HashMap::new(); - /// map.entry("poneyland").or_insert(12); /// - /// assert_eq!(map["poneyland"], 12); + /// map.entry("poneyland").or_insert(3); + /// assert_eq!(map["poneyland"], 3); /// - /// *map.entry("poneyland").or_insert(10) += 10; - /// assert_eq!(map["poneyland"], 22); + /// *map.entry("poneyland").or_insert(10) *= 2; + /// assert_eq!(map["poneyland"], 6); /// ``` pub fn or_insert(self, default: V) -> &'a mut V { match self { From a9a48ed3da1134364052322d628fd9d9418998f4 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 14 Nov 2018 16:22:14 -0700 Subject: [PATCH 09/75] Fix VecDeque pretty-printer This fixes the VecDeque pretty-printer to handle cases where head < tail. Closes #55944 --- src/etc/gdb_rust_pretty_printing.py | 14 +++++++++++--- src/test/debuginfo/pretty-std-collections.rs | 11 +++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index e6d5ef1a23ff..27275ba37957 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -293,15 +293,23 @@ class RustStdVecDequePrinter(object): def to_string(self): (tail, head, data_ptr, cap) = \ rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) + if head >= tail: + size = head - tail + else: + size = cap + head - tail return (self.__val.type.get_unqualified_type_name() + - ("(len: %i, cap: %i)" % (head - tail, cap))) + ("(len: %i, cap: %i)" % (size, cap))) def children(self): (tail, head, data_ptr, cap) = \ rustpp.extract_tail_head_ptr_and_cap_from_std_vecdeque(self.__val) gdb_ptr = data_ptr.get_wrapped_value() - for index in xrange(tail, head): - yield (str(index), (gdb_ptr + index).dereference()) + if head >= tail: + size = head - tail + else: + size = cap + head - tail + for index in xrange(0, size): + yield (str(index), (gdb_ptr + ((tail + index) % cap)).dereference()) class RustStdBTreeSetPrinter(object): diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index 8e37a884b34b..0d3f4b90f23e 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -28,6 +28,9 @@ // gdb-command: print vec_deque // gdb-check:$3 = VecDeque(len: 3, cap: 8) = {5, 3, 7} +// gdb-command: print vec_deque2 +// gdb-check:$4 = VecDeque(len: 7, cap: 8) = {2, 3, 4, 5, 6, 7, 8} + #![allow(unused_variables)] use std::collections::BTreeSet; use std::collections::BTreeMap; @@ -54,6 +57,14 @@ fn main() { vec_deque.push_back(3); vec_deque.push_back(7); + // VecDeque where an element was popped. + let mut vec_deque2 = VecDeque::new(); + for i in 1..8 { + vec_deque2.push_back(i) + } + vec_deque2.pop_front(); + vec_deque2.push_back(8); + zzz(); // #break } From 052bdff8fbaef9b3c32eec842fc9c03877651cf5 Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 15 Nov 2018 16:35:23 +0800 Subject: [PATCH 10/75] lint based on closure pipe span --- src/librustc/traits/error_reporting.rs | 16 +++++++++++++++- .../ui/mismatched_types/closure-arg-count.rs | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 2761a954cea8..d08a4b47b31b 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1092,13 +1092,27 @@ pub fn report_arg_count_mismatch( if let Some(found_span) = found_span { err.span_label(found_span, format!("takes {}", found_str)); + // move |_| { ... } + // ^^^^^^^^-- def_span + // + // move |_| { ... } + // ^^^^^-- prefix + let prefix_span = self.tcx.sess.source_map().span_until_char(found_span, '|'); + // move |_| { ... } + // ^^^-- pipe_span + let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) { + span + } else { + found_span + }; + // Suggest to take and ignore the arguments with expected_args_length `_`s if // found arguments is empty (assume the user just wants to ignore args in this case). // For example, if `expected_args_length` is 2, suggest `|_, _|`. if found_args.is_empty() && is_closure { let underscores = vec!["_"; expected_args.len()].join(", "); err.span_suggestion_with_applicability( - found_span, + pipe_span, &format!( "consider changing the closure to take and ignore the expected argument{}", if expected_args.len() < 2 { diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 9eb11148a8bc..ed9162d23489 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -22,6 +22,8 @@ fn main() { //~^ ERROR closure is expected to take f(|| panic!()); //~^ ERROR closure is expected to take + f(move || panic!()); + //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); //~^ ERROR closure is expected to take From dbd9abd74d1ca8329f483c30ba04526d8c45a5ac Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 15 Nov 2018 22:17:49 +0800 Subject: [PATCH 11/75] update closure arg suggesstion ui test --- .../mismatched_types/closure-arg-count.stderr | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 057cf6efa1de..89977aadf88f 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -60,8 +60,26 @@ help: consider changing the closure to take and ignore the expected argument LL | f(|_| panic!()); | ^^^ +error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments + --> $DIR/closure-arg-count.rs:25:5 + | +LL | f(move || panic!()); + | ^ ------- takes 0 arguments + | | + | expected closure that takes 1 argument + | +note: required by `f` + --> $DIR/closure-arg-count.rs:13:1 + | +LL | fn f>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider changing the closure to take and ignore the expected argument + | +LL | f(move|_| panic!()); + | ^^^ + error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:26:53 + --> $DIR/closure-arg-count.rs:28:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); | ^^^ ------ takes 2 distinct arguments @@ -73,7 +91,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:28:53 + --> $DIR/closure-arg-count.rs:30:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); | ^^^ ------------- takes 2 distinct arguments @@ -85,7 +103,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:30:53 + --> $DIR/closure-arg-count.rs:32:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments @@ -93,7 +111,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:32:53 + --> $DIR/closure-arg-count.rs:34:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument @@ -102,7 +120,7 @@ LL | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:35:53 + --> $DIR/closure-arg-count.rs:37:53 | LL | let bar = |i, x, y| i; | --------- takes 3 distinct arguments @@ -110,7 +128,7 @@ LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:37:53 + --> $DIR/closure-arg-count.rs:39:53 | LL | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); | ^^^ expected function that takes a single 2-tuple as argument @@ -119,13 +137,13 @@ LL | fn qux(x: usize, y: usize) {} | -------------------------- takes 2 distinct arguments error[E0593]: function is expected to take 1 argument, but it takes 2 arguments - --> $DIR/closure-arg-count.rs:40:41 + --> $DIR/closure-arg-count.rs:42:41 | LL | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); | ^^^ expected function that takes 1 argument error[E0593]: function is expected to take 0 arguments, but it takes 1 argument - --> $DIR/closure-arg-count.rs:43:5 + --> $DIR/closure-arg-count.rs:45:5 | LL | call(Foo); | ^^^^ expected function that takes 0 arguments @@ -134,11 +152,11 @@ LL | struct Foo(u8); | --------------- takes 1 argument | note: required by `call` - --> $DIR/closure-arg-count.rs:50:1 + --> $DIR/closure-arg-count.rs:52:1 | LL | fn call(_: F) where F: FnOnce() -> R {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0593`. From 7cb068e52368e374f1f2c41e98f4b802d3869d14 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 13:08:58 +0100 Subject: [PATCH 12/75] add ui test --- src/test/ui/bare-function-self.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/bare-function-self.rs diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs new file mode 100644 index 000000000000..5cd33da923c3 --- /dev/null +++ b/src/test/ui/bare-function-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. + + +fn a(&self) { } +//~^ ERROR `self` argument in bare function + +fn main() { } \ No newline at end of file From 80c2101b2042ba9ba3e4c7b2351ec45867965338 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 13:54:09 +0100 Subject: [PATCH 13/75] change expected error message --- src/test/ui/bare-function-self.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs index 5cd33da923c3..01189ae321b5 100644 --- a/src/test/ui/bare-function-self.rs +++ b/src/test/ui/bare-function-self.rs @@ -10,6 +10,6 @@ fn a(&self) { } -//~^ ERROR `self` argument in bare function +//~^ ERROR unexpected `self` argument in bare function -fn main() { } \ No newline at end of file +fn main() { } From 218e35efa1500be4ebc1ee5d84a4e6971352c500 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 13:54:49 +0100 Subject: [PATCH 14/75] eat CloseDelim --- src/libsyntax/parse/parser.rs | 11 +++++++++-- src/test/ui/bare-function-self.stderr | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/bare-function-self.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d90ec4ea081b..dd1864ce1244 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5385,11 +5385,16 @@ fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { + self.expect(&token::OpenDelim(token::Paren))?; + + if let Ok(Some(_)) = self.parse_self_arg() { + return Err(self.fatal("unexpected `self` argument in bare function")) + } + let sp = self.span; let mut variadic = false; let args: Vec> = - self.parse_unspanned_seq( - &token::OpenDelim(token::Paren), + self.parse_seq_to_before_end( &token::CloseDelim(token::Paren), SeqSep::trailing_allowed(token::Comma), |p| { @@ -5436,6 +5441,8 @@ fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) } )?; + self.eat(&token::CloseDelim(token::Paren)); + let args: Vec<_> = args.into_iter().filter_map(|x| x).collect(); if variadic && args.is_empty() { diff --git a/src/test/ui/bare-function-self.stderr b/src/test/ui/bare-function-self.stderr new file mode 100644 index 000000000000..51db0ddd70d7 --- /dev/null +++ b/src/test/ui/bare-function-self.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in bare function + --> $DIR/bare-function-self.rs:12:11 + | +LL | fn a(&self) { } + | ^ + +error: aborting due to previous error + From 675319e5586817143fef60243d319395ae858ad1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 26 Oct 2018 00:55:12 +0200 Subject: [PATCH 15/75] lint if a private item has doctests --- src/librustc/lint/builtin.rs | 7 +++ src/librustdoc/core.rs | 4 +- .../passes/collect_intra_doc_links.rs | 45 ++------------ src/librustdoc/passes/mod.rs | 60 ++++++++++++++++++- .../passes/private_items_doc_tests.rs | 49 +++++++++++++++ src/test/rustdoc-ui/private-item-doc-test.rs | 20 +++++++ .../rustdoc-ui/private-item-doc-test.stderr | 16 +++++ 7 files changed, 158 insertions(+), 43 deletions(-) create mode 100644 src/librustdoc/passes/private_items_doc_tests.rs create mode 100644 src/test/rustdoc-ui/private-item-doc-test.rs create mode 100644 src/test/rustdoc-ui/private-item-doc-test.stderr diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 01d87bdbf633..22f2023eefbd 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -318,6 +318,12 @@ "warn about missing code example in an item's documentation" } +declare_lint! { + pub PRIVATE_DOC_TESTS, + Allow, + "warn about doc test in private item" +} + declare_lint! { pub WHERE_CLAUSES_OBJECT_SAFETY, Warn, @@ -415,6 +421,7 @@ fn get_lints(&self) -> LintArray { DUPLICATE_MACRO_EXPORTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, + PRIVATE_DOC_TESTS, WHERE_CLAUSES_OBJECT_SAFETY, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 0bd6f6bf8a2f..aac0f9f94e32 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -351,13 +351,15 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt let warnings_lint_name = lint::builtin::WARNINGS.name; let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; + let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; // In addition to those specific lints, we also need to whitelist those given through // command line, otherwise they'll get ignored and we don't want that. let mut whitelisted_lints = vec![warnings_lint_name.to_owned(), intra_link_resolution_failure_name.to_owned(), missing_docs.to_owned(), - missing_doc_example.to_owned()]; + missing_doc_example.to_owned(), + private_doc_tests.to_owned()]; whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 471ba6345e24..675e3e9be1e6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -24,9 +24,9 @@ use core::DocContext; use fold::DocFolder; -use html::markdown::{find_testable_code, markdown_links, ErrorCodes, LangString}; +use html::markdown::markdown_links; -use passes::Pass; +use passes::{look_for_tests, Pass}; pub const COLLECT_INTRA_DOC_LINKS: Pass = Pass::early("collect-intra-doc-links", collect_intra_doc_links, @@ -214,43 +214,6 @@ fn resolve(&self, } } -fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx>( - cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, - dox: &str, - item: &Item, -) { - if (item.is_mod() && cx.tcx.hir.as_local_node_id(item.def_id).is_none()) || - cx.as_local_node_id(item.def_id).is_none() { - // If non-local, no need to check anything. - return; - } - - struct Tests { - found_tests: usize, - } - - impl ::test::Tester for Tests { - fn add_test(&mut self, _: String, _: LangString, _: usize) { - self.found_tests += 1; - } - } - - let mut tests = Tests { - found_tests: 0, - }; - - if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() { - if tests.found_tests == 0 { - let mut diag = cx.tcx.struct_span_lint_node( - lint::builtin::MISSING_DOC_CODE_EXAMPLES, - NodeId::from_u32(0), - span_of_attrs(&item.attrs), - "Missing code example in this documentation"); - diag.emit(); - } - } -} - impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for LinkCollector<'a, 'tcx, 'rcx, 'cstore> { fn fold_item(&mut self, mut item: Item) -> Option { let item_node_id = if item.is_mod() { @@ -313,7 +276,7 @@ fn fold_item(&mut self, mut item: Item) -> Option { let cx = self.cx; let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); - look_for_tests(&cx, &dox, &item); + look_for_tests(&cx, &dox, &item, true); if !self.is_nightly_build { return None; @@ -488,7 +451,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option { None } -fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { +pub fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span { if attrs.doc_strings.is_empty() { return DUMMY_SP; } diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index d00eb3257d43..eee7278e4f0a 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -12,16 +12,22 @@ //! process. use rustc::hir::def_id::DefId; +use rustc::lint as lint; use rustc::middle::privacy::AccessLevels; use rustc::util::nodemap::DefIdSet; use std::mem; use std::fmt; +use syntax::ast::NodeId; use clean::{self, GetDefId, Item}; -use core::DocContext; +use core::{DocContext, DocAccessLevels}; use fold; use fold::StripItem; +use html::markdown::{find_testable_code, ErrorCodes, LangString}; + +use self::collect_intra_doc_links::span_of_attrs; + mod collapse_docs; pub use self::collapse_docs::COLLAPSE_DOCS; @@ -43,6 +49,9 @@ mod collect_intra_doc_links; pub use self::collect_intra_doc_links::COLLECT_INTRA_DOC_LINKS; +mod private_items_doc_tests; +pub use self::private_items_doc_tests::CHECK_PRIVATE_ITEMS_DOC_TESTS; + mod collect_trait_impls; pub use self::collect_trait_impls::COLLECT_TRAIT_IMPLS; @@ -128,6 +137,7 @@ pub fn late_fn(self) -> Option clean::Crate> { /// The full list of passes. pub const PASSES: &'static [Pass] = &[ + CHECK_PRIVATE_ITEMS_DOC_TESTS, STRIP_HIDDEN, UNINDENT_COMMENTS, COLLAPSE_DOCS, @@ -141,6 +151,7 @@ pub fn late_fn(self) -> Option clean::Crate> { /// The list of passes run by default. pub const DEFAULT_PASSES: &'static [&'static str] = &[ "collect-trait-impls", + "check-private-items-doc-tests", "strip-hidden", "strip-private", "collect-intra-doc-links", @@ -152,6 +163,7 @@ pub fn late_fn(self) -> Option clean::Crate> { /// The list of default passes run with `--document-private-items` is passed to rustdoc. pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[ "collect-trait-impls", + "check-private-items-doc-tests", "strip-priv-imports", "collect-intra-doc-links", "collapse-docs", @@ -348,3 +360,49 @@ fn fold_item(&mut self, i: Item) -> Option { } } } + +pub fn look_for_tests<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx>( + cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, + dox: &str, + item: &Item, + check_missing_code: bool, +) { + if cx.as_local_node_id(item.def_id).is_none() { + // If non-local, no need to check anything. + return; + } + + struct Tests { + found_tests: usize, + } + + impl ::test::Tester for Tests { + fn add_test(&mut self, _: String, _: LangString, _: usize) { + self.found_tests += 1; + } + } + + let mut tests = Tests { + found_tests: 0, + }; + + if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() { + if check_missing_code == true && tests.found_tests == 0 { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::MISSING_DOC_CODE_EXAMPLES, + NodeId::from_u32(0), + span_of_attrs(&item.attrs), + "Missing code example in this documentation"); + diag.emit(); + } else if check_missing_code == false && + tests.found_tests > 0 && + !cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) { + let mut diag = cx.tcx.struct_span_lint_node( + lint::builtin::PRIVATE_DOC_TESTS, + NodeId::from_u32(0), + span_of_attrs(&item.attrs), + "Documentation test in private item"); + diag.emit(); + } + } +} diff --git a/src/librustdoc/passes/private_items_doc_tests.rs b/src/librustdoc/passes/private_items_doc_tests.rs new file mode 100644 index 000000000000..7c5ce8894b10 --- /dev/null +++ b/src/librustdoc/passes/private_items_doc_tests.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. + +use clean::*; + +use core::DocContext; +use fold::DocFolder; + +use passes::{look_for_tests, Pass}; + +pub const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = + Pass::early("check-private-items-doc-tests", check_private_items_doc_tests, + "check private items doc tests"); + +struct PrivateItemDocTestLinter<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { + cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>, +} + +impl<'a, 'tcx, 'rcx, 'cstore> PrivateItemDocTestLinter<'a, 'tcx, 'rcx, 'cstore> { + fn new(cx: &'a DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self { + PrivateItemDocTestLinter { + cx, + } + } +} + +pub fn check_private_items_doc_tests(krate: Crate, cx: &DocContext) -> Crate { + let mut coll = PrivateItemDocTestLinter::new(cx); + + coll.fold_crate(krate) +} + +impl<'a, 'tcx, 'rcx, 'cstore> DocFolder for PrivateItemDocTestLinter<'a, 'tcx, 'rcx, 'cstore> { + fn fold_item(&mut self, item: Item) -> Option { + let cx = self.cx; + let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new); + + look_for_tests(&cx, &dox, &item, false); + + self.fold_item_recur(item) + } +} diff --git a/src/test/rustdoc-ui/private-item-doc-test.rs b/src/test/rustdoc-ui/private-item-doc-test.rs new file mode 100644 index 000000000000..5a13fe359f52 --- /dev/null +++ b/src/test/rustdoc-ui/private-item-doc-test.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. + +#![deny(private_doc_tests)] + +mod foo { + /// private doc test + /// + /// ``` + /// assert!(false); + /// ``` + fn bar() {} +} diff --git a/src/test/rustdoc-ui/private-item-doc-test.stderr b/src/test/rustdoc-ui/private-item-doc-test.stderr new file mode 100644 index 000000000000..b43add7ea505 --- /dev/null +++ b/src/test/rustdoc-ui/private-item-doc-test.stderr @@ -0,0 +1,16 @@ +error: Documentation test in private item + --> $DIR/private-item-doc-test.rs:14:5 + | +LL | / /// private doc test +LL | | /// +LL | | /// ``` +LL | | /// assert!(false); +LL | | /// ``` + | |___________^ + | +note: lint level defined here + --> $DIR/private-item-doc-test.rs:11:9 + | +LL | #![deny(private_doc_tests)] + | ^^^^^^^^^^^^^^^^^ + From 4c4aff9b3d1734a1dfb127ce8732728edc5b39ed Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 18:28:23 +0100 Subject: [PATCH 16/75] remove license --- src/test/ui/bare-function-self.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs index 01189ae321b5..0a430aee9737 100644 --- a/src/test/ui/bare-function-self.rs +++ b/src/test/ui/bare-function-self.rs @@ -1,14 +1,3 @@ -// 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 a(&self) { } //~^ ERROR unexpected `self` argument in bare function From 646d68f585e6cbabba5b7a67665af9a1f83ea6ea Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 18:43:06 +0100 Subject: [PATCH 17/75] add a note to the error message --- src/libsyntax/parse/parser.rs | 5 ++++- src/test/ui/bare-function-self.rs | 1 + src/test/ui/bare-function-self.stderr | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index dd1864ce1244..7ddb4099e0e9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5388,7 +5388,10 @@ fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) self.expect(&token::OpenDelim(token::Paren))?; if let Ok(Some(_)) = self.parse_self_arg() { - return Err(self.fatal("unexpected `self` argument in bare function")) + let mut err = self.struct_span_err(self.prev_span + , "unexpected `self` argument in bare function"); + err.span_label(self.prev_span, "invalid argument in bare function"); + return Err(err); } let sp = self.span; diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs index 0a430aee9737..f906b176d924 100644 --- a/src/test/ui/bare-function-self.rs +++ b/src/test/ui/bare-function-self.rs @@ -1,4 +1,5 @@ fn a(&self) { } //~^ ERROR unexpected `self` argument in bare function +//~| NOTE invalid argument in bare function fn main() { } diff --git a/src/test/ui/bare-function-self.stderr b/src/test/ui/bare-function-self.stderr index 51db0ddd70d7..002d71b1103e 100644 --- a/src/test/ui/bare-function-self.stderr +++ b/src/test/ui/bare-function-self.stderr @@ -1,8 +1,8 @@ error: unexpected `self` argument in bare function - --> $DIR/bare-function-self.rs:12:11 + --> $DIR/bare-function-self.rs:1:7 | LL | fn a(&self) { } - | ^ + | ^^^^ invalid argument in bare function error: aborting due to previous error From fe23ffbda01d2033c98ec6cec7f51cb08f625ec9 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 19:27:27 +0100 Subject: [PATCH 18/75] improve error when self is used as not the first argument --- src/libsyntax/parse/parser.rs | 17 +++++++++-------- src/test/ui/bare-function-self.rs | 5 ----- .../ui/invalid-self-argument/bare-fn-start.rs | 5 +++++ src/test/ui/invalid-self-argument/bare-fn.rs | 5 +++++ src/test/ui/invalid-self-argument/trait-fn.rs | 11 +++++++++++ 5 files changed, 30 insertions(+), 13 deletions(-) delete mode 100644 src/test/ui/bare-function-self.rs create mode 100644 src/test/ui/invalid-self-argument/bare-fn-start.rs create mode 100644 src/test/ui/invalid-self-argument/bare-fn.rs create mode 100644 src/test/ui/invalid-self-argument/trait-fn.rs diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7ddb4099e0e9..a4b01f485d38 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1824,6 +1824,14 @@ fn eat_incorrect_doc_comment(&mut self, applied_to: &str) { fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { maybe_whole!(self, NtArg, |x| x); + if let Ok(Some(_)) = self.parse_self_arg() { + let mut err = self.struct_span_err(self.prev_span, + "unexpected `self` argument in function"); + err.span_label(self.prev_span, + "`self` is only valid as the first argument of a trait function"); + return Err(err); + } + let (pat, ty) = if require_name || self.is_named_argument() { debug!("parse_arg_general parse_pat (require_name:{})", require_name); @@ -5386,14 +5394,7 @@ fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { self.expect(&token::OpenDelim(token::Paren))?; - - if let Ok(Some(_)) = self.parse_self_arg() { - let mut err = self.struct_span_err(self.prev_span - , "unexpected `self` argument in bare function"); - err.span_label(self.prev_span, "invalid argument in bare function"); - return Err(err); - } - + let sp = self.span; let mut variadic = false; let args: Vec> = diff --git a/src/test/ui/bare-function-self.rs b/src/test/ui/bare-function-self.rs deleted file mode 100644 index f906b176d924..000000000000 --- a/src/test/ui/bare-function-self.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn a(&self) { } -//~^ ERROR unexpected `self` argument in bare function -//~| NOTE invalid argument in bare function - -fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs new file mode 100644 index 000000000000..a84fe55502dc --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -0,0 +1,5 @@ +fn a(&self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of a trait function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs new file mode 100644 index 000000000000..27e56a537139 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.rs @@ -0,0 +1,5 @@ +fn b(foo: u32, &mut self) { } +//~^ ERROR unexpected `self` argument in function +//~| NOTE `self` is only valid as the first argument of a trait function + +fn main() { } diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs new file mode 100644 index 000000000000..e2107e4d8676 --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.rs @@ -0,0 +1,11 @@ +struct Foo {} + +impl Foo { + fn c(foo: u32, self) {} + //~^ ERROR unexpected `self` argument in function + //~| NOTE `self` is only valid as the first argument of a trait function + + fn good(&mut self, foo: u32) {} +} + +fn main() { } From 2be930bd03d3c9b9230ae3b9cc8fc30b83378900 Mon Sep 17 00:00:00 2001 From: Axary Date: Fri, 16 Nov 2018 19:35:13 +0100 Subject: [PATCH 19/75] fix tidy (remove whitespace) --- src/libsyntax/parse/parser.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn-start.stderr | 8 ++++++++ src/test/ui/invalid-self-argument/bare-fn.stderr | 8 ++++++++ src/test/ui/invalid-self-argument/trait-fn.stderr | 8 ++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/invalid-self-argument/bare-fn-start.stderr create mode 100644 src/test/ui/invalid-self-argument/bare-fn.stderr create mode 100644 src/test/ui/invalid-self-argument/trait-fn.stderr diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a4b01f485d38..18929af4718f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5394,7 +5394,7 @@ fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> { fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool) -> PResult<'a, (Vec , bool)> { self.expect(&token::OpenDelim(token::Paren))?; - + let sp = self.span; let mut variadic = false; let args: Vec> = diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr new file mode 100644 index 000000000000..d0eca1a9e5ce --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn-start.rs:1:7 + | +LL | fn a(&self) { } + | ^^^^ `self` is only valid as the first argument of a trait function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr new file mode 100644 index 000000000000..bd6c598c88a0 --- /dev/null +++ b/src/test/ui/invalid-self-argument/bare-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/bare-fn.rs:1:21 + | +LL | fn b(foo: u32, &mut self) { } + | ^^^^ `self` is only valid as the first argument of a trait function + +error: aborting due to previous error + diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr new file mode 100644 index 000000000000..d056e53b95c7 --- /dev/null +++ b/src/test/ui/invalid-self-argument/trait-fn.stderr @@ -0,0 +1,8 @@ +error: unexpected `self` argument in function + --> $DIR/trait-fn.rs:4:20 + | +LL | fn c(foo: u32, self) {} + | ^^^^ `self` is only valid as the first argument of a trait function + +error: aborting due to previous error + From 5bfdcc1ab1c94baa4865093b6c36fb15416e6a4d Mon Sep 17 00:00:00 2001 From: Axary Date: Sat, 17 Nov 2018 09:36:56 +0100 Subject: [PATCH 20/75] remove stray file with UI testing output --- src/test/ui/bare-function-self.stderr | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/test/ui/bare-function-self.stderr diff --git a/src/test/ui/bare-function-self.stderr b/src/test/ui/bare-function-self.stderr deleted file mode 100644 index 002d71b1103e..000000000000 --- a/src/test/ui/bare-function-self.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: unexpected `self` argument in bare function - --> $DIR/bare-function-self.rs:1:7 - | -LL | fn a(&self) { } - | ^^^^ invalid argument in bare function - -error: aborting due to previous error - From d93e5b04f4817718480d17eafa0ee5e7bbe1f019 Mon Sep 17 00:00:00 2001 From: csmoe Date: Sat, 17 Nov 2018 17:57:17 +0800 Subject: [PATCH 21/75] reserve whitespaces between prefix and pipe --- src/librustc/traits/error_reporting.rs | 2 +- src/test/ui/mismatched_types/closure-arg-count.rs | 2 +- src/test/ui/mismatched_types/closure-arg-count.stderr | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d08a4b47b31b..48b2b25d6adf 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1097,7 +1097,7 @@ pub fn report_arg_count_mismatch( // // move |_| { ... } // ^^^^^-- prefix - let prefix_span = self.tcx.sess.source_map().span_until_char(found_span, '|'); + let prefix_span = self.tcx.sess.source_map().span_until_non_whitespace(found_span); // move |_| { ... } // ^^^-- pipe_span let pipe_span = if let Some(span) = found_span.trim_start(prefix_span) { diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index ed9162d23489..2dcc7a25c840 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -22,7 +22,7 @@ fn main() { //~^ ERROR closure is expected to take f(|| panic!()); //~^ ERROR closure is expected to take - f(move || panic!()); + f( move || panic!()); //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 89977aadf88f..eeadf07262c3 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -63,8 +63,8 @@ LL | f(|_| panic!()); error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments --> $DIR/closure-arg-count.rs:25:5 | -LL | f(move || panic!()); - | ^ ------- takes 0 arguments +LL | f( move || panic!()); + | ^ ---------- takes 0 arguments | | | expected closure that takes 1 argument | @@ -75,8 +75,8 @@ LL | fn f>(_: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the closure to take and ignore the expected argument | -LL | f(move|_| panic!()); - | ^^^ +LL | f( move |_| panic!()); + | ^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments --> $DIR/closure-arg-count.rs:28:53 From 7c9bcc52668a8865f5ed71f1bc3dcead1367e148 Mon Sep 17 00:00:00 2001 From: 0xrgb <0xrgb@users.noreply.github.com> Date: Mon, 19 Nov 2018 15:59:21 +0900 Subject: [PATCH 22/75] Update any.rs documentation using keyword dyn --- src/libcore/any.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 6b26093439e4..c2113dfd2a06 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -39,7 +39,7 @@ //! //! // Logger function for any type that implements Debug. //! fn log(value: &T) { -//! let value_any = value as &Any; +//! let value_any = value as &dyn Any; //! //! // try to convert our value to a String. If successful, we want to //! // output the String's length as well as its value. If not, it's a @@ -95,7 +95,7 @@ pub trait Any: 'static { /// /// use std::any::{Any, TypeId}; /// - /// fn is_string(s: &Any) -> bool { + /// fn is_string(s: &dyn Any) -> bool { /// TypeId::of::() == s.get_type_id() /// } /// @@ -151,7 +151,7 @@ impl dyn Any { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &Any) { + /// fn is_string(s: &dyn Any) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -185,7 +185,7 @@ pub fn is(&self) -> bool { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &Any) { + /// fn print_if_string(s: &dyn Any) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -218,7 +218,7 @@ pub fn downcast_ref(&self) -> Option<&T> { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut Any) { + /// fn modify_if_u32(s: &mut dyn Any) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } @@ -256,7 +256,7 @@ impl dyn Any+Send { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &(Any + Send)) { + /// fn is_string(s: &(dyn Any + Send)) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -282,7 +282,7 @@ pub fn is(&self) -> bool { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &(Any + Send)) { + /// fn print_if_string(s: &(dyn Any + Send)) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -308,7 +308,7 @@ pub fn downcast_ref(&self) -> Option<&T> { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut (Any + Send)) { + /// fn modify_if_u32(s: &mut (dyn Any + Send)) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } @@ -340,7 +340,7 @@ impl dyn Any+Send+Sync { /// ``` /// use std::any::Any; /// - /// fn is_string(s: &(Any + Send + Sync)) { + /// fn is_string(s: &(dyn Any + Send + Sync)) { /// if s.is::() { /// println!("It's a string!"); /// } else { @@ -366,7 +366,7 @@ pub fn is(&self) -> bool { /// ``` /// use std::any::Any; /// - /// fn print_if_string(s: &(Any + Send + Sync)) { + /// fn print_if_string(s: &(dyn Any + Send + Sync)) { /// if let Some(string) = s.downcast_ref::() { /// println!("It's a string({}): '{}'", string.len(), string); /// } else { @@ -392,7 +392,7 @@ pub fn downcast_ref(&self) -> Option<&T> { /// ``` /// use std::any::Any; /// - /// fn modify_if_u32(s: &mut (Any + Send + Sync)) { + /// fn modify_if_u32(s: &mut (dyn Any + Send + Sync)) { /// if let Some(num) = s.downcast_mut::() { /// *num = 42; /// } From 8ee9711a6c00a0994f7fc69586273c86ab45e396 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 19 Nov 2018 10:40:09 +0100 Subject: [PATCH 23/75] Replace the ICEing on const fn loops with an error --- src/librustc_mir/transform/qualify_min_const_fn.rs | 8 +++----- src/test/ui/consts/min_const_fn/loop_ice.rs | 5 +++++ src/test/ui/consts/min_const_fn/loop_ice.stderr | 8 ++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/consts/min_const_fn/loop_ice.rs create mode 100644 src/test/ui/consts/min_const_fn/loop_ice.stderr diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index ed13063cfdf1..958e5efe3ec7 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -365,10 +365,8 @@ fn check_terminator( cleanup: _, } => check_operand(tcx, mir, cond, span), - | TerminatorKind::FalseUnwind { .. } => span_bug!( - terminator.source_info.span, - "min_const_fn encountered `{:#?}`", - terminator - ), + TerminatorKind::FalseUnwind { .. } => { + Err((span, "loops are not allowed in const fn".into())) + }, } } diff --git a/src/test/ui/consts/min_const_fn/loop_ice.rs b/src/test/ui/consts/min_const_fn/loop_ice.rs new file mode 100644 index 000000000000..4278a8e2d003 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/loop_ice.rs @@ -0,0 +1,5 @@ +const fn foo() { + loop {} //~ ERROR loops are not allowed in const fn +} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/loop_ice.stderr b/src/test/ui/consts/min_const_fn/loop_ice.stderr new file mode 100644 index 000000000000..1424cea65afd --- /dev/null +++ b/src/test/ui/consts/min_const_fn/loop_ice.stderr @@ -0,0 +1,8 @@ +error: loops are not allowed in const fn + --> $DIR/loop_ice.rs:2:5 + | +LL | loop {} //~ ERROR loops are not allowed in const fn + | ^^^^^^^ + +error: aborting due to previous error + From b55717f9b0023f58b7ca2fab77a0b33206076ac4 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 3 Nov 2018 19:23:05 +0000 Subject: [PATCH 24/75] Use general uninhabitedness checking --- src/librustc_lint/unused.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 7eab7d210029..6383ca69fe5c 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -60,19 +60,15 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { } let t = cx.tables.expr_ty(&expr); - // FIXME(varkor): replace with `t.is_unit() || t.conservative_is_uninhabited()`. - let type_permits_no_use = match t.sty { - ty::Tuple(ref tys) if tys.is_empty() => true, - ty::Never => true, - ty::Adt(def, _) => { - if def.variants.is_empty() { - true - } else { - check_must_use(cx, def.did, s.span, "") - } + let type_permits_lack_of_use = if t.is_unit() + || cx.tcx.is_ty_uninhabited_from(cx.tcx.hir.get_module_parent(expr.id), t) { + true + } else { + match t.sty { + ty::Adt(def, _) => check_must_use(cx, def.did, s.span, ""), + _ => false, } - _ => false, - }; + } let mut fn_warned = false; let mut op_warned = false; @@ -99,7 +95,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { if let Some(def) = maybe_def { let def_id = def.def_id(); fn_warned = check_must_use(cx, def_id, s.span, "return value of "); - } else if type_permits_no_use { + } else if type_permits_lack_of_use { // We don't warn about unused unit or uninhabited types. // (See https://github.com/rust-lang/rust/issues/43806 for details.) return; @@ -148,7 +144,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { op_warned = true; } - if !(type_permits_no_use || fn_warned || op_warned) { + if !(type_permits_lack_of_use || fn_warned || op_warned) { cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } From cb5520bc4865473971281ddb3e33a29a256109c8 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 3 Nov 2018 20:08:30 +0000 Subject: [PATCH 25/75] Recognise #[must_use] on traits, affecting impl Trait --- src/librustc_lint/unused.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 6383ca69fe5c..f8030fa6ec7a 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -66,9 +66,22 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { } else { match t.sty { ty::Adt(def, _) => check_must_use(cx, def.did, s.span, ""), + ty::Opaque(def, _) => { + let mut must_use = false; + for (predicate, _) in cx.tcx.predicates_of(def).predicates { + if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { + let trait_ref = poly_trait_predicate.skip_binder().trait_ref; + if check_must_use(cx, trait_ref.def_id, s.span, "implementer of ") { + must_use = true; + break; + } + } + } + must_use + } _ => false, } - } + }; let mut fn_warned = false; let mut op_warned = false; From 122886842e74467e24935793f79d7443eb509e35 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 3 Nov 2018 20:08:38 +0000 Subject: [PATCH 26/75] Test for #[must_use] on traits --- src/test/ui/lint/must_use-trait.rs | 22 ++++++++++++++++++++++ src/test/ui/lint/must_use-trait.stderr | 14 ++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/test/ui/lint/must_use-trait.rs create mode 100644 src/test/ui/lint/must_use-trait.stderr diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/must_use-trait.rs new file mode 100644 index 000000000000..23df4fa6132d --- /dev/null +++ b/src/test/ui/lint/must_use-trait.rs @@ -0,0 +1,22 @@ +#![deny(unused_must_use)] + +#[must_use] +trait Critical {} + +trait NotSoCritical {} + +trait DecidedlyUnimportant {} + +struct Anon; + +impl Critical for Anon {} +impl NotSoCritical for Anon {} +impl DecidedlyUnimportant for Anon {} + +fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant { + Anon {} +} + +fn main() { + get_critical(); //~ ERROR unused implementer of `Critical` that must be used +} diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/must_use-trait.stderr new file mode 100644 index 000000000000..94f5f4f40d2d --- /dev/null +++ b/src/test/ui/lint/must_use-trait.stderr @@ -0,0 +1,14 @@ +error: unused implementer of `Critical` that must be used + --> $DIR/must_use-trait.rs:21:5 + | +LL | get_critical(); //~ ERROR unused implementer of `Critical` that must be used + | ^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/must_use-trait.rs:1:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 9178eb41d3e1ec2d96ff6bdbb19a0bccb7a45aff Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 3 Nov 2018 20:24:24 +0000 Subject: [PATCH 27/75] Handle trait objects --- src/librustc_lint/unused.rs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index f8030fa6ec7a..3bb35b8e4e10 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -65,13 +65,25 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { true } else { match t.sty { - ty::Adt(def, _) => check_must_use(cx, def.did, s.span, ""), + ty::Adt(def, _) => check_must_use(cx, def.did, s.span, "", ""), ty::Opaque(def, _) => { let mut must_use = false; for (predicate, _) in cx.tcx.predicates_of(def).predicates { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; - if check_must_use(cx, trait_ref.def_id, s.span, "implementer of ") { + if check_must_use(cx, trait_ref.def_id, s.span, "implementer of ", "") { + must_use = true; + break; + } + } + } + must_use + } + ty::Dynamic(binder, _) => { + let mut must_use = false; + for predicate in binder.skip_binder().iter() { + if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { + if check_must_use(cx, trait_ref.def_id, s.span, "", " trait object") { must_use = true; break; } @@ -107,7 +119,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { }; if let Some(def) = maybe_def { let def_id = def.def_id(); - fn_warned = check_must_use(cx, def_id, s.span, "return value of "); + fn_warned = check_must_use(cx, def_id, s.span, "return value of ", ""); } else if type_permits_lack_of_use { // We don't warn about unused unit or uninhabited types. // (See https://github.com/rust-lang/rust/issues/43806 for details.) @@ -161,11 +173,17 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } - fn check_must_use(cx: &LateContext, def_id: DefId, sp: Span, describe_path: &str) -> bool { + fn check_must_use( + cx: &LateContext, + def_id: DefId, + sp: Span, + descr_pre_path: &str, + descr_post_path: &str, + ) -> bool { for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name("must_use") { - let msg = format!("unused {}`{}` that must be used", - describe_path, cx.tcx.item_path_str(def_id)); + let msg = format!("unused {}`{}`{} that must be used", + descr_pre_path, descr_post_path, cx.tcx.item_path_str(def_id)); let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg); // check for #[must_use = "..."] if let Some(note) = attr.value_str() { From 0ab70fab1970ea665c0969f04adc66195703a7bc Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 3 Nov 2018 21:27:35 +0000 Subject: [PATCH 28/75] Fix typo in #[must_use] message --- src/librustc_lint/unused.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 3bb35b8e4e10..906579a1ae05 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -183,7 +183,7 @@ fn check_must_use( for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name("must_use") { let msg = format!("unused {}`{}`{} that must be used", - descr_pre_path, descr_post_path, cx.tcx.item_path_str(def_id)); + descr_pre_path, cx.tcx.item_path_str(def_id), descr_post_path); let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg); // check for #[must_use = "..."] if let Some(note) = attr.value_str() { From a44e446551a7251a06c23caa97aebcfbb98c79b2 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 19 Nov 2018 15:04:28 +0530 Subject: [PATCH 29/75] Add `override_export_symbols` option to Rust target specification --- src/librustc_codegen_ssa/back/linker.rs | 4 ++++ src/librustc_target/spec/mod.rs | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index da9cfbb94d1c..ec5ca5801049 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -1050,6 +1050,10 @@ fn cross_lang_lto(&mut self) { } fn exported_symbols(tcx: TyCtxt, crate_type: CrateType) -> Vec { + if let Some(ref exports) = tcx.sess.target.target.options.override_export_symbols { + return exports.clone() + } + let mut symbols = Vec::new(); let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 16dc2a91030f..57bbf6b02608 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -683,6 +683,10 @@ pub struct TargetOptions { /// target features. This is `true` by default, and `false` for targets like /// wasm32 where the whole program either has simd or not. pub simd_types_indirect: bool, + + /// If set, have the linker export exactly these symbols, instead of using + /// the usual logic to figure this out from the crate itself. + pub override_export_symbols: Option> } impl Default for TargetOptions { @@ -763,6 +767,7 @@ fn default() -> TargetOptions { emit_debug_gdb_scripts: true, requires_uwtable: false, simd_types_indirect: true, + override_export_symbols: None, } } } @@ -898,6 +903,14 @@ macro_rules! key { ) ); } ); + ($key_name:ident, opt_list) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).map(|o| o.as_array() + .map(|v| base.options.$key_name = Some(v.iter() + .map(|a| a.as_string().unwrap().to_string()).collect()) + ) + ); + } ); ($key_name:ident, optional) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(o) = obj.find(&name[..]) { @@ -1044,6 +1057,7 @@ macro_rules! key { key!(emit_debug_gdb_scripts, bool); key!(requires_uwtable, bool); key!(simd_types_indirect, bool); + key!(override_export_symbols, opt_list); if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { for name in array.iter().filter_map(|abi| abi.as_string()) { @@ -1253,6 +1267,7 @@ macro_rules! target_option_val { target_option_val!(emit_debug_gdb_scripts); target_option_val!(requires_uwtable); target_option_val!(simd_types_indirect); + target_option_val!(override_export_symbols); if default.abi_blacklist != self.options.abi_blacklist { d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() From 737dec0ec16b2606380ed73166b82e44be080ab5 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 19 Nov 2018 18:54:52 +0000 Subject: [PATCH 30/75] Fix change to predicates --- src/librustc_lint/unused.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 906579a1ae05..fab618d9c8ec 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -68,7 +68,7 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) { ty::Adt(def, _) => check_must_use(cx, def.did, s.span, "", ""), ty::Opaque(def, _) => { let mut must_use = false; - for (predicate, _) in cx.tcx.predicates_of(def).predicates { + for (predicate, _) in &cx.tcx.predicates_of(def).predicates { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; if check_must_use(cx, trait_ref.def_id, s.span, "implementer of ", "") { From b8da7190243faca8dc0a5173496034b772ff4449 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 19 Nov 2018 13:29:35 -0800 Subject: [PATCH 31/75] Fix error message for `-C panic=xxx`. --- src/librustc/session/config.rs | 2 +- src/test/ui/panic-runtime/bad-panic-flag1.rs | 2 +- src/test/ui/panic-runtime/bad-panic-flag1.stderr | 2 +- src/test/ui/panic-runtime/bad-panic-flag2.rs | 2 +- src/test/ui/panic-runtime/bad-panic-flag2.stderr | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index ee6d970750ad..c620e092f36c 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -802,7 +802,7 @@ mod $mod_desc { pub const parse_opt_uint: Option<&'static str> = Some("a number"); pub const parse_panic_strategy: Option<&'static str> = - Some("either `panic` or `abort`"); + Some("either `unwind` or `abort`"); pub const parse_relro_level: Option<&'static str> = Some("one of: `full`, `partial`, or `off`"); pub const parse_sanitizer: Option<&'static str> = diff --git a/src/test/ui/panic-runtime/bad-panic-flag1.rs b/src/test/ui/panic-runtime/bad-panic-flag1.rs index f067b6b8349b..4e553c4df2fd 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag1.rs +++ b/src/test/ui/panic-runtime/bad-panic-flag1.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags:-C panic=foo -// error-pattern:either `panic` or `abort` was expected +// error-pattern:either `unwind` or `abort` was expected fn main() {} diff --git a/src/test/ui/panic-runtime/bad-panic-flag1.stderr b/src/test/ui/panic-runtime/bad-panic-flag1.stderr index 3a65419c98fb..013373c6f931 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag1.stderr +++ b/src/test/ui/panic-runtime/bad-panic-flag1.stderr @@ -1,2 +1,2 @@ -error: incorrect value `foo` for codegen option `panic` - either `panic` or `abort` was expected +error: incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected diff --git a/src/test/ui/panic-runtime/bad-panic-flag2.rs b/src/test/ui/panic-runtime/bad-panic-flag2.rs index 0ecf65f080fa..f560e7f4eb2d 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag2.rs +++ b/src/test/ui/panic-runtime/bad-panic-flag2.rs @@ -9,6 +9,6 @@ // except according to those terms. // compile-flags:-C panic -// error-pattern:requires either `panic` or `abort` +// error-pattern:requires either `unwind` or `abort` fn main() {} diff --git a/src/test/ui/panic-runtime/bad-panic-flag2.stderr b/src/test/ui/panic-runtime/bad-panic-flag2.stderr index 8d919e55c906..6ab94ea704d3 100644 --- a/src/test/ui/panic-runtime/bad-panic-flag2.stderr +++ b/src/test/ui/panic-runtime/bad-panic-flag2.stderr @@ -1,2 +1,2 @@ -error: codegen option `panic` requires either `panic` or `abort` (C panic=) +error: codegen option `panic` requires either `unwind` or `abort` (C panic=) From b50c1b243e09284b7bbfb81c1819d358d024168d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Nov 2018 14:17:40 +0100 Subject: [PATCH 32/75] Make const_eval_raw query return just an AllocId --- src/librustc/ich/impls_ty.rs | 4 ++ src/librustc/mir/interpret/error.rs | 3 +- src/librustc/mir/interpret/mod.rs | 4 +- src/librustc/mir/interpret/value.rs | 15 ++++-- src/librustc/ty/query/mod.rs | 4 +- src/librustc_mir/const_eval.rs | 46 ++++++++++--------- src/librustc_mir/interpret/memory.rs | 15 +++--- src/librustc_mir/interpret/operand.rs | 3 +- src/librustc_mir/interpret/place.rs | 19 ++++++-- src/librustc_mir/transform/const_prop.rs | 2 +- src/test/ui/consts/const-err4.rs | 2 +- src/test/ui/consts/const-err4.stderr | 6 ++- .../const-pointer-values-in-various-types.rs | 4 +- ...nst-pointer-values-in-various-types.stderr | 12 +++-- .../const-eval/union-const-eval-field.rs | 3 +- .../const-eval/union-const-eval-field.stderr | 9 ++-- src/test/ui/consts/const-eval/union-ice.rs | 2 +- .../ui/consts/const-eval/union-ice.stderr | 8 ++-- 18 files changed, 97 insertions(+), 64 deletions(-) diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 64685446e8fe..679107160a6f 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -317,6 +317,10 @@ impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValu ByRef(id, alloc, offset), } ); +impl_stable_hash_for!(struct ::mir::interpret::RawConst<'tcx> { + alloc_id, + ty, +}); impl_stable_hash_for! { impl for struct mir::interpret::Pointer { diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index f1c95e0f0002..f1ac4b210583 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -16,7 +16,7 @@ use ty::layout::{Size, Align, LayoutError}; use rustc_target::spec::abi::Abi; -use super::{Pointer, InboundsCheck, ScalarMaybeUndef}; +use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef}; use backtrace::Backtrace; @@ -46,6 +46,7 @@ pub fn assert_reported(self) { } } +pub type ConstEvalRawResult<'tcx> = Result, ErrorHandled>; pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>; #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index ec25431bd1ff..9369b6e56f1d 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -22,10 +22,10 @@ macro_rules! err { pub use self::error::{ EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalResult, ErrorHandled, + FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, }; -pub use self::value::{Scalar, ConstValue, ScalarMaybeUndef}; +pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue}; pub use self::allocation::{ InboundsCheck, Allocation, AllocationExtra, diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 47c42c9431a2..4bcba9d54674 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -10,12 +10,20 @@ use std::fmt; -use ty::layout::{HasDataLayout, Size}; -use ty::subst::Substs; -use hir::def_id::DefId; +use crate::ty::{Ty, subst::Substs, layout::{HasDataLayout, Size}}; +use crate::hir::def_id::DefId; use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate}; +/// Represents the result of a raw const operation, pre-validation. +#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)] +pub struct RawConst<'tcx> { + // the value lives here, at offset 0, and that allocation definitely is a `AllocType::Memory` + // (so you can use `AllocMap::unwrap_memory`). + pub alloc_id: AllocId, + pub ty: Ty<'tcx>, +} + /// Represents a constant value in Rust. Scalar and ScalarPair are optimizations which /// matches the LocalValue optimizations for easy conversions between Value and ConstValue. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)] @@ -23,6 +31,7 @@ pub enum ConstValue<'tcx> { /// Never returned from the `const_eval` query, but the HIR contains these frequently in order /// to allow HIR creation to happen for everything before needing to be able to run constant /// evaluation + /// FIXME: The query should then return a type that does not even have this variant. Unevaluated(DefId, &'tcx Substs<'tcx>), /// Used only for types with layout::abi::Scalar ABI and ZSTs diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 89e7f4db502b..22bd1e26ba3e 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -27,7 +27,7 @@ use middle::lib_features::LibFeatures; use middle::lang_items::{LanguageItems, LangItem}; use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; -use mir::interpret::ConstEvalResult; +use mir::interpret::{ConstEvalRawResult, ConstEvalResult}; use mir::mono::CodegenUnit; use mir; use mir::interpret::GlobalId; @@ -309,7 +309,7 @@ /// validation. Please add a comment to every use site explaining why using `const_eval` /// isn't sufficient [] fn const_eval_raw: const_eval_raw_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) - -> ConstEvalResult<'tcx>, + -> ConstEvalRawResult<'tcx>, /// Results of evaluating const items or constants embedded in /// other items (such as enum variant explicit discriminants). diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 51046399ec20..4e727de53582 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -31,8 +31,8 @@ use syntax::ast::Mutability; use syntax::source_map::{Span, DUMMY_SP}; -use interpret::{self, - PlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, ConstValue, Pointer, +use crate::interpret::{self, + PlaceTy, MPlaceTy, MemPlace, OpTy, Operand, Immediate, Scalar, RawConst, ConstValue, Pointer, EvalResult, EvalError, EvalErrorKind, GlobalId, EvalContext, StackPopCleanup, Allocation, AllocId, MemoryKind, snapshot, RefTracking, @@ -94,11 +94,13 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( cid: GlobalId<'tcx>, mir: &'mir mir::Mir<'tcx>, param_env: ty::ParamEnv<'tcx>, -) -> EvalResult<'tcx, OpTy<'tcx>> { +) -> EvalResult<'tcx, MPlaceTy<'tcx>> { let mut ecx = mk_borrowck_eval_cx(tcx, cid.instance, mir, DUMMY_SP).unwrap(); eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env) } +// FIXME: This thing is a bad hack. We should get rid of it. Ideally constants are always +// in an allocation. pub fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, op: OpTy<'tcx>, @@ -150,7 +152,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>( cid: GlobalId<'tcx>, mir: Option<&'mir mir::Mir<'tcx>>, param_env: ty::ParamEnv<'tcx>, -) -> (EvalResult<'tcx, OpTy<'tcx>>, CompileTimeEvalContext<'a, 'mir, 'tcx>) { +) -> (EvalResult<'tcx, MPlaceTy<'tcx>>, CompileTimeEvalContext<'a, 'mir, 'tcx>) { // we start out with the best span we have // and try improving it down the road when more information is available let span = tcx.def_span(cid.instance.def_id()); @@ -166,7 +168,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( cid: GlobalId<'tcx>, mir: Option<&'mir mir::Mir<'tcx>>, param_env: ty::ParamEnv<'tcx>, -) -> EvalResult<'tcx, OpTy<'tcx>> { +) -> EvalResult<'tcx, MPlaceTy<'tcx>> { debug!("eval_body_using_ecx: {:?}, {:?}", cid, param_env); let tcx = ecx.tcx.tcx; let mut mir = match mir { @@ -206,7 +208,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.memory.intern_static(ret.ptr.to_ptr()?.alloc_id, mutability)?; debug!("eval_body_using_ecx done: {:?}", *ret); - Ok(ret.into()) + Ok(ret) } impl<'tcx> Into> for ConstEvalError { @@ -534,15 +536,17 @@ pub fn error_to_const_error<'a, 'mir, 'tcx>( ConstEvalErr { error: error.kind, stacktrace, span: ecx.tcx.span } } -fn validate_const<'a, 'tcx>( +fn validate_and_turn_into_const<'a, 'tcx>( tcx: ty::TyCtxt<'a, 'tcx, 'tcx>, - constant: &'tcx ty::Const<'tcx>, + constant: RawConst<'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { let cid = key.value; let ecx = mk_eval_cx(tcx, cid.instance, key.param_env).unwrap(); let val = (|| { - let op = ecx.const_to_op(constant)?; + let op = ecx.raw_const_to_mplace(constant)?.into(); + // FIXME: Once the visitor infrastructure landed, change validation to + // work directly on `MPlaceTy`. let mut ref_tracking = RefTracking::new(op); while let Some((op, path)) = ref_tracking.todo.pop() { ecx.validate_operand( @@ -552,7 +556,10 @@ fn validate_const<'a, 'tcx>( /* const_mode */ true, )?; } - Ok(constant) + // Now that we validated, turn this into a proper constant + let def_id = cid.instance.def.def_id(); + let normalize = tcx.is_static(def_id).is_none() && cid.promoted.is_none(); + op_to_const(&ecx, op, normalize) })(); val.map_err(|error| { @@ -591,14 +598,14 @@ pub fn const_eval_provider<'a, 'tcx>( } } tcx.const_eval_raw(key).and_then(|val| { - validate_const(tcx, val, key) + validate_and_turn_into_const(tcx, val, key) }) } pub fn const_eval_raw_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>, -) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { +) -> ::rustc::mir::interpret::ConstEvalRawResult<'tcx> { // Because the constant is computed twice (once per value of `Reveal`), we are at risk of // reporting the same error twice here. To resolve this, we check whether we can evaluate the // constant in the more restrictive `Reveal::UserFacing`, which most likely already was @@ -648,16 +655,11 @@ pub fn const_eval_raw_provider<'a, 'tcx>( }; let (res, ecx) = eval_body_and_ecx(tcx, cid, None, key.param_env); - res.and_then(|op| { - let normalize = tcx.is_static(def_id).is_none() && cid.promoted.is_none(); - if !normalize { - // Sanity check: These must always be a MemPlace - match op.op { - Operand::Indirect(_) => { /* all is good */ }, - Operand::Immediate(_) => bug!("const eval gave us an Immediate"), - } - } - op_to_const(&ecx, op, normalize) + res.and_then(|place| { + Ok(RawConst { + alloc_id: place.to_ptr().expect("we allocated this ptr!").alloc_id, + ty: place.layout.ty + }) }).map_err(|error| { let err = error_to_const_error(&ecx, error); // errors in statics are always emitted as fatal errors diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index c5a242f334c9..7dd42c666496 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -28,7 +28,7 @@ use syntax::ast::Mutability; use super::{ - Pointer, AllocId, Allocation, ConstValue, GlobalId, AllocationExtra, InboundsCheck, + Pointer, AllocId, Allocation, GlobalId, AllocationExtra, InboundsCheck, EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic, Machine, AllocMap, MayLeak, ScalarMaybeUndef, ErrorHandled, }; @@ -374,14 +374,11 @@ fn get_static_alloc( ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(), ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(), } - }).map(|const_val| { - if let ConstValue::ByRef(_, allocation, _) = const_val.val { - // We got tcx memory. Let the machine figure out whether and how to - // turn that into memory with the right pointer tag. - M::adjust_static_allocation(allocation) - } else { - bug!("Matching on non-ByRef static") - } + }).map(|raw_const| { + let allocation = tcx.alloc_map.lock().unwrap_memory(raw_const.alloc_id); + // We got tcx memory. Let the machine figure out whether and how to + // turn that into memory with the right pointer tag. + M::adjust_static_allocation(allocation) }) } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index b7910ad3bce9..16f1e487f59a 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -536,7 +536,8 @@ pub(super) fn eval_operands( } // Also used e.g. when miri runs into a constant. - pub(super) fn const_value_to_op( + // FIXME: Can we avoid converting with ConstValue and Const? We should be using RawConst. + fn const_value_to_op( &self, val: ConstValue<'tcx>, ) -> EvalResult<'tcx, Operand> { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index fa76eeb2fedd..104d66f7bde2 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -20,12 +20,10 @@ use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; -use rustc::mir::interpret::{ - GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic -}; use super::{ + GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic, EvalContext, Machine, AllocMap, AllocationExtra, - Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind + RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] @@ -981,6 +979,19 @@ pub fn place_to_op( Ok(OpTy { op, layout: place.layout }) } + pub fn raw_const_to_mplace( + &self, + raw: RawConst<'tcx>, + ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { + // This must be an allocation in `tcx` + assert!(self.tcx.alloc_map.lock().get(raw.alloc_id).is_some()); + let layout = self.layout_of(raw.ty)?; + Ok(MPlaceTy::from_aligned_ptr( + Pointer::new(raw.alloc_id, Size::ZERO).with_default_tag(), + layout, + )) + } + /// Turn a place with a `dyn Trait` type into a place with the actual dynamic type. /// Also return some more information so drop doesn't have to run the same code twice. pub(super) fn unpack_dyn_trait(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 885d70dc4304..6b8233c941e8 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -309,7 +309,7 @@ fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option eval_promoted(this.tcx, cid, this.mir, this.param_env) })?; trace!("evaluated promoted {:?} to {:?}", promoted, res); - Some((res, source_info.span)) + Some((res.into(), source_info.span)) }, _ => None, } diff --git a/src/test/ui/consts/const-err4.rs b/src/test/ui/consts/const-err4.rs index 0bbc254453cf..129177e9a1ae 100644 --- a/src/test/ui/consts/const-err4.rs +++ b/src/test/ui/consts/const-err4.rs @@ -16,7 +16,7 @@ union Foo { enum Bar { Boo = [unsafe { Foo { b: () }.a }; 4][3], - //~^ ERROR evaluation of constant value failed + //~^ ERROR it is undefined behavior to use this value } fn main() { diff --git a/src/test/ui/consts/const-err4.stderr b/src/test/ui/consts/const-err4.stderr index bb50f38062ee..2f58712be28f 100644 --- a/src/test/ui/consts/const-err4.stderr +++ b/src/test/ui/consts/const-err4.stderr @@ -1,8 +1,10 @@ -error[E0080]: evaluation of constant value failed +error[E0080]: it is undefined behavior to use this value --> $DIR/const-err4.rs:18:11 | LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs index 23e1ab013ef3..cc5ddb440164 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs @@ -37,7 +37,7 @@ fn main() { //~^ ERROR it is undefined behavior to use this value const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; - //~^ ERROR any use of this value will cause an error + //~^ ERROR it is undefined behavior to use this value const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; //~^ ERROR any use of this value will cause an error @@ -52,7 +52,7 @@ fn main() { //~^ ERROR it is undefined behavior to use this value const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; - //~^ ERROR any use of this value will cause an error + //~^ ERROR it is undefined behavior to use this value const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; //~^ ERROR any use of this value will cause an error diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr index 0126743eedec..60079193ee8e 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr @@ -40,11 +40,13 @@ LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:39:5 | LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:42:5 @@ -78,11 +80,13 @@ LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:54:5 | LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:57:5 diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs index c0bfbc17629f..2bdad3af889d 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.rs +++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs @@ -34,7 +34,8 @@ const fn read_field2() -> Field2 { } const fn read_field3() -> Field3 { - const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value + const FIELD3: Field3 = unsafe { UNION.field3 }; + //~^ ERROR it is undefined behavior to use this value FIELD3 } diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr index 565cd916ffcb..035a95a14c83 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr +++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr @@ -1,10 +1,11 @@ -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/union-const-eval-field.rs:37:5 | -LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR any use of this value - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes +LL | const FIELD3: Field3 = unsafe { UNION.field3 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits | - = note: #[deny(const_err)] on by default + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error: aborting due to previous error +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/union-ice.rs b/src/test/ui/consts/const-eval/union-ice.rs index 0e4f1e09171d..6bd63472b212 100644 --- a/src/test/ui/consts/const-eval/union-ice.rs +++ b/src/test/ui/consts/const-eval/union-ice.rs @@ -20,7 +20,7 @@ union DummyUnion { const UNION: DummyUnion = DummyUnion { field1: 1065353216 }; -const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error +const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value const FIELD_PATH: Struct = Struct { //~ ERROR it is undefined behavior to use this value a: 42, diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr index 98c2c1472aae..a6b49e0cda3a 100644 --- a/src/test/ui/consts/const-eval/union-ice.stderr +++ b/src/test/ui/consts/const-eval/union-ice.stderr @@ -1,10 +1,10 @@ -error: any use of this value will cause an error +error[E0080]: it is undefined behavior to use this value --> $DIR/union-ice.rs:23:1 | -LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR will cause an error - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes +LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits | - = note: #[deny(const_err)] on by default + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior error[E0080]: it is undefined behavior to use this value --> $DIR/union-ice.rs:25:1 From ba82f54b04f429d29b0d7c5aebbae2addd5669fd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Nov 2018 16:16:27 +0100 Subject: [PATCH 33/75] use RawConst in miri --- src/librustc_mir/const_eval.rs | 14 +++++++---- src/librustc_mir/interpret/eval_context.rs | 14 +++++++---- src/librustc_mir/interpret/operand.rs | 28 ++++++---------------- src/librustc_mir/interpret/place.rs | 10 ++------ src/librustc_mir/transform/const_prop.rs | 6 +++-- 5 files changed, 32 insertions(+), 40 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 4e727de53582..3b32fe21adf8 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -99,8 +99,7 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env) } -// FIXME: This thing is a bad hack. We should get rid of it. Ideally constants are always -// in an allocation. +// FIXME: These two conversion functions are bad hacks. We should just always use allocations. pub fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, op: OpTy<'tcx>, @@ -146,6 +145,13 @@ pub fn op_to_const<'tcx>( }; Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, op.layout.ty)) } +pub fn const_to_op<'tcx>( + ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, + cnst: &ty::Const<'tcx>, +) -> EvalResult<'tcx, OpTy<'tcx>> { + let op = ecx.const_value_to_op(cnst.val)?; + Ok(OpTy { op, layout: ecx.layout_of(cnst.ty)? }) +} fn eval_body_and_ecx<'a, 'mir, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -496,7 +502,7 @@ pub fn const_field<'a, 'tcx>( let ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); let result = (|| { // get the operand again - let op = ecx.const_to_op(value)?; + let op = const_to_op(&ecx, value)?; // downcast let down = match variant { None => op, @@ -523,7 +529,7 @@ pub fn const_variant_index<'a, 'tcx>( ) -> EvalResult<'tcx, VariantIdx> { trace!("const_variant_index: {:?}, {:?}", instance, val); let ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); - let op = ecx.const_to_op(val)?; + let op = const_to_op(&ecx, val)?; Ok(ecx.read_discriminant(op)?.1) } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index ce7269d1e783..1d7eae50e718 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -588,18 +588,22 @@ pub(super) fn deallocate_local( Ok(()) } - pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> { + pub fn const_eval_raw( + &self, + gid: GlobalId<'tcx>, + ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { let param_env = if self.tcx.is_static(gid.instance.def_id()).is_some() { ty::ParamEnv::reveal_all() } else { self.param_env }; - self.tcx.const_eval(param_env.and(gid)).map_err(|err| { + let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { match err { - ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(), - ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(), + ErrorHandled::Reported => EvalErrorKind::ReferencedConstant, + ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric, } - }) + })?; + self.raw_const_to_mplace(val) } pub fn dump_place(&self, place: Place) { diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 16f1e487f59a..5d993cfee084 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -13,7 +13,7 @@ use std::convert::TryInto; -use rustc::{mir, ty}; +use rustc::mir; use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx}; use rustc::mir::interpret::{ @@ -535,9 +535,10 @@ pub(super) fn eval_operands( .collect() } - // Also used e.g. when miri runs into a constant. - // FIXME: Can we avoid converting with ConstValue and Const? We should be using RawConst. - fn const_value_to_op( + // Used when miri runs into a constant, and by CTFE. + // FIXME: CTFE should use allocations, then we can make this private (embed it into + // `eval_operand`, ideally). + pub(crate) fn const_value_to_op( &self, val: ConstValue<'tcx>, ) -> EvalResult<'tcx, Operand> { @@ -545,10 +546,10 @@ fn const_value_to_op( match val { ConstValue::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; - self.global_to_op(GlobalId { + Ok(*OpTy::from(self.const_eval_raw(GlobalId { instance, promoted: None, - }) + })?)) } ConstValue::ByRef(id, alloc, offset) => { // We rely on mutability being set correctly in that allocation to prevent writes @@ -566,21 +567,6 @@ fn const_value_to_op( Ok(Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag()), } } - pub fn const_to_op( - &self, - cnst: &ty::Const<'tcx>, - ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { - let op = self.const_value_to_op(cnst.val)?; - Ok(OpTy { op, layout: self.layout_of(cnst.ty)? }) - } - - pub(super) fn global_to_op( - &self, - gid: GlobalId<'tcx> - ) -> EvalResult<'tcx, Operand> { - let cv = self.const_eval(gid)?; - self.const_value_to_op(cv.val) - } /// Read discriminant, return the runtime value as well as the variant index. pub fn read_discriminant( diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 104d66f7bde2..9f248d463507 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -553,16 +553,10 @@ pub(super) fn eval_place_to_mplace( Ok(match *mir_place { Promoted(ref promoted) => { let instance = self.frame().instance; - let op = self.global_to_op(GlobalId { + self.const_eval_raw(GlobalId { instance, promoted: Some(promoted.0), - })?; - let mplace = op.to_mem_place(); // these are always in memory - let ty = self.monomorphize(promoted.1, self.substs()); - MPlaceTy { - mplace, - layout: self.layout_of(ty)?, - } + })? } Static(ref static_) => { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 6b8233c941e8..661ca4773b4a 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -29,7 +29,9 @@ }; use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind}; -use const_eval::{CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_borrowck_eval_cx}; +use const_eval::{ + CompileTimeInterpreter, const_to_op, error_to_const_error, eval_promoted, mk_borrowck_eval_cx +}; use transform::{MirPass, MirSource}; pub struct ConstProp; @@ -262,7 +264,7 @@ fn eval_constant( source_info: SourceInfo, ) -> Option> { self.ecx.tcx.span = source_info.span; - match self.ecx.const_to_op(c.literal) { + match const_to_op(&self.ecx, c.literal) { Ok(op) => { Some((op, c.span)) }, From c462e44c13ce33359dc50dbeb4f60ef552acd438 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 7 Nov 2018 13:51:29 +0100 Subject: [PATCH 34/75] we now do proper validation on scalars --- src/test/ui/consts/const-err4.stderr | 2 +- .../const-pointer-values-in-various-types.stderr | 4 ++-- src/test/ui/consts/const-eval/ub-enum.rs | 10 +++++----- src/test/ui/consts/const-eval/ub-enum.stderr | 8 ++++---- .../ui/consts/const-eval/union-const-eval-field.stderr | 2 +- src/test/ui/consts/const-eval/union-ice.stderr | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/test/ui/consts/const-err4.stderr b/src/test/ui/consts/const-err4.stderr index 2f58712be28f..38a8f75a5c20 100644 --- a/src/test/ui/consts/const-err4.stderr +++ b/src/test/ui/consts/const-err4.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-err4.rs:18:11 | LL | Boo = [unsafe { Foo { b: () }.a }; 4][3], - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr index 60079193ee8e..786338222e3b 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr @@ -44,7 +44,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:39:5 | LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior @@ -84,7 +84,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/const-pointer-values-in-various-types.rs:54:5 | LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index 89b449464419..2bf85e25a21a 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -16,12 +16,12 @@ enum Enum { A = 0, } union TransmuteEnum { - a: &'static u8, - out: Enum, + in1: &'static u8, + out1: Enum, } // A pointer is guaranteed non-null -const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out }; +const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; //~^ ERROR is undefined behavior // (Potentially) invalid enum discriminant @@ -48,8 +48,8 @@ union TransmuteEnum2 { const BAD_ENUM4: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; //~^ ERROR is undefined behavior -// Undef enum discriminant. In an arry to avoid `Scalar` layout. -const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2]; +// Undef enum discriminant. +const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; //~^ ERROR is undefined behavior // Pointer value in an enum with a niche that is not just 0. diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr index 5aae3a2f3511..509faaa46f81 100644 --- a/src/test/ui/consts/const-eval/ub-enum.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.stderr @@ -1,8 +1,8 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:24:1 | -LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { a: &1 }.out }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant +LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior @@ -33,8 +33,8 @@ LL | const BAD_ENUM4: Wrap = unsafe { TransmuteEnum2 { in2: &0 }.out2 }; error[E0080]: it is undefined behavior to use this value --> $DIR/ub-enum.rs:52:1 | -LL | const BAD_ENUM_UNDEF: [Enum2; 2] = [unsafe { TransmuteEnum2 { in3: () }.out1 }; 2]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at [0], but expected a valid enum discriminant +LL | const BAD_ENUM_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr index 035a95a14c83..ca7cf2b028ce 100644 --- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr +++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/union-const-eval-field.rs:37:5 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr index a6b49e0cda3a..7cadef246177 100644 --- a/src/test/ui/consts/const-eval/union-ice.stderr +++ b/src/test/ui/consts/const-eval/union-ice.stderr @@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/union-ice.rs:23:1 | LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR it is undefined behavior to use this value - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain bits + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior From 612febcc4bec60dba58472269c2cf30860315a3d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 17 Nov 2018 15:45:09 +0100 Subject: [PATCH 35/75] explain why we can use raw --- src/librustc_mir/interpret/eval_context.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 1d7eae50e718..590834135824 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -597,6 +597,10 @@ pub fn const_eval_raw( } else { self.param_env }; + // We use `const_eval_raw` here, and get an unvalidated result. That is okay: + // Our result will later be validated anyway, and there seems no good reason + // to have to fail early here. This is also more consistent with + // `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles. let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { match err { ErrorHandled::Reported => EvalErrorKind::ReferencedConstant, From 9240ad4571d9000cffc7a02764f09834fade6e4d Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Tue, 20 Nov 2018 10:47:28 +0100 Subject: [PATCH 36/75] Update releases to add rename dependencies feature --- RELEASES.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 6f5f45aed210..a455186859f8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -45,6 +45,8 @@ Stabilized APIs Cargo ----- - [Cargo will now download crates in parallel using HTTP/2.][cargo/6005] +- [You can now rename packages in your Cargo.toml][cargo/6319] We have a guide + on [how to use the `package` key in your dependencies.][cargo-rename-reference] [52813]: https://github.com/rust-lang/rust/pull/52813/ [53218]: https://github.com/rust-lang/rust/pull/53218/ @@ -68,6 +70,8 @@ Cargo [`slice::rchunks_mut`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks_mut [`slice::rchunks`]: https://doc.rust-lang.org/std/primitive.slice.html#method.rchunks [cargo/6005]: https://github.com/rust-lang/cargo/pull/6005/ +[cargo/6319]: https://github.com/rust-lang/cargo/pull/6319/ +[cargo-rename-reference]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml [const-reference]: https://doc.rust-lang.org/reference/items/functions.html#const-functions From 88d60941da317d8e9deee34d2ed5e8dbb54f928c Mon Sep 17 00:00:00 2001 From: Axary Date: Tue, 20 Nov 2018 14:43:16 +0100 Subject: [PATCH 37/75] improve error note --- src/libsyntax/parse/parser.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn-start.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn-start.stderr | 2 +- src/test/ui/invalid-self-argument/bare-fn.rs | 2 +- src/test/ui/invalid-self-argument/bare-fn.stderr | 2 +- src/test/ui/invalid-self-argument/trait-fn.rs | 2 +- src/test/ui/invalid-self-argument/trait-fn.stderr | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 18929af4718f..e4a4c1f5a7cc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1828,7 +1828,7 @@ fn parse_arg_general(&mut self, require_name: bool) -> PResult<'a, Arg> { let mut err = self.struct_span_err(self.prev_span, "unexpected `self` argument in function"); err.span_label(self.prev_span, - "`self` is only valid as the first argument of a trait function"); + "`self` is only valid as the first argument of an associated function"); return Err(err); } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.rs b/src/test/ui/invalid-self-argument/bare-fn-start.rs index a84fe55502dc..741ba5f41ce1 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.rs +++ b/src/test/ui/invalid-self-argument/bare-fn-start.rs @@ -1,5 +1,5 @@ fn a(&self) { } //~^ ERROR unexpected `self` argument in function -//~| NOTE `self` is only valid as the first argument of a trait function +//~| NOTE `self` is only valid as the first argument of an associated function fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn-start.stderr b/src/test/ui/invalid-self-argument/bare-fn-start.stderr index d0eca1a9e5ce..6a878b619d81 100644 --- a/src/test/ui/invalid-self-argument/bare-fn-start.stderr +++ b/src/test/ui/invalid-self-argument/bare-fn-start.stderr @@ -2,7 +2,7 @@ error: unexpected `self` argument in function --> $DIR/bare-fn-start.rs:1:7 | LL | fn a(&self) { } - | ^^^^ `self` is only valid as the first argument of a trait function + | ^^^^ `self` is only valid as the first argument of an associated function error: aborting due to previous error diff --git a/src/test/ui/invalid-self-argument/bare-fn.rs b/src/test/ui/invalid-self-argument/bare-fn.rs index 27e56a537139..704fa996ca63 100644 --- a/src/test/ui/invalid-self-argument/bare-fn.rs +++ b/src/test/ui/invalid-self-argument/bare-fn.rs @@ -1,5 +1,5 @@ fn b(foo: u32, &mut self) { } //~^ ERROR unexpected `self` argument in function -//~| NOTE `self` is only valid as the first argument of a trait function +//~| NOTE `self` is only valid as the first argument of an associated function fn main() { } diff --git a/src/test/ui/invalid-self-argument/bare-fn.stderr b/src/test/ui/invalid-self-argument/bare-fn.stderr index bd6c598c88a0..b13f746a4ec5 100644 --- a/src/test/ui/invalid-self-argument/bare-fn.stderr +++ b/src/test/ui/invalid-self-argument/bare-fn.stderr @@ -2,7 +2,7 @@ error: unexpected `self` argument in function --> $DIR/bare-fn.rs:1:21 | LL | fn b(foo: u32, &mut self) { } - | ^^^^ `self` is only valid as the first argument of a trait function + | ^^^^ `self` is only valid as the first argument of an associated function error: aborting due to previous error diff --git a/src/test/ui/invalid-self-argument/trait-fn.rs b/src/test/ui/invalid-self-argument/trait-fn.rs index e2107e4d8676..31e867bc7641 100644 --- a/src/test/ui/invalid-self-argument/trait-fn.rs +++ b/src/test/ui/invalid-self-argument/trait-fn.rs @@ -3,7 +3,7 @@ struct Foo {} impl Foo { fn c(foo: u32, self) {} //~^ ERROR unexpected `self` argument in function - //~| NOTE `self` is only valid as the first argument of a trait function + //~| NOTE `self` is only valid as the first argument of an associated function fn good(&mut self, foo: u32) {} } diff --git a/src/test/ui/invalid-self-argument/trait-fn.stderr b/src/test/ui/invalid-self-argument/trait-fn.stderr index d056e53b95c7..b3c2cc5b5ebe 100644 --- a/src/test/ui/invalid-self-argument/trait-fn.stderr +++ b/src/test/ui/invalid-self-argument/trait-fn.stderr @@ -2,7 +2,7 @@ error: unexpected `self` argument in function --> $DIR/trait-fn.rs:4:20 | LL | fn c(foo: u32, self) {} - | ^^^^ `self` is only valid as the first argument of a trait function + | ^^^^ `self` is only valid as the first argument of an associated function error: aborting due to previous error From 8a0909df79d30c2d893dc6b6bfc2ec5667dc28cc Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 20 Nov 2018 17:30:29 +0100 Subject: [PATCH 38/75] Remove incorrect doc comment --- src/librustc_codegen_ssa/mono_item.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs index 53acb3e376c7..8fe897919690 100644 --- a/src/librustc_codegen_ssa/mono_item.rs +++ b/src/librustc_codegen_ssa/mono_item.rs @@ -8,12 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and -//! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates -//! paths etc in all kinds of annoying scenarios. - use base; use rustc::hir; use rustc::hir::def::Def; From 9ce7b11e7c6ac970c4a507f27ea340d4dd4e8960 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 20 Nov 2018 17:32:46 +0100 Subject: [PATCH 39/75] Remove incorrect doc comment in rustc_mir::monomorphize::item --- src/librustc_mir/monomorphize/item.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 9d69a5669b1c..9c90e5ffd3c7 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -8,12 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_item_path` attribute and -//! generates an error giving, respectively, the symbol name or -//! item-path. This is used for unit testing the code that generates -//! paths etc in all kinds of annoying scenarios. - use monomorphize::Instance; use rustc::hir; use rustc::hir::def_id::DefId; From 595bea6b3306f3bb3e420d00a709e68a30b93425 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 19 Nov 2018 17:21:10 +1300 Subject: [PATCH 40/75] Update RLS and Rustfmt --- src/Cargo.lock | 153 ++++++++++++++++++++++++++-------------------- src/tools/rls | 2 +- src/tools/rustfmt | 2 +- 3 files changed, 89 insertions(+), 68 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 94a07f6c91cf..e7b42a038a3b 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -605,12 +605,13 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -724,7 +725,7 @@ name = "failure_derive" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1331,7 +1332,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1581,7 +1582,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.13" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1660,23 +1661,23 @@ name = "quote" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "racer" -version = "2.1.9" +version = "2.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)", "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1798,7 +1799,7 @@ dependencies = [ [[package]] name = "rls" -version = "0.130.5" +version = "1.31.6" dependencies = [ "cargo 0.33.0", "cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1813,20 +1814,20 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "racer 2.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-analysis 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-analysis 0.16.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", "rls-rustc 0.5.0 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", "rustc_tools_util 0.1.0", - "rustfmt-nightly 0.99.6", + "rustfmt-nightly 1.0.0", "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1837,7 +1838,7 @@ dependencies = [ [[package]] name = "rls-analysis" -version = "0.16.1" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1852,7 +1853,7 @@ dependencies = [ [[package]] name = "rls-blacklist" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1883,9 +1884,10 @@ dependencies = [ [[package]] name = "rls-vfs" -version = "0.4.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1932,15 +1934,20 @@ dependencies = [ [[package]] name = "rustc-ap-arena" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc-ap-graphviz" +version = "297.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-ap-rustc_cratesio_shim" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1950,7 +1957,7 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_data_structures" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1958,8 +1965,9 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-graphviz 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1969,33 +1977,34 @@ dependencies = [ [[package]] name = "rustc-ap-rustc_errors" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-rustc_target" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-serialize" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2003,29 +2012,29 @@ dependencies = [ [[package]] name = "rustc-ap-syntax" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_errors 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_errors 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-ap-syntax_pos" -version = "274.0.0" +version = "297.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-arena 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-arena 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2526,7 +2535,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "0.99.6" +version = "1.0.0" dependencies = [ "assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2541,9 +2550,9 @@ dependencies = [ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-rustc_target 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0", "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2620,7 +2629,7 @@ name = "serde_derive" version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2762,7 +2771,7 @@ name = "strum_macros" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2792,7 +2801,17 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.15.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2810,7 +2829,7 @@ name = "synstructure" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3237,7 +3256,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870" "checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142" "checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a" -"checksum derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46c7f14685a20f5dd08e7f754f2ea8cc064d8f4214ae21116c106a2768ba7b9b" +"checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" @@ -3342,7 +3361,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -"checksum proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5697238f0d893c7f0ecc59c0999f18d2af85e424de441178bcacc9f9e6cf67" +"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" "checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f" "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" @@ -3350,7 +3369,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" -"checksum racer 2.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5eeddfffd44c83eb03eedf5eb336e9c75303534fe28728a9f6b39a6e6f07ccff" +"checksum racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "344a53b68d889ab5f44d0617f2bbe1f696abe6a730bd41fa619cfc6fa83a6078" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" @@ -3363,20 +3382,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum rls-analysis 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a625690e3bf1204ce27b50f71e508ee788214b2d51e26e4e5db884a83627673" -"checksum rls-blacklist 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e4a9cc2545ccb7e05b355bfe047b8039a6ec12270d5f3c996b766b340a50f7d2" +"checksum rls-analysis 0.16.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2a1d3a2a8c03e380331aefb8b5e3e06f3065602fbaa6657ba0ac649dc99d8537" +"checksum rls-blacklist 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ce1fdac03e138c4617ff87b194e1ff57a39bb985a044ccbd8673d30701e411" "checksum rls-data 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a209ce46bb52813cbe0786a7baadc0c1a3f5543ef93f179eda3b841ed72cf2e" "checksum rls-rustc 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9dba7390427aefa953608429701e3665192ca810ba8ae09301e001b7c7bed0" "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" -"checksum rls-vfs 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ecbc8541b4c341d6271eae10f869dd9d36db871afe184f5b6f9bffbd6ed0373f" -"checksum rustc-ap-arena 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "866fda692855b38f9d6562f0e952c75c6ebe4032d7dd63c608a88e7c4d3f8087" -"checksum rustc-ap-rustc_cratesio_shim 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6c2343e11a97b4eb3bee29cd5f9314ea409a87baee5d3fec8d1516d1633412e" -"checksum rustc-ap-rustc_data_structures 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b88f905f7ab99bf14220a3a87eff60ec143af8136fd0ca8573641c78be532ec8" -"checksum rustc-ap-rustc_errors 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c86fda6cf42e0355b7ecf40f14888340c20b7b864c9d37f6ffca85fe87200652" -"checksum rustc-ap-rustc_target 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fa8622299beac8c40270e8536a7b0509ca80f227a2b56550019a325fa5a60c0" -"checksum rustc-ap-serialize 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d16cc3d014af9a524c0bed6ca806c3170e39d5987180f0f8ce8fb7df5113576c" -"checksum rustc-ap-syntax 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a29f280f04f4f45e1bdd773ab5e667b36e757bfbbd01193c330815b9e76d05a" -"checksum rustc-ap-syntax_pos 274.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c2ea27b65311571c7614deb393691eb18c5e41fd4fd9d8490304e128e1358646" +"checksum rls-vfs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "72d56425bd5aa86d9d4372b76f0381d3b4bda9c0220e71956c9fcc929f45c1f1" +"checksum rustc-ap-arena 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b69fd4a0e8a3ecd99b497965d05f6f04dd2e4601a6146a841dbe4c8e77c2b30c" +"checksum rustc-ap-graphviz 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8136418dbc491bab74aa0565eaa2086754a7a81a5e74a1d84d6168d18e889e7" +"checksum rustc-ap-rustc_cratesio_shim 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a972feda82332d1d05b1ba5a097e915cd9c9c8f1af2bd7b08af09fb88c753d5f" +"checksum rustc-ap-rustc_data_structures 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "582584c6c48b0ece4b8aef3f9bb59d94d17c5665612bc87a71f509e45a3113b5" +"checksum rustc-ap-rustc_errors 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cd852096944d0ac6af1aefa9639a2ae6dede217606ce97f88ff0dcc8c86d6ff6" +"checksum rustc-ap-rustc_target 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98301a272ecfeec29d2d4e97b07238707c2b89d86fc3a4a5f31a00728f14e288" +"checksum rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f13510e617e2e322e3297038fd6a7346f2297124af9e10e33a627c5d544e9d" +"checksum rustc-ap-syntax 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0792f5a9ccfc5ec13bb5b0472fa49e145481029c39f6bf5b1a36decc99c3328f" +"checksum rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0df9f97f41650d23b14f92f7267f8c61089655efb4533d82bf8991f99245198d" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c6d5a683c6ba4ed37959097e88d71c9e8e26659a3cb5be8b389078e7ad45306" @@ -3412,6 +3432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +"checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" "checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c" diff --git a/src/tools/rls b/src/tools/rls index 1c755efed6ee..daa138ce7f22 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 1c755efed6ee265c762f4d3fec73de8a989637a5 +Subproject commit daa138ce7f222559e9a339600b44a715101a3f4d diff --git a/src/tools/rustfmt b/src/tools/rustfmt index 750b25261380..1cc61cfc2b29 160000 --- a/src/tools/rustfmt +++ b/src/tools/rustfmt @@ -1 +1 @@ -Subproject commit 750b25261380b776de2518fd6863fe63f98d2722 +Subproject commit 1cc61cfc2b29ae3f29a924b4c8feb1bcb09aa5fc From 1af682a55731ca208fa5a5deb1cf5c89a07856a6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 17 Nov 2018 21:08:00 +0300 Subject: [PATCH 41/75] Stabilize `extern_crate_item_prelude` --- src/librustc_resolve/lib.rs | 12 +-- src/librustc_resolve/macros.rs | 5 +- src/librustc_resolve/resolve_imports.rs | 3 +- src/libsyntax/feature_gate.rs | 5 +- .../extern-prelude-extern-crate-proc-macro.rs | 2 - .../feature-gate-extern_crate_item_prelude.rs | 46 ------------ ...ture-gate-extern_crate_item_prelude.stderr | 75 ------------------- ...-prelude-extern-crate-absolute-expanded.rs | 2 - .../extern-prelude-extern-crate-cfg.rs | 1 - .../extern-prelude-extern-crate-pass.rs | 2 - ...elude-extern-crate-restricted-shadowing.rs | 2 - 11 files changed, 7 insertions(+), 148 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7b2d1d4a3d53..4f3a652af914 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -58,7 +58,6 @@ use syntax::ext::base::SyntaxExtension; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; use syntax::ext::base::MacroKind; -use syntax::feature_gate::{emit_feature_err, GateIssue}; use syntax::symbol::{Symbol, keywords}; use syntax::util::lev_distance::find_best_match_for_name; @@ -2115,7 +2114,7 @@ fn resolve_ident_in_lexical_scope(&mut self, if !module.no_implicit_prelude { if ns == TypeNS { - if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) { + if let Some(binding) = self.extern_prelude_get(ident, !record_used) { return Some(LexicalScopeBinding::Item(binding)); } } @@ -5022,7 +5021,7 @@ fn report_conflict<'b>(&mut self, self.name_already_seen.insert(name, span); } - fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_gate: bool) + fn extern_prelude_get(&mut self, ident: Ident, speculative: bool) -> Option<&'a NameBinding<'a>> { if ident.is_path_segment_keyword() { // Make sure `self`, `super` etc produce an error when passed to here. @@ -5030,13 +5029,6 @@ fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_g } self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| { if let Some(binding) = entry.extern_crate_item { - if !speculative && !skip_feature_gate && entry.introduced_by_item && - !self.session.features_untracked().extern_crate_item_prelude { - emit_feature_err(&self.session.parse_sess, "extern_crate_item_prelude", - ident.span, GateIssue::Language, - "use of extern prelude names introduced \ - with `extern crate` items is unstable"); - } Some(binding) } else { let crate_id = if !speculative { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 921f7568b520..581756dc6bf0 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -738,8 +738,7 @@ struct Flags: u8 { } WhereToResolve::ExternPrelude => { if use_prelude { - match self.extern_prelude_get(ident, !record_used, - innermost_result.is_some()) { + match self.extern_prelude_get(ident, !record_used) { Some(binding) => Ok((binding, Flags::PRELUDE)), None => Err(Determinacy::determined( self.graph_root.unresolved_invocations.borrow().is_empty() @@ -906,7 +905,7 @@ struct Flags: u8 { // but its `Def` should coincide with a crate passed with `--extern` // (otherwise there would be ambiguity) and we can skip feature error in this case. if ns != TypeNS || !use_prelude || - self.extern_prelude_get(ident, true, false).is_none() { + self.extern_prelude_get(ident, true).is_none() { let msg = "imports can only refer to extern crate names \ passed with `--extern` on stable channel"; let mut err = feature_err(&self.session.parse_sess, "uniform_paths", diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 9e5036b6e500..422ae677d6a2 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -166,8 +166,7 @@ fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace) assert!(!restricted_shadowing); match uniform_root_kind { UniformRootKind::ExternPrelude => { - return if let Some(binding) = - self.extern_prelude_get(ident, !record_used, false) { + return if let Some(binding) = self.extern_prelude_get(ident, !record_used) { Ok(binding) } else if !self.graph_root.unresolved_invocations.borrow().is_empty() { // Macro-expanded `extern crate` items can add names to extern prelude. diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a7c97feee498..2f5db9bd0815 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -499,9 +499,6 @@ pub fn walk_feature_fields(&self, mut f: F) // Allows `const _: TYPE = VALUE` (active, underscore_const_names, "1.31.0", Some(54912), None), - // `extern crate foo as bar;` puts `bar` into extern prelude. - (active, extern_crate_item_prelude, "1.31.0", Some(55599), None), - // `reason = ` in lint attributes and `expect` lint attribute (active, lint_reasons, "1.31.0", Some(54503), None), ); @@ -691,6 +688,8 @@ pub fn walk_feature_fields(&self, mut f: F) // impl Iterator for &mut Iterator // impl Debug for Foo<'_> (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), + // `extern crate foo as bar;` puts `bar` into extern prelude. + (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs b/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs index e320ad971354..25a2a3761477 100644 --- a/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs +++ b/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs @@ -1,8 +1,6 @@ // compile-pass // edition:2018 -#![feature(extern_crate_item_prelude)] - extern crate proc_macro; use proc_macro::TokenStream; // OK diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs deleted file mode 100644 index 27b9a34ff4eb..000000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs +++ /dev/null @@ -1,46 +0,0 @@ -// edition:2018 - -#![feature(alloc, underscore_imports)] - -extern crate alloc; - -mod in_scope { - fn check() { - let v = alloc::vec![0]; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - type A = alloc::boxed::Box; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - } -} - -mod absolute { - fn check() { - let v = ::alloc::vec![0]; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - type A = ::alloc::boxed::Box; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - } -} - -mod import_in_scope { - use alloc as _; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - use alloc::boxed; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable -} - -mod import_absolute { - use ::alloc; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable - use ::alloc::boxed; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable -} - -extern crate alloc as core; - -mod unrelated_crate_renamed { - type A = core::boxed::Box; - //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr deleted file mode 100644 index 103ab79ef84c..000000000000 --- a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr +++ /dev/null @@ -1,75 +0,0 @@ -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:26:9 - | -LL | use alloc as _; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:28:9 - | -LL | use alloc::boxed; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:33:11 - | -LL | use ::alloc; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:35:11 - | -LL | use ::alloc::boxed; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:9:17 - | -LL | let v = alloc::vec![0]; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:11:18 - | -LL | type A = alloc::boxed::Box; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:18:19 - | -LL | let v = ::alloc::vec![0]; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:20:20 - | -LL | type A = ::alloc::boxed::Box; - | ^^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599) - --> $DIR/feature-gate-extern_crate_item_prelude.rs:42:14 - | -LL | type A = core::boxed::Box; - | ^^^^ - | - = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable - -error: aborting due to 9 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs index b1154f2076b8..cf91a9714ade 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-absolute-expanded.rs @@ -1,8 +1,6 @@ // compile-pass // edition:2018 -#![feature(extern_crate_item_prelude)] - macro_rules! define_iso { () => { extern crate std as iso; }} diff --git a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs index c48a65798b6c..6117e5f6f3cd 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs @@ -1,7 +1,6 @@ // compile-pass // compile-flags:--cfg my_feature -#![feature(extern_crate_item_prelude)] #![no_std] #[cfg(my_feature)] diff --git a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs index 8c147dfd04a3..bb4cf6ca99c7 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs @@ -1,8 +1,6 @@ // compile-pass // aux-build:two_macros.rs -#![feature(extern_crate_item_prelude)] - extern crate two_macros; mod m { diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs index 732f1c4de2fb..3eefaf1267e8 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs @@ -1,7 +1,5 @@ // aux-build:two_macros.rs -#![feature(extern_crate_item_prelude)] - macro_rules! define_vec { () => { extern crate std as Vec; From d4934c748fd9bb74d08d38f240eadf3455777ffb Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 21 Nov 2018 01:28:07 +0300 Subject: [PATCH 42/75] Add a couple more tests --- ...n-prelude-extern-crate-restricted-shadowing.rs | 9 +++++++++ ...elude-extern-crate-restricted-shadowing.stderr | 15 ++++++++++++--- .../extern-prelude-extern-crate-shadowing.rs | 12 ++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs index 3eefaf1267e8..6ff3ab73639c 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs @@ -14,4 +14,13 @@ fn check() { } } +macro_rules! define_other_core { + () => { + extern crate std as core; + //~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern` + } +} + +define_other_core!(); + fn main() {} diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr index 218dfb796f77..795e1761ccdb 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr @@ -1,12 +1,21 @@ +error: macro-expanded `extern crate` items cannot shadow names passed with `--extern` + --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:19:9 + | +LL | extern crate std as core; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | define_other_core!(); + | --------------------- in this macro invocation + error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:15:9 + --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:13:9 | LL | Vec::panic!(); //~ ERROR `Vec` is ambiguous | ^^^ ambiguous name | = note: `Vec` could refer to a struct from prelude note: `Vec` could also refer to the extern crate imported here - --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:7:9 + --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:5:9 | LL | extern crate std as Vec; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,6 +23,6 @@ LL | extern crate std as Vec; LL | define_vec!(); | -------------- in this macro invocation -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs new file mode 100644 index 000000000000..c5adeaf17fa9 --- /dev/null +++ b/src/test/ui/imports/extern-prelude-extern-crate-shadowing.rs @@ -0,0 +1,12 @@ +// compile-pass +// aux-build:two_macros.rs + +extern crate two_macros as core; + +mod m { + fn check() { + core::m!(); // OK + } +} + +fn main() {} From 1e4cf740cfaf5332722ae6ff717ceaed181a4caf Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 21 Nov 2018 03:39:41 +0300 Subject: [PATCH 43/75] resolve: Make "empty import canaries" invisible from other crates --- src/librustc_resolve/resolve_imports.rs | 5 ++++- src/test/ui/imports/auxiliary/issue-55811.rs | 5 +++++ src/test/ui/imports/issue-55811.rs | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/imports/auxiliary/issue-55811.rs create mode 100644 src/test/ui/imports/issue-55811.rs diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 9e5036b6e500..c2ba3048c1b2 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1164,7 +1164,10 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) { None => continue, }; - if binding.is_import() || binding.is_macro_def() { + // Filter away "empty import canaries". + let is_non_canary_import = + binding.is_import() && binding.vis != ty::Visibility::Invisible; + if is_non_canary_import || binding.is_macro_def() { let def = binding.def(); if def != Def::Err { if let Some(def_id) = def.opt_def_id() { diff --git a/src/test/ui/imports/auxiliary/issue-55811.rs b/src/test/ui/imports/auxiliary/issue-55811.rs new file mode 100644 index 000000000000..877e4cdb0bdf --- /dev/null +++ b/src/test/ui/imports/auxiliary/issue-55811.rs @@ -0,0 +1,5 @@ +mod m {} + +// These two imports should not conflict when this crate is loaded from some other crate. +use m::{}; +use m::{}; diff --git a/src/test/ui/imports/issue-55811.rs b/src/test/ui/imports/issue-55811.rs new file mode 100644 index 000000000000..95316777fabf --- /dev/null +++ b/src/test/ui/imports/issue-55811.rs @@ -0,0 +1,6 @@ +// compile-pass +// aux-build:issue-55811.rs + +extern crate issue_55811; + +fn main() {} From 240a55ce50531f3bc237027593205d3b857eba33 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 07:40:31 -0500 Subject: [PATCH 44/75] update books --- 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 e871c4598925..616fe4172b68 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit e871c4598925594421d63e929fee292e6e071f97 +Subproject commit 616fe4172b688393aeee5f34935cc25733c9c062 diff --git a/src/doc/nomicon b/src/doc/nomicon index 7f7a597b47ed..f8a4e96feb2e 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 7f7a597b47ed6c35c2a0f0ee6a69050fe2d5e013 +Subproject commit f8a4e96feb2e5a6ed1ef170ad40e3509a7755cb4 diff --git a/src/doc/reference b/src/doc/reference index b9fb838054b8..60077efda319 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit b9fb838054b8441223c22eeae5b6d8e498071cd0 +Subproject commit 60077efda319c95a89fe39609803c5433567adbf diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index bc342a475c09..2ce92beabb91 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit bc342a475c09b6df8004d518382e6d5b6bcb49f7 +Subproject commit 2ce92beabb912d417a7314d6da83ac9b50dc2afb From 0579ef0166e7ce493e57f17121f7b5ef809265b1 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 14:57:56 -0500 Subject: [PATCH 45/75] fix rustbuild to build all the books --- src/bootstrap/doc.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 7623ca1e27ea..f9b19ffb10d6 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -260,22 +260,31 @@ fn run(self, builder: &Builder) { let compiler = self.compiler; let target = self.target; let name = self.name; - // build book first edition + + // build book builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/first-edition", name)), + name: INTERNER.intern_string(name.to_string()), }); - // build book second edition + // building older edition redirects + + let source_name = format!("{}/first-edition", name); builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/second-edition", name)), + name: INTERNER.intern_string(source_name), }); - // build book 2018 edition + let source_name = format!("{}/second-edition", name); builder.ensure(Rustbook { target, - name: INTERNER.intern_string(format!("{}/2018-edition", name)), + name: INTERNER.intern_string(source_name), + }); + + let source_name = format!("{}/2018-edition", name); + builder.ensure(Rustbook { + target, + name: INTERNER.intern_string(source_name), }); // build the version info page and CSS @@ -284,11 +293,6 @@ fn run(self, builder: &Builder) { target, }); - // build the index page - let index = format!("{}/index.md", name); - builder.info(&format!("Documenting book index ({})", target)); - invoke_rustdoc(builder, compiler, target, &index); - // build the redirect pages builder.info(&format!("Documenting book redirect pages ({})", target)); for file in t!(fs::read_dir(builder.src.join("src/doc/book/redirects"))) { From 57b7d55591d0a4a0d9aa16afa0f202427aa89aa3 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 18:42:49 -0500 Subject: [PATCH 46/75] fix more links --- .../src/language-features/macro-literal-matcher.md | 4 ++-- src/doc/unstable-book/src/language-features/plugin.md | 2 -- src/libcore/iter/iterator.rs | 6 +++--- src/libstd/lib.rs | 10 +++++----- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md b/src/doc/unstable-book/src/language-features/macro-literal-matcher.md index 7e3638fd1cf4..870158200dee 100644 --- a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md +++ b/src/doc/unstable-book/src/language-features/macro-literal-matcher.md @@ -4,7 +4,7 @@ The tracking issue for this feature is: [#35625] The RFC is: [rfc#1576]. -With this feature gate enabled, the [list of fragment specifiers][frags] gains one more entry: +With this feature gate enabled, the [list of designators] gains one more entry: * `literal`: a literal. Examples: 2, "string", 'c' @@ -12,6 +12,6 @@ A `literal` may be followed by anything, similarly to the `ident` specifier. [rfc#1576]: http://rust-lang.github.io/rfcs/1576-macros-literal-matcher.html [#35625]: https://github.com/rust-lang/rust/issues/35625 -[frags]: ../book/first-edition/macros.html#syntactic-requirements +[list of designators]: ../reference/macros-by-example.html ------------------------ diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index b408d5d08051..74bdd4dc3b59 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -137,8 +137,6 @@ of extensions. See `Registry::register_syntax_extension` and the ## Tips and tricks -Some of the [macro debugging tips](../book/first-edition/macros.html#debugging-macro-code) are applicable. - You can use `syntax::parse` to turn token trees into higher-level syntax elements like expressions: diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 2903c370df89..fd4189ef50df 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -532,7 +532,7 @@ fn zip(self, other: U) -> Zip where /// If you're doing some sort of looping for a side effect, it's considered /// more idiomatic to use [`for`] than `map()`. /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// # Examples /// @@ -580,7 +580,7 @@ fn map(self, f: F) -> Map where /// cases `for_each` may also be faster than a loop, because it will use /// internal iteration on adaptors like `Chain`. /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// # Examples /// @@ -1669,7 +1669,7 @@ fn try_for_each(&mut self, mut f: F) -> R where /// use a `for` loop with a list of things to build up a result. Those /// can be turned into `fold()`s: /// - /// [`for`]: ../../book/first-edition/loops.html#for + /// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for /// /// ``` /// let numbers = [1, 2, 3, 4, 5]; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f460d109c894..eb7caa61972f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -185,7 +185,7 @@ //! [slice]: primitive.slice.html //! [`atomic`]: sync/atomic/index.html //! [`collections`]: collections/index.html -//! [`for`]: ../book/first-edition/loops.html#for +/// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for //! [`format!`]: macro.format.html //! [`fs`]: fs/index.html //! [`io`]: io/index.html @@ -200,14 +200,14 @@ //! [`sync`]: sync/index.html //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html -//! [`use`]: ../book/first-edition/crates-and-modules.html#importing-modules-with-use -//! [crate root]: ../book/first-edition/crates-and-modules.html#basic-terminology-crates-and-modules +//! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#use-to-bring-paths-into-scope +//! [crate root]: ../book/ch07-01-packages-and-crates-for-making-libraries-and-executables.html //! [crates.io]: https://crates.io -//! [deref-coercions]: ../book/second-edition/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods +//! [deref-coercions]: ../book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods //! [files]: fs/struct.File.html //! [multithreading]: thread/index.html //! [other]: #what-is-in-the-standard-library-documentation -//! [primitive types]: ../book/first-edition/primitive-types.html +//! [primitive types]: ../book/ch03-02-data-types.html #![stable(feature = "rust1", since = "1.0.0")] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", From da622a3796f5488d89daaf3b32ceb509ce4d669b Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 21 Jul 2018 22:15:11 +0300 Subject: [PATCH 47/75] rustc: remove {FxHash,Node,DefId,HirId,ItemLocal}{Map,Set} "constructor" fns. --- src/librustc/hir/lowering.rs | 17 ++++++----- src/librustc/hir/map/definitions.rs | 2 +- src/librustc/infer/opaque_types/mod.rs | 2 +- src/librustc/lint/mod.rs | 2 +- src/librustc/middle/liveness.rs | 12 ++++---- src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 12 ++++---- src/librustc/ty/context.rs | 28 +++++++++---------- src/librustc/util/nodemap.rs | 4 --- src/librustc_codegen_llvm/debuginfo/mod.rs | 2 +- .../back/symbol_export.rs | 4 +-- src/librustc_data_structures/fx.rs | 4 +-- src/librustc_lint/builtin.rs | 2 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_mir/build/mod.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 2 +- src/librustc_mir/transform/mod.rs | 2 +- src/librustc_passes/rvalue_promotion.rs | 4 +-- src/librustc_privacy/lib.rs | 2 +- src/librustc_resolve/check_unused.rs | 2 +- src/librustc_resolve/lib.rs | 18 ++++++------ src/librustc_typeck/check/mod.rs | 8 +++--- src/librustc_typeck/check/writeback.rs | 2 +- src/librustc_typeck/check_unused.rs | 2 +- .../coherence/inherent_impls.rs | 2 +- src/librustc_typeck/variance/terms.rs | 2 +- src/librustdoc/passes/strip_hidden.rs | 2 +- src/librustdoc/passes/strip_private.rs | 2 +- 28 files changed, 72 insertions(+), 75 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index ce1e67804318..7ac3b033437f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -244,9 +244,9 @@ pub fn lower_crate( loop_scopes: Vec::new(), is_in_loop_condition: false, anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough, - type_def_lifetime_params: DefIdMap(), + type_def_lifetime_params: Default::default(), current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)], - item_local_id_counters: NodeMap(), + item_local_id_counters: Default::default(), node_id_to_hir_id: IndexVec::new(), is_generator: false, is_in_trait_impl: false, @@ -1168,7 +1168,7 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T hir::TyKind::BareFn(P(hir::BareFnTy { generic_params: this.lower_generic_params( &f.generic_params, - &NodeMap(), + &NodeMap::default(), ImplTraitContext::disallowed(), ), unsafety: this.lower_unsafety(f.unsafety), @@ -2467,7 +2467,7 @@ fn lower_generics( // FIXME: This could probably be done with less rightward drift. Also looks like two control // paths where report_error is called are also the only paths that advance to after // the match statement, so the error reporting could probably just be moved there. - let mut add_bounds: NodeMap> = NodeMap(); + let mut add_bounds: NodeMap> = Default::default(); for pred in &generics.where_clause.predicates { if let WherePredicate::BoundPredicate(ref bound_pred) = *pred { 'next_bound: for bound in &bound_pred.bounds { @@ -2552,7 +2552,7 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { bound_generic_params: this.lower_generic_params( bound_generic_params, - &NodeMap(), + &NodeMap::default(), ImplTraitContext::disallowed(), ), bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()), @@ -2636,8 +2636,11 @@ fn lower_poly_trait_ref( p: &PolyTraitRef, mut itctx: ImplTraitContext<'_>, ) -> hir::PolyTraitRef { - let bound_generic_params = - self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx.reborrow()); + let bound_generic_params = self.lower_generic_params( + &p.bound_generic_params, + &NodeMap::default(), + itctx.reborrow(), + ); let trait_ref = self.with_parent_impl_lifetime_defs( &bound_generic_params, |this| this.lower_trait_ref(&p.trait_ref, itctx), diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index dd6891540868..6be7444136e2 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -418,7 +418,7 @@ pub fn new() -> Definitions { index_to_key: [vec![], vec![]], def_path_hashes: [vec![], vec![]], }, - node_to_def_index: NodeMap(), + node_to_def_index: Default::default(), def_index_to_node: [vec![], vec![]], node_to_hir_id: IndexVec::new(), parent_modules_of_macro_defs: Default::default(), diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index cc73dd63816a..fda9817cc88a 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -121,7 +121,7 @@ pub fn instantiate_opaque_types>( parent_def_id, body_id, param_env, - opaque_types: DefIdMap(), + opaque_types: Default::default(), obligations: vec![], }; let value = instantiator.instantiate_opaque_types_in_map(value); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 18922ec5d173..c43cdb24c339 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -496,7 +496,7 @@ pub struct LintBuffer { impl LintBuffer { pub fn new() -> LintBuffer { - LintBuffer { map: NodeMap() } + LintBuffer { map: ::std::default::Default::default() } } pub fn add_lint(&mut self, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 1b258a23462c..54a0192d2e8a 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -272,9 +272,9 @@ fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> IrMaps<'a, 'tcx> { tcx, num_live_nodes: 0, num_vars: 0, - live_node_map: HirIdMap(), - variable_map: HirIdMap(), - capture_info_map: NodeMap(), + live_node_map: HirIdMap::default(), + variable_map: HirIdMap::default(), + capture_info_map: Default::default(), var_kinds: Vec::new(), lnks: Vec::new(), } @@ -397,7 +397,7 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>, fn add_from_pat<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, pat: &P) { // For struct patterns, take note of which fields used shorthand // (`x` rather than `x: x`). - let mut shorthand_field_ids = HirIdSet(); + let mut shorthand_field_ids = HirIdSet::default(); let mut pats = VecDeque::new(); pats.push_back(pat); while let Some(pat) = pats.pop_front() { @@ -691,8 +691,8 @@ fn new(ir: &'a mut IrMaps<'a, 'tcx>, body: hir::BodyId) -> Liveness<'a, 'tcx> { s: specials, successors: vec![invalid_node(); num_live_nodes], rwu_table: RWUTable::new(num_live_nodes * num_vars), - break_ln: NodeMap(), - cont_ln: NodeMap(), + break_ln: Default::default(), + cont_ln: Default::default(), } } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 8c3a3fb6dc1d..0009a517dd1d 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -408,7 +408,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> let mut reachable_context = ReachableContext { tcx, tables: &ty::TypeckTables::empty(None), - reachable_symbols: NodeSet(), + reachable_symbols: Default::default(), worklist: Vec::new(), any_library, }; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 79cd8b21f1b6..b7f4e3808159 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -425,8 +425,8 @@ fn resolve_lifetimes<'tcx>( fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap { let krate = tcx.hir.krate(); let mut map = NamedRegionMap { - defs: NodeMap(), - late_bound: NodeSet(), + defs: Default::default(), + late_bound: Default::default(), object_lifetime_defaults: compute_object_lifetime_defaults(tcx), }; { @@ -437,8 +437,8 @@ fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap { trait_ref_hack: false, is_in_fn_syntax: false, labels_in_fn: vec![], - xcrate_object_lifetime_defaults: DefIdMap(), - lifetime_uses: &mut DefIdMap(), + xcrate_object_lifetime_defaults: Default::default(), + lifetime_uses: &mut Default::default(), }; for (_, item) in &krate.items { visitor.visit_item(item); @@ -1278,7 +1278,7 @@ fn check_if_label_shadows_lifetime( fn compute_object_lifetime_defaults( tcx: TyCtxt<'_, '_, '_>, ) -> NodeMap> { - let mut map = NodeMap(); + let mut map = NodeMap::default(); for item in tcx.hir.krate().items.values() { match item.node { hir::ItemKind::Struct(_, ref generics) @@ -1432,7 +1432,7 @@ fn with(&mut self, wrap_scope: Scope<'_>, f: F) } = self; let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); let xcrate_object_lifetime_defaults = - replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap()); + replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap::default()); let mut this = LifetimeContext { tcx: *tcx, map: map, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 923d362c2345..a8ce52a8e156 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -446,22 +446,22 @@ impl<'tcx> TypeckTables<'tcx> { pub fn empty(local_id_root: Option) -> TypeckTables<'tcx> { TypeckTables { local_id_root, - type_dependent_defs: ItemLocalMap(), - field_indices: ItemLocalMap(), - user_provided_tys: ItemLocalMap(), + type_dependent_defs: Default::default(), + field_indices: Default::default(), + user_provided_tys: Default::default(), user_provided_sigs: Default::default(), - node_types: ItemLocalMap(), - node_substs: ItemLocalMap(), - user_substs: ItemLocalMap(), - adjustments: ItemLocalMap(), - pat_binding_modes: ItemLocalMap(), - pat_adjustments: ItemLocalMap(), + node_types: Default::default(), + node_substs: Default::default(), + user_substs: Default::default(), + adjustments: Default::default(), + pat_binding_modes: Default::default(), + pat_adjustments: Default::default(), upvar_capture_map: Default::default(), - closure_kind_origins: ItemLocalMap(), - liberated_fn_sigs: ItemLocalMap(), - fru_field_types: ItemLocalMap(), - cast_kinds: ItemLocalMap(), - used_trait_imports: Lrc::new(DefIdSet()), + closure_kind_origins: Default::default(), + liberated_fn_sigs: Default::default(), + fru_field_types: Default::default(), + cast_kinds: Default::default(), + used_trait_imports: Lrc::new(Default::default()), tainted_by_errors: false, free_region_map: Default::default(), concrete_existential_types: Default::default(), diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index dbd3e00d9fd1..6adfe2cde6c3 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -10,8 +10,6 @@ //! An efficient hash map for node IDs -#![allow(non_snake_case)] - use hir::def_id::DefId; use hir::{HirId, ItemLocalId}; use syntax::ast; @@ -22,9 +20,7 @@ macro_rules! define_id_collections { ($map_name:ident, $set_name:ident, $key:ty) => { pub type $map_name = FxHashMap<$key, T>; - pub fn $map_name() -> $map_name { Default::default() } pub type $set_name = FxHashSet<$key>; - pub fn $set_name() -> $set_name { Default::default() } } } diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 9784cc6cf9c8..6dd13447fb55 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -106,7 +106,7 @@ pub fn new(llmod: &'a llvm::Module) -> Self { created_files: Default::default(), created_enum_disr_types: Default::default(), type_map: Default::default(), - namespace_map: RefCell::new(DefIdMap()), + namespace_map: RefCell::new(Default::default()), composite_types_completed: Default::default(), } } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index dff7e518630e..10dd1de8b784 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -64,7 +64,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { - return Lrc::new(DefIdMap()) + return Lrc::new(Default::default()) } // Check to see if this crate is a "special runtime crate". These @@ -299,7 +299,7 @@ fn upstream_monomorphizations_provider<'a, 'tcx>( let cnums = tcx.all_crate_nums(LOCAL_CRATE); - let mut instances: DefIdMap> = DefIdMap(); + let mut instances: DefIdMap> = Default::default(); let cnum_stable_ids: IndexVec = { let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, diff --git a/src/librustc_data_structures/fx.rs b/src/librustc_data_structures/fx.rs index bce21f5085c7..7c7fc3a93462 100644 --- a/src/librustc_data_structures/fx.rs +++ b/src/librustc_data_structures/fx.rs @@ -8,6 +8,4 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use rustc_hash::FxHashMap; -pub use rustc_hash::FxHashSet; -pub use rustc_hash::FxHasher; +pub use rustc_hash::{FxHasher, FxHashMap, FxHashSet}; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index bef7b364d844..7dd1ca3493e9 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -603,7 +603,7 @@ fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { }; if self.impling_types.is_none() { - let mut impls = NodeSet(); + let mut impls = NodeSet::default(); cx.tcx.for_each_impl(debug, |d| { if let Some(ty_def) = cx.tcx.type_of(d).ty_adt_def() { if let Some(node_id) = cx.tcx.hir.as_local_node_id(ty_def.did) { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index e1d9ca5339e6..c7bd1744a3d6 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -316,7 +316,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { use std::collections::hash_map::Entry; assert_eq!(cnum, LOCAL_CRATE); - let mut visible_parent_map: DefIdMap = DefIdMap(); + let mut visible_parent_map: DefIdMap = Default::default(); // Issue 46112: We want the map to prefer the shortest // paths when reporting the path to an item. Therefore we diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 0aa1924c0e59..d95a74be7769 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -829,7 +829,7 @@ fn new(hir: Cx<'a, 'gcx, 'tcx>, 1, ), upvar_decls, - var_indices: NodeMap(), + var_indices: Default::default(), unit_temp: None, cached_resume_block: None, cached_return_block: None, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 8e27635dee8c..b4ffb39a2ebd 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -314,7 +314,7 @@ pub fn collect_crate_mono_items<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, time(tcx.sess, "collecting mono items", || { par_iter(roots).for_each(|root| { - let mut recursion_depths = DefIdMap(); + let mut recursion_depths = DefIdMap::default(); collect_items_rec(tcx, root, visited, diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 92cfcb3fd56c..8d3a04f9f3c2 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -72,7 +72,7 @@ fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum) -> Lrc { assert_eq!(krate, LOCAL_CRATE); - let mut set = DefIdSet(); + let mut set = DefIdSet::default(); // All body-owners have MIR associated with them. set.extend(tcx.body_owners()); diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index a90cccfa7a77..099c6df32ad1 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -84,10 +84,10 @@ fn rvalue_promotable_map<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tables: &ty::TypeckTables::empty(None), in_fn: false, in_static: false, - mut_rvalue_borrows: NodeSet(), + mut_rvalue_borrows: Default::default(), param_env: ty::ParamEnv::empty(), identity_substs: Substs::empty(), - result: ItemLocalSet(), + result: ItemLocalSet::default(), }; // `def_id` should be a `Body` owner diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 5f8c7daea6e9..fbd6f6edd31c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1761,7 +1761,7 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx, access_levels: &visitor.access_levels, in_variant: false, - old_error_set: NodeSet(), + old_error_set: Default::default(), }; intravisit::walk_crate(&mut visitor, krate); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index ddcaf128bf5b..659ca1f5b9f3 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -162,7 +162,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) { let mut visitor = UnusedImportCheckVisitor { resolver, - unused_imports: NodeMap(), + unused_imports: Default::default(), base_id: ast::DUMMY_NODE_ID, item_span: DUMMY_SP, }; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7b2d1d4a3d53..5f4e9946e501 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1862,22 +1862,22 @@ pub fn new(session: &'a Session, primitive_type_table: PrimitiveTypeTable::new(), - def_map: NodeMap(), - import_map: NodeMap(), - freevars: NodeMap(), - freevars_seen: NodeMap(), + def_map: Default::default(), + import_map: Default::default(), + freevars: Default::default(), + freevars_seen: Default::default(), export_map: FxHashMap::default(), - trait_map: NodeMap(), + trait_map: Default::default(), module_map, - block_map: NodeMap(), + block_map: Default::default(), extern_module_map: FxHashMap::default(), binding_parent_modules: FxHashMap::default(), make_glob_map: make_glob_map == MakeGlobMap::Yes, - glob_map: NodeMap(), + glob_map: Default::default(), used_imports: FxHashSet::default(), - maybe_unused_trait_imports: NodeSet(), + maybe_unused_trait_imports: Default::default(), maybe_unused_extern_crates: Vec::new(), unused_labels: FxHashMap::default(), @@ -1907,7 +1907,7 @@ pub fn new(session: &'a Session, name_already_seen: FxHashMap::default(), whitelisted_legacy_custom_derives: Vec::new(), potentially_unused_imports: Vec::new(), - struct_constructors: DefIdMap(), + struct_constructors: Default::default(), found_unresolved_macro: false, unused_macros: FxHashSet::default(), current_type_ascription: Vec::new(), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index eed5d909063b..aabef5c32348 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -643,11 +643,11 @@ fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self { }, infcx, fulfillment_cx: RefCell::new(TraitEngine::new(tcx)), - locals: RefCell::new(NodeMap()), - deferred_call_resolutions: RefCell::new(DefIdMap()), + locals: RefCell::new(Default::default()), + deferred_call_resolutions: RefCell::new(Default::default()), deferred_cast_checks: RefCell::new(Vec::new()), deferred_generator_interiors: RefCell::new(Vec::new()), - opaque_types: RefCell::new(DefIdMap()), + opaque_types: RefCell::new(Default::default()), implicit_region_bound, body_id, } @@ -1986,7 +1986,7 @@ pub fn new(inh: &'a Inherited<'a, 'gcx, 'tcx>, has_errors: Cell::new(false), enclosing_breakables: RefCell::new(EnclosingBreakables { stack: Vec::new(), - by_id: NodeMap(), + by_id: Default::default(), }), inh, } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 4460d5f64ce2..50f54bba3fd2 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -56,7 +56,7 @@ pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::Type let used_trait_imports = mem::replace( &mut self.tables.borrow_mut().used_trait_imports, - Lrc::new(DefIdSet()), + Lrc::new(DefIdSet::default()), ); debug!( "used_trait_imports({:?}) = {:?}", diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 9d785dfb58ac..22a96d4e908c 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -24,7 +24,7 @@ use rustc_data_structures::fx::FxHashMap; pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { - let mut used_trait_imports = DefIdSet(); + let mut used_trait_imports = DefIdSet::default(); for &body_id in tcx.hir.krate().bodies.keys() { let item_def_id = tcx.hir.body_owner_def_id(body_id); let imports = tcx.used_trait_imports(item_def_id); diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 370f8857f140..79e4abc4c0e2 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -38,7 +38,7 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut collect = InherentCollect { tcx, impls_map: CrateInherentImpls { - inherent_impls: DefIdMap() + inherent_impls: DefIdMap::default() } }; krate.visit_all_item_likes(&mut collect); diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index 0aec31609b06..087d53b92d49 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -81,7 +81,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx> let mut terms_cx = TermsContext { tcx, arena, - inferred_starts: NodeMap(), + inferred_starts: Default::default(), inferred_terms: vec![], lang_items: lang_items(tcx), diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 24dd4cc13bfe..946c5c5fa9bc 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -25,7 +25,7 @@ /// Strip items marked `#[doc(hidden)]` pub fn strip_hidden(krate: clean::Crate, _: &DocContext) -> clean::Crate { - let mut retained = DefIdSet(); + let mut retained = DefIdSet::default(); // strip all #[doc(hidden)] items let krate = { diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index 46d0034497e2..e9d927398e44 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -24,7 +24,7 @@ /// crate, specified by the `xcrate` flag. pub fn strip_private(mut krate: clean::Crate, cx: &DocContext) -> clean::Crate { // This stripper collects all *retained* nodes. - let mut retained = DefIdSet(); + let mut retained = DefIdSet::default(); let access_levels = cx.renderinfo.borrow().access_levels.clone(); // strip all private items From 7683180be5b51bb626e0cf372a3dee31cab8b61c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 25 Jul 2018 15:44:06 +0300 Subject: [PATCH 48/75] rustc: implement and use Default on more types. --- src/Cargo.lock | 11 ++++++++- src/librustc/dep_graph/graph.rs | 4 ++-- src/librustc/hir/map/definitions.rs | 19 ++++----------- src/librustc/ich/hcx.rs | 3 +-- src/librustc/infer/region_constraints/mod.rs | 14 +++-------- src/librustc/lint/context.rs | 2 +- src/librustc/lint/mod.rs | 5 +--- src/librustc/middle/borrowck.rs | 8 ++++++- src/librustc/middle/resolve_lifetime.rs | 9 +++----- src/librustc/session/mod.rs | 2 +- src/librustc/ty/mod.rs | 2 +- .../back/symbol_export.rs | 2 +- src/librustc_data_structures/Cargo.toml | 2 +- .../snapshot_map/mod.rs | 23 ++++++++++--------- .../transitive_relation.rs | 23 ++++++++++--------- .../coherence/inherent_impls.rs | 5 +--- 16 files changed, 61 insertions(+), 73 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index e7b42a038a3b..0dd693e7217e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -659,6 +659,14 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ena" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "env_logger" version = "0.5.12" @@ -2196,7 +2204,7 @@ name = "rustc_data_structures" version = "0.0.0" dependencies = [ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ena 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3261,6 +3269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum elasticlunr-rs 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4837d77a1e157489a3933b743fd774ae75074e0e390b2b7f071530048a0d87ee" +"checksum ena 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25b4e5febb25f08c49f1b07dc33a182729a6b21edfb562b5aef95f78e0dbe5bb" "checksum ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dc8393b3c7352f94092497f6b52019643e493b6b890eb417cdb7c46117e621" "checksum env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)" = "f4d7e69c283751083d53d01eac767407343b8b69c4bd70058e08adc2637cb257" "checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index ddc5676c74eb..63b749c548e2 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -101,11 +101,11 @@ pub fn new(prev_graph: PreviousDepGraph, DepGraph { data: Some(Lrc::new(DepGraphData { previous_work_products: prev_work_products, - dep_node_debug: Lock::new(Default::default()), + dep_node_debug: Default::default(), current: Lock::new(CurrentDepGraph::new()), previous: prev_graph, colors: Lock::new(DepNodeColorMap::new(prev_graph_node_count)), - loaded_from_cache: Lock::new(Default::default()), + loaded_from_cache: Default::default(), })), fingerprints: Lrc::new(Lock::new(fingerprints)), } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 6be7444136e2..eb9bd183fd93 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -36,6 +36,7 @@ /// Internally the DefPathTable holds a tree of DefKeys, where each DefKey /// stores the DefIndex of its parent. /// There is one DefPathTable for each crate. +#[derive(Default)] pub struct DefPathTable { index_to_key: [Vec; 2], def_path_hashes: [Vec; 2], @@ -153,7 +154,7 @@ fn decode(d: &mut D) -> Result { /// The definition table containing node definitions. /// It holds the DefPathTable for local DefIds/DefPaths and it also stores a /// mapping from NodeIds to local DefIds. -#[derive(Clone)] +#[derive(Clone, Default)] pub struct Definitions { table: DefPathTable, node_to_def_index: NodeMap, @@ -412,20 +413,8 @@ impl Definitions { /// ascending order. /// /// FIXME: there is probably a better place to put this comment. - pub fn new() -> Definitions { - Definitions { - table: DefPathTable { - index_to_key: [vec![], vec![]], - def_path_hashes: [vec![], vec![]], - }, - node_to_def_index: Default::default(), - def_index_to_node: [vec![], vec![]], - node_to_hir_id: IndexVec::new(), - parent_modules_of_macro_defs: Default::default(), - expansions_that_defined: Default::default(), - next_disambiguator: Default::default(), - def_index_to_span: Default::default(), - } + pub fn new() -> Self { + Self::default() } pub fn def_path_table(&self) -> &DefPathTable { diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 1c7c1b854da4..7c623a1874e7 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -369,8 +369,7 @@ fn hash_stable(&self, // times, we cache a stable hash of it and hash that instead of // recursing every time. thread_local! { - static CACHE: RefCell> = - RefCell::new(Default::default()); + static CACHE: RefCell> = Default::default(); } let sub_hash: u64 = CACHE.with(|cache| { diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 46b12d01829e..391bfc428c3b 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -29,6 +29,7 @@ mod taint; +#[derive(Default)] pub struct RegionConstraintCollector<'tcx> { /// For each `RegionVid`, the corresponding `RegionVariableOrigin`. var_infos: IndexVec, @@ -341,17 +342,8 @@ pub fn both() -> Self { } impl<'tcx> RegionConstraintCollector<'tcx> { - pub fn new() -> RegionConstraintCollector<'tcx> { - RegionConstraintCollector { - var_infos: VarInfos::default(), - data: RegionConstraintData::default(), - lubs: Default::default(), - glbs: Default::default(), - bound_count: 0, - undo_log: Vec::new(), - unification_table: ut::UnificationTable::new(), - any_unifications: false, - } + pub fn new() -> Self { + Self::default() } pub fn num_region_vars(&self) -> usize { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 8acbaaa844d7..469d77403a3d 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1233,7 +1233,7 @@ pub fn check_ast_crate( let (passes, buffered) = if pre_expansion { ( sess.lint_store.borrow_mut().pre_expansion_passes.take(), - LintBuffer::new(), + LintBuffer::default(), ) } else { ( diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index c43cdb24c339..4b878b862526 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -490,15 +490,12 @@ pub enum LintSource { pub use self::levels::{LintLevelSets, LintLevelMap}; +#[derive(Default)] pub struct LintBuffer { map: NodeMap>, } impl LintBuffer { - pub fn new() -> LintBuffer { - LintBuffer { map: ::std::default::Default::default() } - } - pub fn add_lint(&mut self, lint: &'static Lint, id: ast::NodeId, diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs index c8d513a59f00..633c58413780 100644 --- a/src/librustc/middle/borrowck.rs +++ b/src/librustc/middle/borrowck.rs @@ -18,9 +18,15 @@ #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub enum SignalledError { SawSomeError, NoErrorsSeen } +impl Default for SignalledError { + fn default() -> SignalledError { + SignalledError::NoErrorsSeen + } +} + impl_stable_hash_for!(enum self::SignalledError { SawSomeError, NoErrorsSeen }); -#[derive(Debug, RustcEncodable, RustcDecodable)] +#[derive(Debug, Default, RustcEncodable, RustcDecodable)] pub struct BorrowCheckResult { pub used_mut_nodes: FxHashSet, pub signalled_any_error: SignalledError, diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index b7f4e3808159..6ff450508d13 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2741,9 +2741,7 @@ fn insert_late_bound_lifetimes( constrained_by_input.visit_ty(arg_ty); } - let mut appears_in_output = AllCollector { - regions: Default::default(), - }; + let mut appears_in_output = AllCollector::default(); intravisit::walk_fn_ret_ty(&mut appears_in_output, &decl.output); debug!( @@ -2755,9 +2753,7 @@ fn insert_late_bound_lifetimes( // // Subtle point: because we disallow nested bindings, we can just // ignore binders here and scrape up all names we see. - let mut appears_in_where_clause = AllCollector { - regions: Default::default(), - }; + let mut appears_in_where_clause = AllCollector::default(); appears_in_where_clause.visit_generics(generics); for param in &generics.params { @@ -2854,6 +2850,7 @@ fn visit_lifetime(&mut self, lifetime_ref: &'v hir::Lifetime) { } } + #[derive(Default)] struct AllCollector { regions: FxHashSet, } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 8582900b72c8..d688d93b8084 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -1149,7 +1149,7 @@ pub fn build_session_( local_crate_source_file, working_dir, lint_store: RwLock::new(lint::LintStore::new()), - buffered_lints: Lock::new(Some(lint::LintBuffer::new())), + buffered_lints: Lock::new(Some(Default::default())), one_time_diagnostics: Default::default(), plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())), plugin_attributes: OneThread::new(RefCell::new(Vec::new())), diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index dfdffa2d5478..ad200449f890 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3183,7 +3183,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { /// rather, you should request the vector for a specific type via /// `tcx.inherent_impls(def_id)` so as to minimize your dependencies /// (constructing this map requires touching the entire crate). -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct CrateInherentImpls { pub inherent_impls: DefIdMap>>, } diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index 10dd1de8b784..0463da00c89d 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -64,7 +64,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, assert_eq!(cnum, LOCAL_CRATE); if !tcx.sess.opts.output_types.should_codegen() { - return Lrc::new(Default::default()) + return Default::default(); } // Check to see if this crate is a "special runtime crate". These diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 79f073d643dd..5b3dd38adf23 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -9,7 +9,7 @@ path = "lib.rs" crate-type = ["dylib"] [dependencies] -ena = "0.9.3" +ena = "0.10.1" log = "0.4" rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } serialize = { path = "../libserialize" } diff --git a/src/librustc_data_structures/snapshot_map/mod.rs b/src/librustc_data_structures/snapshot_map/mod.rs index f8663cd4fd43..0b42cb1eddde 100644 --- a/src/librustc_data_structures/snapshot_map/mod.rs +++ b/src/librustc_data_structures/snapshot_map/mod.rs @@ -23,6 +23,18 @@ pub struct SnapshotMap undo_log: Vec>, } +// HACK(eddyb) manual impl avoids `Default` bounds on `K` and `V`. +impl Default for SnapshotMap + where K: Hash + Clone + Eq +{ + fn default() -> Self { + SnapshotMap { + map: Default::default(), + undo_log: Default::default(), + } + } +} + pub struct Snapshot { len: usize, } @@ -35,17 +47,6 @@ enum UndoLog { Noop, } -impl Default for SnapshotMap - where K: Hash + Clone + Eq -{ - fn default() -> Self { - SnapshotMap { - map: FxHashMap::default(), - undo_log: vec![], - } - } -} - impl SnapshotMap where K: Hash + Clone + Eq { diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index e1318eb54d58..fd5dfab9e61b 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -42,6 +42,18 @@ pub struct TransitiveRelation { closure: Lock>>, } +// HACK(eddyb) manual impl avoids `Default` bound on `T`. +impl Default for TransitiveRelation { + fn default() -> Self { + TransitiveRelation { + elements: Default::default(), + map: Default::default(), + edges: Default::default(), + closure: Default::default(), + } + } +} + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] struct Index(usize); @@ -51,17 +63,6 @@ struct Edge { target: Index, } -impl Default for TransitiveRelation { - fn default() -> TransitiveRelation { - TransitiveRelation { - elements: vec![], - map: FxHashMap::default(), - edges: vec![], - closure: Lock::new(None), - } - } -} - impl TransitiveRelation { pub fn is_empty(&self) -> bool { self.edges.is_empty() diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 79e4abc4c0e2..d9dff1441296 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -22,7 +22,6 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::{self, CrateInherentImpls, TyCtxt}; -use rustc::util::nodemap::DefIdMap; use rustc_data_structures::sync::Lrc; use syntax::ast; @@ -37,9 +36,7 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let krate = tcx.hir.krate(); let mut collect = InherentCollect { tcx, - impls_map: CrateInherentImpls { - inherent_impls: DefIdMap::default() - } + impls_map: Default::default(), }; krate.visit_all_item_likes(&mut collect); Lrc::new(collect.impls_map) From 9e2e57511f13569c8e9de910c04540ad1b93a321 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 19 Nov 2018 15:05:28 +0530 Subject: [PATCH 49/75] Add x86_64-fortanix-unknown-sgx target to the compiler --- src/librustc_target/spec/mod.rs | 2 + .../spec/x86_64_fortanix_unknown_sgx.rs | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 57bbf6b02608..986607e9ca76 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -412,6 +412,8 @@ fn $module() { ("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf), ("aarch64-unknown-none", aarch64_unknown_none), + + ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx), } /// Everything `rustc` knows about how to compile for a specific target. diff --git a/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs new file mode 100644 index 000000000000..07383b3d6486 --- /dev/null +++ b/src/librustc_target/spec/x86_64_fortanix_unknown_sgx.rs @@ -0,0 +1,72 @@ +// 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::iter; + +use super::{LinkerFlavor, Target, TargetOptions, PanicStrategy}; + +pub fn target() -> Result { + const PRE_LINK_ARGS: &[&str] = &[ + "-Wl,--as-needed", + "-Wl,-z,noexecstack", + "-m64", + "-fuse-ld=gold", + "-nostdlib", + "-shared", + "-Wl,-e,sgx_entry", + "-Wl,-Bstatic", + "-Wl,--gc-sections", + "-Wl,-z,text", + "-Wl,-z,norelro", + "-Wl,--rosegment", + "-Wl,--no-undefined", + "-Wl,--error-unresolved-symbols", + "-Wl,--no-undefined-version", + "-Wl,-Bsymbolic", + "-Wl,--export-dynamic", + ]; + const EXPORT_SYMBOLS: &[&str] = &[ + "sgx_entry", + "HEAP_BASE", + "HEAP_SIZE", + "RELA", + "RELACOUNT", + "ENCLAVE_SIZE", + "CFGDATA_BASE", + "DEBUG", + ]; + let opts = TargetOptions { + dynamic_linking: false, + executables: true, + linker_is_gnu: true, + max_atomic_width: Some(64), + panic_strategy: PanicStrategy::Abort, + cpu: "x86-64".into(), + position_independent_executables: true, + pre_link_args: iter::once( + (LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect()) + ).collect(), + override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()), + ..Default::default() + }; + Ok(Target { + llvm_target: "x86_64-unknown-linux-gnu".into(), + target_endian: "little".into(), + target_pointer_width: "64".into(), + target_c_int_width: "32".into(), + target_os: "unknown".into(), + target_env: "sgx".into(), + target_vendor: "fortanix".into(), + data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + linker_flavor: LinkerFlavor::Gcc, + options: opts, + }) +} From e538a4a7debaff6627c11f4a5d2cb29beea0b336 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Tue, 13 Nov 2018 13:54:51 +0100 Subject: [PATCH 50/75] core/benches/num: Add `from_str/from_str_radix()` benchmarks --- src/libcore/benches/num/mod.rs | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/libcore/benches/num/mod.rs b/src/libcore/benches/num/mod.rs index 55f0bdb57ec8..b57e167b05d9 100644 --- a/src/libcore/benches/num/mod.rs +++ b/src/libcore/benches/num/mod.rs @@ -10,3 +10,108 @@ mod flt2dec; mod dec2flt; + +use test::Bencher; +use std::str::FromStr; + +const ASCII_NUMBERS: [&str; 19] = [ + "0", + "1", + "2", + "43", + "765", + "76567", + "987245987", + "-4aa32", + "1786235", + "8723095", + "f##5s", + "83638730", + "-2345", + "562aa43", + "-1", + "-0", + "abc", + "xyz", + "c0ffee", +]; + +macro_rules! from_str_bench { + ($mac:ident, $t:ty) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str(s).ok()) + .max() + }) + } + ) +} + +macro_rules! from_str_radix_bench { + ($mac:ident, $t:ty, $radix:expr) => ( + #[bench] + fn $mac(b: &mut Bencher) { + b.iter(|| { + ASCII_NUMBERS + .iter() + .cycle() + .take(5_000) + .filter_map(|s| <($t)>::from_str_radix(s, $radix).ok()) + .max() + }) + } + ) +} + +from_str_bench!(bench_u8_from_str, u8); +from_str_radix_bench!(bench_u8_from_str_radix_2, u8, 2); +from_str_radix_bench!(bench_u8_from_str_radix_10, u8, 10); +from_str_radix_bench!(bench_u8_from_str_radix_16, u8, 16); +from_str_radix_bench!(bench_u8_from_str_radix_36, u8, 36); + +from_str_bench!(bench_u16_from_str, u16); +from_str_radix_bench!(bench_u16_from_str_radix_2, u16, 2); +from_str_radix_bench!(bench_u16_from_str_radix_10, u16, 10); +from_str_radix_bench!(bench_u16_from_str_radix_16, u16, 16); +from_str_radix_bench!(bench_u16_from_str_radix_36, u16, 36); + +from_str_bench!(bench_u32_from_str, u32); +from_str_radix_bench!(bench_u32_from_str_radix_2, u32, 2); +from_str_radix_bench!(bench_u32_from_str_radix_10, u32, 10); +from_str_radix_bench!(bench_u32_from_str_radix_16, u32, 16); +from_str_radix_bench!(bench_u32_from_str_radix_36, u32, 36); + +from_str_bench!(bench_u64_from_str, u64); +from_str_radix_bench!(bench_u64_from_str_radix_2, u64, 2); +from_str_radix_bench!(bench_u64_from_str_radix_10, u64, 10); +from_str_radix_bench!(bench_u64_from_str_radix_16, u64, 16); +from_str_radix_bench!(bench_u64_from_str_radix_36, u64, 36); + +from_str_bench!(bench_i8_from_str, i8); +from_str_radix_bench!(bench_i8_from_str_radix_2, i8, 2); +from_str_radix_bench!(bench_i8_from_str_radix_10, i8, 10); +from_str_radix_bench!(bench_i8_from_str_radix_16, i8, 16); +from_str_radix_bench!(bench_i8_from_str_radix_36, i8, 36); + +from_str_bench!(bench_i16_from_str, i16); +from_str_radix_bench!(bench_i16_from_str_radix_2, i16, 2); +from_str_radix_bench!(bench_i16_from_str_radix_10, i16, 10); +from_str_radix_bench!(bench_i16_from_str_radix_16, i16, 16); +from_str_radix_bench!(bench_i16_from_str_radix_36, i16, 36); + +from_str_bench!(bench_i32_from_str, i32); +from_str_radix_bench!(bench_i32_from_str_radix_2, i32, 2); +from_str_radix_bench!(bench_i32_from_str_radix_10, i32, 10); +from_str_radix_bench!(bench_i32_from_str_radix_16, i32, 16); +from_str_radix_bench!(bench_i32_from_str_radix_36, i32, 36); + +from_str_bench!(bench_i64_from_str, i64); +from_str_radix_bench!(bench_i64_from_str_radix_2, i64, 2); +from_str_radix_bench!(bench_i64_from_str_radix_10, i64, 10); +from_str_radix_bench!(bench_i64_from_str_radix_16, i64, 16); +from_str_radix_bench!(bench_i64_from_str_radix_36, i64, 36); From d7b3f5c6aeedf07c6a0ea4d5a79a106642488e0d Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 20 Nov 2018 19:49:47 -0500 Subject: [PATCH 51/75] update various stdlib docs --- src/liballoc/rc.rs | 5 ++--- src/liballoc/sync.rs | 5 ++--- src/libcore/char/convert.rs | 6 ++---- src/libcore/mem.rs | 15 +++++---------- src/libcore/ptr.rs | 2 +- src/libcore/raw.rs | 6 +----- src/libstd/lib.rs | 4 ++-- src/libstd/macros.rs | 11 +++++------ src/libstd/primitive_docs.rs | 5 ++--- 9 files changed, 22 insertions(+), 37 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index bb52d7990ff5..705345ce963b 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -43,8 +43,8 @@ //! //! `Rc` automatically dereferences to `T` (via the [`Deref`] trait), //! so you can call `T`'s methods on a value of type [`Rc`][`Rc`]. To avoid name -//! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are [associated -//! functions][assoc], called using function-like syntax: +//! clashes with `T`'s methods, the methods of [`Rc`][`Rc`] itself are associated +//! functions, called using function-like syntax: //! //! ``` //! use std::rc::Rc; @@ -234,7 +234,6 @@ //! [downgrade]: struct.Rc.html#method.downgrade //! [upgrade]: struct.Weak.html#method.upgrade //! [`None`]: ../../std/option/enum.Option.html#variant.None -//! [assoc]: ../../book/first-edition/method-syntax.html#associated-functions //! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable #![stable(feature = "rust1", since = "1.0.0")] diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index b63b3684964b..4f4031e3c4e3 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -120,8 +120,8 @@ /// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), /// so you can call `T`'s methods on a value of type `Arc`. To avoid name -/// clashes with `T`'s methods, the methods of `Arc` itself are [associated -/// functions][assoc], called using function-like syntax: +/// clashes with `T`'s methods, the methods of `Arc` itself are associated +/// functions, called using function-like syntax: /// /// ``` /// use std::sync::Arc; @@ -146,7 +146,6 @@ /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade /// [`None`]: ../../std/option/enum.Option.html#variant.None -/// [assoc]: ../../book/first-edition/method-syntax.html#associated-functions /// [`RefCell`]: ../../std/cell/struct.RefCell.html /// [`std::sync`]: ../../std/sync/index.html /// [`Arc::clone(&from)`]: #method.clone diff --git a/src/libcore/char/convert.rs b/src/libcore/char/convert.rs index e9ccdd0ea3c5..160728f923db 100644 --- a/src/libcore/char/convert.rs +++ b/src/libcore/char/convert.rs @@ -19,7 +19,7 @@ /// Converts a `u32` to a `char`. /// /// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with -/// [`as`]: +/// `as`: /// /// ``` /// let c = '💯'; @@ -34,7 +34,6 @@ /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// For an unsafe version of this function which ignores these checks, see /// [`from_u32_unchecked`]. @@ -71,7 +70,7 @@ pub fn from_u32(i: u32) -> Option { /// Converts a `u32` to a `char`, ignoring validity. /// /// Note that all [`char`]s are valid [`u32`]s, and can be cast to one with -/// [`as`]: +/// `as`: /// /// ``` /// let c = '💯'; @@ -86,7 +85,6 @@ pub fn from_u32(i: u32) -> Option { /// /// [`char`]: ../../std/primitive.char.html /// [`u32`]: ../../std/primitive.u32.html -/// [`as`]: ../../book/first-edition/casting-between-types.html#as /// /// # Safety /// diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index d8eec2bd9a6a..6b2d878b3e7b 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -132,7 +132,6 @@ /// [uninit]: fn.uninitialized.html /// [clone]: ../clone/trait.Clone.html /// [swap]: fn.swap.html -/// [FFI]: ../../book/first-edition/ffi.html /// [box]: ../../std/boxed/struct.Box.html /// [leak]: ../../std/boxed/struct.Box.html#method.leak /// [into_raw]: ../../std/boxed/struct.Box.html#method.into_raw @@ -479,7 +478,7 @@ pub const fn needs_drop() -> bool { /// /// This has the same effect as allocating space with /// [`mem::uninitialized`][uninit] and then zeroing it out. It is useful for -/// [FFI] sometimes, but should generally be avoided. +/// FFI sometimes, but should generally be avoided. /// /// There is no guarantee that an all-zero byte-pattern represents a valid value of /// some type `T`. If `T` has a destructor and the value is destroyed (due to @@ -490,7 +489,6 @@ pub const fn needs_drop() -> bool { /// many of the same caveats. /// /// [uninit]: fn.uninitialized.html -/// [FFI]: ../../book/first-edition/ffi.html /// [ub]: ../../reference/behavior-considered-undefined.html /// /// # Examples @@ -514,11 +512,9 @@ pub unsafe fn zeroed() -> T { /// **This is incredibly dangerous and should not be done lightly. Deeply /// consider initializing your memory with a default value instead.** /// -/// This is useful for [FFI] functions and initializing arrays sometimes, +/// This is useful for FFI functions and initializing arrays sometimes, /// but should generally be avoided. /// -/// [FFI]: ../../book/first-edition/ffi.html -/// /// # Undefined behavior /// /// It is [undefined behavior][ub] to read uninitialized memory, even just an @@ -689,10 +685,9 @@ pub fn replace(dest: &mut T, mut src: T) -> T { /// While this does call the argument's implementation of [`Drop`][drop], /// it will not release any borrows, as borrows are based on lexical scope. /// -/// This effectively does nothing for -/// [types which implement `Copy`](../../book/first-edition/ownership.html#copy-types), -/// e.g. integers. Such values are copied and _then_ moved into the function, -/// so the value persists after this function call. +/// This effectively does nothing for types which implement `Copy`, e.g. +/// integers. Such values are copied and _then_ moved into the function, so the +/// value persists after this function call. /// /// This function is not magic; it is literally defined as /// diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a7bfc3f51244..e9cf11424cae 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -58,7 +58,7 @@ //! [`NonNull::dangling`] in such cases. //! //! [aliasing]: ../../nomicon/aliasing.html -//! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer +//! [book]: ../../book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer //! [ub]: ../../reference/behavior-considered-undefined.html //! [null]: ./fn.null.html //! [zst]: ../../nomicon/exotic-sizes.html#zero-sized-types-zsts diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index a95f05227fb8..495b9afe8602 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -21,11 +21,7 @@ /// The representation of a trait object like `&SomeTrait`. /// /// This struct has the same layout as types like `&SomeTrait` and -/// `Box`. The [Trait Objects chapter of the -/// Book][moreinfo] contains more details about the precise nature of -/// these internals. -/// -/// [moreinfo]: ../../book/first-edition/trait-objects.html#representation +/// `Box`. /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g. the fields are not directly accessible diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index eb7caa61972f..575903d576a2 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -185,7 +185,7 @@ //! [slice]: primitive.slice.html //! [`atomic`]: sync/atomic/index.html //! [`collections`]: collections/index.html -/// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for +//! [`for`]: ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for //! [`format!`]: macro.format.html //! [`fs`]: fs/index.html //! [`io`]: io/index.html @@ -200,7 +200,7 @@ //! [`sync`]: sync/index.html //! [`thread`]: thread/index.html //! [`use std::env`]: env/index.html -//! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#use-to-bring-paths-into-scope +//! [`use`]: ../book/ch07-02-modules-and-use-to-control-scope-and-privacy.html#the-use-keyword-to-bring-paths-into-a-scope //! [crate root]: ../book/ch07-01-packages-and-crates-for-making-libraries-and-executables.html //! [crates.io]: https://crates.io //! [deref-coercions]: ../book/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 15fbb1059213..0995ab3c373c 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -32,7 +32,7 @@ /// /// [`Result`] enum is often a better solution for recovering from errors than /// using the `panic!` macro. This macro should be used to avoid proceeding using -/// incorrect values, such as from external sources. Detailed information about +/// incorrect values, such as from external sources. Detailed information about /// error handling is found in the [book]. /// /// The multi-argument form of this macro panics with a string and has the @@ -45,7 +45,7 @@ /// [`Result`]: ../std/result/enum.Result.html /// [`format!`]: ../std/macro.format.html /// [`compile_error!`]: ../std/macro.compile_error.html -/// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html +/// [book]: ../book/ch09-00-error-handling.html /// /// # Current implementation /// @@ -839,8 +839,8 @@ macro_rules! module_path { () => ({ /* compiler built-in */ }) } /// boolean expression evaluation of configuration flags. This frequently /// leads to less duplicated code. /// - /// The syntax given to this macro is the same syntax as [the `cfg` - /// attribute](../book/first-edition/conditional-compilation.html). + /// The syntax given to this macro is the same syntax as the `cfg` + /// attribute. /// /// # Examples /// @@ -915,7 +915,7 @@ macro_rules! include { /// 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 + /// Other use-cases of `assert!` include testing and enforcing run-time /// invariants in safe code (whose violation cannot result in unsafety). /// /// # Custom Messages @@ -926,7 +926,6 @@ macro_rules! include { /// /// [`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 diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index c2a16122a0dd..48acc1096a68 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -22,7 +22,7 @@ /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc., /// which allow us to perform boolean operations using `&`, `|` and `!`. /// -/// [`if`] always demands a `bool` value. [`assert!`], being an important macro in testing, +/// `if` always demands a `bool` value. [`assert!`], being an important macro in testing, /// checks whether an expression returns `true`. /// /// ``` @@ -31,7 +31,6 @@ /// ``` /// /// [`assert!`]: macro.assert.html -/// [`if`]: ../book/first-edition/if.html /// [`BitAnd`]: ops/trait.BitAnd.html /// [`BitOr`]: ops/trait.BitOr.html /// [`Not`]: ops/trait.Not.html @@ -695,7 +694,7 @@ mod prim_str { } /// assert_eq!(tuple.2, 'c'); /// ``` /// -/// For more about tuples, see [the book](../book/first-edition/primitive-types.html#tuples). +/// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type). /// /// # Trait implementations /// From 33efce1c2f280848a84b94f99ea1bc874e189a37 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 21 Nov 2018 14:27:30 +0100 Subject: [PATCH 52/75] Forward rust version number to tools Clippy uses it to identify the correct documentation to point to --- src/bootstrap/tool.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 978e3602e7db..d8e86644ee05 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -22,6 +22,7 @@ use compile; use native; use channel::GitInfo; +use channel; use cache::Interned; use toolstate::ToolState; @@ -240,6 +241,7 @@ pub fn prepare_tool_cargo( cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel); cargo.env("CFG_VERSION", builder.rust_version()); + cargo.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM); let info = GitInfo::new(&builder.config, &dir); if let Some(sha) = info.sha() { From d0a174d41b230dc2cb08a902c2ecca0d89ee7856 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 13:35:14 -0500 Subject: [PATCH 53/75] track the span for each id so that we can give a nice ICE --- src/librustc/hir/map/collector.rs | 64 ++++++++++++++++++------------- src/librustc/hir/map/mod.rs | 4 +- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 4fbcd83adb55..2917fd7457ac 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -28,6 +28,10 @@ pub(super) struct NodeCollector<'a, 'hir> { /// The crate krate: &'hir Crate, + + /// Source map + source_map: &'a SourceMap, + /// The node map map: Vec>>, /// The parent of this node @@ -54,7 +58,8 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { pub(super) fn root(krate: &'hir Crate, dep_graph: &'a DepGraph, definitions: &'a definitions::Definitions, - hcx: StableHashingContext<'a>) + hcx: StableHashingContext<'a>, + source_map: &'a SourceMap) -> NodeCollector<'a, 'hir> { let root_mod_def_path_hash = definitions.def_path_hash(CRATE_DEF_INDEX); @@ -102,6 +107,7 @@ pub(super) fn root(krate: &'hir Crate, let mut collector = NodeCollector { krate, + source_map, map: vec![], parent_node: CRATE_NODE_ID, current_signature_dep_index: root_mod_sig_dep_index, @@ -125,7 +131,6 @@ pub(super) fn root(krate: &'hir Crate, pub(super) fn finalize_and_compute_crate_hash(mut self, crate_disambiguator: CrateDisambiguator, cstore: &dyn CrateStore, - source_map: &SourceMap, commandline_args_hash: u64) -> (Vec>>, Svh) { @@ -154,7 +159,8 @@ pub(super) fn finalize_and_compute_crate_hash(mut self, // If we included the full mapping in the SVH, we could only have // reproducible builds by compiling from the same directory. So we just // hash the result of the mapping instead of the mapping itself. - let mut source_file_names: Vec<_> = source_map + let mut source_file_names: Vec<_> = self + .source_map .files() .iter() .filter(|source_file| CrateNum::from_u32(source_file.crate_of_origin) == LOCAL_CRATE) @@ -186,7 +192,7 @@ fn insert_entry(&mut self, id: NodeId, entry: Entry<'hir>) { self.map[id.as_usize()] = Some(entry); } - fn insert(&mut self, id: NodeId, node: Node<'hir>) { + fn insert(&mut self, span: Span, id: NodeId, node: Node<'hir>) { let entry = Entry { parent: self.parent_node, dep_node: if self.currently_in_body { @@ -216,8 +222,11 @@ fn insert(&mut self, id: NodeId, node: Node<'hir>) { String::new() }; - bug!("inconsistent DepNode for `{}`: \ - current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}", + span_bug!( + span, + "inconsistent DepNode at `{:?}` for `{}`: \ + current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}){}", + self.source_map.span_to_string(span), node_str, self.definitions .def_path(self.current_dep_node_owner) @@ -225,7 +234,8 @@ fn insert(&mut self, id: NodeId, node: Node<'hir>) { self.current_dep_node_owner, self.definitions.def_path(hir_id.owner).to_string_no_crate(), hir_id.owner, - forgot_str) + forgot_str, + ) } } @@ -309,12 +319,12 @@ fn visit_item(&mut self, i: &'hir Item) { debug_assert_eq!(i.hir_id.owner, self.definitions.opt_def_index(i.id).unwrap()); self.with_dep_node_owner(i.hir_id.owner, i, |this| { - this.insert(i.id, Node::Item(i)); + this.insert(i.span, i.id, Node::Item(i)); this.with_parent(i.id, |this| { if let ItemKind::Struct(ref struct_def, _) = i.node { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { - this.insert(struct_def.id(), Node::StructCtor(struct_def)); + this.insert(i.span, struct_def.id(), Node::StructCtor(struct_def)); } } intravisit::walk_item(this, i); @@ -323,7 +333,7 @@ fn visit_item(&mut self, i: &'hir Item) { } fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem) { - self.insert(foreign_item.id, Node::ForeignItem(foreign_item)); + self.insert(foreign_item.span, foreign_item.id, Node::ForeignItem(foreign_item)); self.with_parent(foreign_item.id, |this| { intravisit::walk_foreign_item(this, foreign_item); @@ -331,7 +341,7 @@ fn visit_foreign_item(&mut self, foreign_item: &'hir ForeignItem) { } fn visit_generic_param(&mut self, param: &'hir GenericParam) { - self.insert(param.id, Node::GenericParam(param)); + self.insert(param.span, param.id, Node::GenericParam(param)); intravisit::walk_generic_param(self, param); } @@ -339,7 +349,7 @@ fn visit_trait_item(&mut self, ti: &'hir TraitItem) { debug_assert_eq!(ti.hir_id.owner, self.definitions.opt_def_index(ti.id).unwrap()); self.with_dep_node_owner(ti.hir_id.owner, ti, |this| { - this.insert(ti.id, Node::TraitItem(ti)); + this.insert(ti.span, ti.id, Node::TraitItem(ti)); this.with_parent(ti.id, |this| { intravisit::walk_trait_item(this, ti); @@ -351,7 +361,7 @@ fn visit_impl_item(&mut self, ii: &'hir ImplItem) { debug_assert_eq!(ii.hir_id.owner, self.definitions.opt_def_index(ii.id).unwrap()); self.with_dep_node_owner(ii.hir_id.owner, ii, |this| { - this.insert(ii.id, Node::ImplItem(ii)); + this.insert(ii.span, ii.id, Node::ImplItem(ii)); this.with_parent(ii.id, |this| { intravisit::walk_impl_item(this, ii); @@ -365,7 +375,7 @@ fn visit_pat(&mut self, pat: &'hir Pat) { } else { Node::Pat(pat) }; - self.insert(pat.id, node); + self.insert(pat.span, pat.id, node); self.with_parent(pat.id, |this| { intravisit::walk_pat(this, pat); @@ -373,7 +383,7 @@ fn visit_pat(&mut self, pat: &'hir Pat) { } fn visit_anon_const(&mut self, constant: &'hir AnonConst) { - self.insert(constant.id, Node::AnonConst(constant)); + self.insert(DUMMY_SP, constant.id, Node::AnonConst(constant)); self.with_parent(constant.id, |this| { intravisit::walk_anon_const(this, constant); @@ -381,7 +391,7 @@ fn visit_anon_const(&mut self, constant: &'hir AnonConst) { } fn visit_expr(&mut self, expr: &'hir Expr) { - self.insert(expr.id, Node::Expr(expr)); + self.insert(expr.span, expr.id, Node::Expr(expr)); self.with_parent(expr.id, |this| { intravisit::walk_expr(this, expr); @@ -390,7 +400,7 @@ fn visit_expr(&mut self, expr: &'hir Expr) { fn visit_stmt(&mut self, stmt: &'hir Stmt) { let id = stmt.node.id(); - self.insert(id, Node::Stmt(stmt)); + self.insert(stmt.span, id, Node::Stmt(stmt)); self.with_parent(id, |this| { intravisit::walk_stmt(this, stmt); @@ -399,13 +409,13 @@ fn visit_stmt(&mut self, stmt: &'hir Stmt) { fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment) { if let Some(id) = path_segment.id { - self.insert(id, Node::PathSegment(path_segment)); + self.insert(path_span, id, Node::PathSegment(path_segment)); } intravisit::walk_path_segment(self, path_span, path_segment); } fn visit_ty(&mut self, ty: &'hir Ty) { - self.insert(ty.id, Node::Ty(ty)); + self.insert(ty.span, ty.id, Node::Ty(ty)); self.with_parent(ty.id, |this| { intravisit::walk_ty(this, ty); @@ -413,7 +423,7 @@ fn visit_ty(&mut self, ty: &'hir Ty) { } fn visit_trait_ref(&mut self, tr: &'hir TraitRef) { - self.insert(tr.ref_id, Node::TraitRef(tr)); + self.insert(tr.path.span, tr.ref_id, Node::TraitRef(tr)); self.with_parent(tr.ref_id, |this| { intravisit::walk_trait_ref(this, tr); @@ -427,21 +437,21 @@ fn visit_fn(&mut self, fk: intravisit::FnKind<'hir>, fd: &'hir FnDecl, } fn visit_block(&mut self, block: &'hir Block) { - self.insert(block.id, Node::Block(block)); + self.insert(block.span, block.id, Node::Block(block)); self.with_parent(block.id, |this| { intravisit::walk_block(this, block); }); } fn visit_local(&mut self, l: &'hir Local) { - self.insert(l.id, Node::Local(l)); + self.insert(l.span, l.id, Node::Local(l)); self.with_parent(l.id, |this| { intravisit::walk_local(this, l) }) } fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) { - self.insert(lifetime.id, Node::Lifetime(lifetime)); + self.insert(lifetime.span, lifetime.id, Node::Lifetime(lifetime)); } fn visit_vis(&mut self, visibility: &'hir Visibility) { @@ -450,7 +460,7 @@ fn visit_vis(&mut self, visibility: &'hir Visibility) { VisibilityKind::Crate(_) | VisibilityKind::Inherited => {} VisibilityKind::Restricted { id, .. } => { - self.insert(id, Node::Visibility(visibility)); + self.insert(visibility.span, id, Node::Visibility(visibility)); self.with_parent(id, |this| { intravisit::walk_vis(this, visibility); }); @@ -462,20 +472,20 @@ fn visit_macro_def(&mut self, macro_def: &'hir MacroDef) { let def_index = self.definitions.opt_def_index(macro_def.id).unwrap(); self.with_dep_node_owner(def_index, macro_def, |this| { - this.insert(macro_def.id, Node::MacroDef(macro_def)); + this.insert(macro_def.span, macro_def.id, Node::MacroDef(macro_def)); }); } fn visit_variant(&mut self, v: &'hir Variant, g: &'hir Generics, item_id: NodeId) { let id = v.node.data.id(); - self.insert(id, Node::Variant(v)); + self.insert(v.span, id, Node::Variant(v)); self.with_parent(id, |this| { intravisit::walk_variant(this, v, g, item_id); }); } fn visit_struct_field(&mut self, field: &'hir StructField) { - self.insert(field.id, Node::Field(field)); + self.insert(field.span, field.id, Node::Field(field)); self.with_parent(field.id, |this| { intravisit::walk_struct_field(this, field); }); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index cf7a7abf95a6..ef777abfbc41 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1032,14 +1032,14 @@ pub fn map_crate<'hir>(sess: &::session::Session, let mut collector = NodeCollector::root(&forest.krate, &forest.dep_graph, &definitions, - hcx); + hcx, + sess.source_map()); intravisit::walk_crate(&mut collector, &forest.krate); let crate_disambiguator = sess.local_crate_disambiguator(); let cmdline_args = sess.opts.dep_tracking_hash(); collector.finalize_and_compute_crate_hash(crate_disambiguator, cstore, - sess.source_map(), cmdline_args) }; From 40f80940035af4b44aa7846ed34abee71151d3ee Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 13:35:54 -0500 Subject: [PATCH 54/75] add some `debug!` into lowering --- src/librustc/hir/lowering.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7ac3b033437f..e4819d6fb1da 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1866,6 +1866,10 @@ fn lower_path_segment( } else { self.lower_node_id(segment.id) }; + debug!( + "lower_path_segment: ident={:?} original-id={:?} new-id={:?}", + segment.ident, segment.id, id, + ); hir::PathSegment::new( segment.ident, @@ -2955,6 +2959,9 @@ fn lower_use_tree( name: &mut Name, attrs: &hir::HirVec, ) -> hir::ItemKind { + debug!("lower_use_tree(tree={:?})", tree); + debug!("lower_use_tree: vis = {:?}", vis); + let path = &tree.prefix; let segments = prefix .segments @@ -4540,6 +4547,7 @@ fn lower_visibility( VisibilityKind::Public => hir::VisibilityKind::Public, VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), VisibilityKind::Restricted { ref path, id } => { + debug!("lower_visibility: restricted path id = {:?}", id); let lowered_id = if let Some(owner) = explicit_owner { self.lower_node_id_with_owner(id, owner) } else { From a0a47904d64031a7a24828d6ad368ea9da33082a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 13:36:11 -0500 Subject: [PATCH 55/75] renumber segment ids for visibilities whenever we clone them --- src/librustc/hir/lowering.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e4819d6fb1da..79d605c0035e 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3029,12 +3029,7 @@ fn lower_use_tree( hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => { let id = this.next_id(); - let mut path = path.clone(); - for seg in path.segments.iter_mut() { - if seg.id.is_some() { - seg.id = Some(this.next_id().node_id); - } - } + let path = this.renumber_segment_ids(path); hir::VisibilityKind::Restricted { path, id: id.node_id, @@ -3119,8 +3114,9 @@ fn lower_use_tree( hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited, hir::VisibilityKind::Restricted { ref path, id: _, hir_id: _ } => { let id = this.next_id(); + let path = this.renumber_segment_ids(path); hir::VisibilityKind::Restricted { - path: path.clone(), + path: path, id: id.node_id, hir_id: id.hir_id, } @@ -3154,6 +3150,20 @@ fn lower_use_tree( } } + /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated + /// many times in the HIR tree; for each occurrence, we need to assign distinct + /// node-ids. (See e.g. #56128.) + fn renumber_segment_ids(&mut self, path: &P) -> P { + debug!("renumber_segment_ids(path = {:?})", path); + let mut path = path.clone(); + for seg in path.segments.iter_mut() { + if seg.id.is_some() { + seg.id = Some(self.next_id().node_id); + } + } + path + } + fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem { let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); let trait_item_def_id = self.resolver.definitions().local_def_id(node_id); From 4687eebc287e6f715b237dbb15f6c734715b474a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 15:34:11 -0500 Subject: [PATCH 56/75] preserve the original visibility for the "list stem" node Without this, the `vis` does not wind up in the tree anywhere, and then we get ICEs because the node-ids it refers to are not present. The motivation seemed to be documentation, but `ListStem` HIR nodes are ignored in rustdoc, from what I can tell. --- src/librustc/hir/lowering.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 79d605c0035e..eec9d084d7e3 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3139,12 +3139,8 @@ fn lower_use_tree( }); } - // 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 def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err); let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None)); - *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); hir::ItemKind::Use(path, hir::UseKind::ListStem) } } From 2bd2fc9418ee986fd96c32308dc2ef0efcc7973d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 14:20:03 -0500 Subject: [PATCH 57/75] add regression test --- src/test/ui/issues/issue-56128.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/issues/issue-56128.rs diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs new file mode 100644 index 000000000000..4d36fec9c04f --- /dev/null +++ b/src/test/ui/issues/issue-56128.rs @@ -0,0 +1,13 @@ +// Regression test for #56128. When this `pub(super) use...` gets +// exploded in the HIR, we were not handling ids correctly. + +mod bar { + pub(super) use self::baz::{x, y}; + + mod baz { + pub fn x() { } + pub fn y() { } + } +} + +fn main() { } From 4c7ce7c8973ff8f4b9427faffff3ceda8a1ab7f2 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 14:24:36 -0500 Subject: [PATCH 58/75] pass vis by shared reference We are not mutating it now. --- src/librustc/hir/lowering.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index eec9d084d7e3..5b38263f90f0 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2752,7 +2752,7 @@ fn lower_item_kind( id: NodeId, name: &mut Name, attrs: &hir::HirVec, - vis: &mut hir::Visibility, + vis: &hir::Visibility, i: &ItemKind, ) -> hir::ItemKind { match *i { @@ -2955,7 +2955,7 @@ fn lower_use_tree( tree: &UseTree, prefix: &Path, id: NodeId, - vis: &mut hir::Visibility, + vis: &hir::Visibility, name: &mut Name, attrs: &hir::HirVec, ) -> hir::ItemKind { @@ -3086,7 +3086,7 @@ fn lower_use_tree( hir_id: new_hir_id, } = self.lower_node_id(id); - let mut vis = vis.clone(); + let vis = vis.clone(); let mut name = name.clone(); let mut prefix = prefix.clone(); @@ -3104,7 +3104,7 @@ fn lower_use_tree( let item = this.lower_use_tree(use_tree, &prefix, new_id, - &mut vis, + &vis, &mut name, attrs); @@ -3384,7 +3384,7 @@ fn lower_item_id_use_tree(&mut self, pub fn lower_item(&mut self, i: &Item) -> Option { let mut name = i.ident.name; - let mut vis = self.lower_visibility(&i.vis, None); + let vis = self.lower_visibility(&i.vis, None); let attrs = self.lower_attrs(&i.attrs); if let ItemKind::MacroDef(ref def) = i.node { if !def.legacy || attr::contains_name(&i.attrs, "macro_export") || @@ -3403,7 +3403,7 @@ pub fn lower_item(&mut self, i: &Item) -> Option { return None; } - let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node); + let node = self.lower_item_kind(i.id, &mut name, &attrs, &vis, &i.node); let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); From 9cdf4911db1b143f0e40913793389c72e4fa6b17 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 16:09:17 -0500 Subject: [PATCH 59/75] hack: ignore list-stems for pub lint --- src/librustc_lint/builtin.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7dd1ca3493e9..0348ba1f1afe 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1136,7 +1136,15 @@ fn perform_lint(&self, cx: &LateContext, what: &str, id: ast::NodeId, impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { - self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); + match item.node { + hir::ItemKind::Use(_, hir::UseKind::ListStem) => { + // Hack: ignore these `use foo::{}` remnants which are just a figment + // our IR. + } + _ => { + self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); + } + } } fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) { From 1dc11249792aca93ee0bd6ff44fe9084adf78ddc Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 22 Nov 2018 01:13:09 +0300 Subject: [PATCH 60/75] resolve: Fix some asserts in import validation --- src/librustc_resolve/resolve_imports.rs | 6 ++- src/test/ui/imports/auxiliary/issue-56125.rs | 9 ++++ src/test/ui/imports/issue-56125.rs | 12 +++++ src/test/ui/imports/issue-56125.stderr | 46 ++++++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/imports/auxiliary/issue-56125.rs create mode 100644 src/test/ui/imports/issue-56125.rs create mode 100644 src/test/ui/imports/issue-56125.stderr diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index dfc066e4b961..616cc9d2fc51 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -842,12 +842,14 @@ fn finalize_import( module } PathResult::Failed(span, msg, false) => { - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); resolve_error(self, span, ResolutionError::FailedToResolve(&msg)); return None; } PathResult::Failed(span, msg, true) => { - assert!(directive.imported_module.get().is_none()); + assert!(!self.ambiguity_errors.is_empty() || + directive.imported_module.get().is_none()); return if let Some((suggested_path, note)) = self.make_path_suggestion( span, directive.module_path.clone(), &directive.parent_scope ) { diff --git a/src/test/ui/imports/auxiliary/issue-56125.rs b/src/test/ui/imports/auxiliary/issue-56125.rs new file mode 100644 index 000000000000..0ff407756b3a --- /dev/null +++ b/src/test/ui/imports/auxiliary/issue-56125.rs @@ -0,0 +1,9 @@ +pub mod last_segment { + pub mod issue_56125 {} +} + +pub mod non_last_segment { + pub mod non_last_segment { + pub mod issue_56125 {} + } +} diff --git a/src/test/ui/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs new file mode 100644 index 000000000000..4baeb8a34dd7 --- /dev/null +++ b/src/test/ui/imports/issue-56125.rs @@ -0,0 +1,12 @@ +// edition:2018 +// compile-flags:--extern issue_56125 +// aux-build:issue-56125.rs + +use issue_56125::last_segment::*; +//~^ ERROR `issue_56125` is ambiguous +//~| ERROR unresolved import `issue_56125::last_segment` +use issue_56125::non_last_segment::non_last_segment::*; +//~^ ERROR `issue_56125` is ambiguous +//~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125` + +fn main() {} diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr new file mode 100644 index 000000000000..096d5be97f0e --- /dev/null +++ b/src/test/ui/imports/issue-56125.stderr @@ -0,0 +1,46 @@ +error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125` + --> $DIR/issue-56125.rs:8:18 + | +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125` + +error[E0432]: unresolved import `issue_56125::last_segment` + --> $DIR/issue-56125.rs:5:18 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125` + +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56125` could refer to an extern crate passed with `--extern` + = help: use `::issue_56125` to refer to this extern crate unambiguously +note: `issue_56125` could also refer to the module imported here + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this module unambiguously + +error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) + --> $DIR/issue-56125.rs:8:5 + | +LL | use issue_56125::non_last_segment::non_last_segment::*; + | ^^^^^^^^^^^ ambiguous name + | + = note: `issue_56125` could refer to an extern crate passed with `--extern` + = help: use `::issue_56125` to refer to this extern crate unambiguously +note: `issue_56125` could also refer to the module imported here + --> $DIR/issue-56125.rs:5:5 + | +LL | use issue_56125::last_segment::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::issue_56125` to refer to this module unambiguously + +error: aborting due to 4 previous errors + +Some errors occurred: E0432, E0433, E0659. +For more information about an error, try `rustc --explain E0432`. From ebf3c8d8e993ea0ef94c9ff9bf33436c6a526e19 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 21 Nov 2018 18:50:10 -0500 Subject: [PATCH 61/75] add compile-pass annotation --- src/test/ui/issues/issue-56128.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/ui/issues/issue-56128.rs b/src/test/ui/issues/issue-56128.rs index 4d36fec9c04f..3a3eccdc33ce 100644 --- a/src/test/ui/issues/issue-56128.rs +++ b/src/test/ui/issues/issue-56128.rs @@ -1,5 +1,7 @@ // Regression test for #56128. When this `pub(super) use...` gets // exploded in the HIR, we were not handling ids correctly. +// +// compile-pass mod bar { pub(super) use self::baz::{x, y}; From d56e8920852adec249c9d8159348a94dcafbd31c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 8 Sep 2018 22:14:55 +0300 Subject: [PATCH 62/75] rustc_target: rename abi::Align to AbiAndPrefAlign. --- src/librustc/mir/interpret/allocation.rs | 10 +- src/librustc/mir/interpret/error.rs | 8 +- src/librustc/session/code_stats.rs | 4 +- src/librustc/ty/layout.rs | 14 +-- src/librustc_codegen_llvm/builder.rs | 24 ++--- src/librustc_codegen_llvm/consts.rs | 10 +- .../debuginfo/metadata.rs | 28 +++-- src/librustc_codegen_llvm/type_of.rs | 13 +-- src/librustc_codegen_ssa/base.rs | 6 +- src/librustc_codegen_ssa/glue.rs | 22 ++-- src/librustc_codegen_ssa/meth.rs | 6 +- src/librustc_codegen_ssa/mir/operand.rs | 8 +- src/librustc_codegen_ssa/mir/place.rs | 11 +- src/librustc_codegen_ssa/mir/rvalue.rs | 8 +- src/librustc_codegen_ssa/traits/builder.rs | 27 ++--- src/librustc_codegen_ssa/traits/statics.rs | 16 ++- src/librustc_codegen_ssa/traits/type_.rs | 6 +- src/librustc_mir/interpret/eval_context.rs | 12 +-- src/librustc_mir/interpret/memory.rs | 56 +++++----- src/librustc_mir/interpret/place.rs | 18 ++-- src/librustc_mir/interpret/snapshot.rs | 4 +- src/librustc_mir/interpret/traits.rs | 6 +- src/librustc_mir/interpret/validity.rs | 6 +- src/librustc_target/abi/call/mod.rs | 10 +- src/librustc_target/abi/call/powerpc64.rs | 4 +- src/librustc_target/abi/mod.rs | 101 +++++++++--------- 26 files changed, 220 insertions(+), 218 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 02c0ebcec4fe..eb44c3c8c5f7 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -12,7 +12,7 @@ use super::{Pointer, EvalResult, AllocId}; -use ty::layout::{Size, Align}; +use ty::layout::{Size, AbiAndPrefAlign}; use syntax::ast::Mutability; use std::iter; use mir; @@ -40,7 +40,7 @@ pub struct Allocation { /// Denotes undefined memory. Reading from undefined memory is forbidden in miri pub undef_mask: UndefMask, /// The alignment of the allocation to detect unaligned reads. - pub align: Align, + pub align: AbiAndPrefAlign, /// Whether the allocation is mutable. /// Also used by codegen to determine if a static should be put into mutable memory, /// which happens for `static mut` and `static` with interior mutability. @@ -90,7 +90,7 @@ impl AllocationExtra<()> for () {} impl Allocation { /// Creates a read-only allocation initialized by the given bytes - pub fn from_bytes(slice: &[u8], align: Align) -> Self { + pub fn from_bytes(slice: &[u8], align: AbiAndPrefAlign) -> Self { let mut undef_mask = UndefMask::new(Size::ZERO); undef_mask.grow(Size::from_bytes(slice.len() as u64), true); Self { @@ -104,10 +104,10 @@ pub fn from_bytes(slice: &[u8], align: Align) -> Self { } pub fn from_byte_aligned_bytes(slice: &[u8]) -> Self { - Allocation::from_bytes(slice, Align::from_bytes(1, 1).unwrap()) + Allocation::from_bytes(slice, AbiAndPrefAlign::from_bytes(1, 1).unwrap()) } - pub fn undef(size: Size, align: Align) -> Self { + pub fn undef(size: Size, align: AbiAndPrefAlign) -> Self { assert_eq!(size.bytes() as usize as u64, size.bytes()); Allocation { bytes: vec![0; size.bytes() as usize], diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index f1ac4b210583..bae53a9216a4 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -13,7 +13,7 @@ use hir::map::definitions::DefPathData; use mir; use ty::{self, Ty, layout}; -use ty::layout::{Size, Align, LayoutError}; +use ty::layout::{Size, AbiAndPrefAlign, LayoutError}; use rustc_target::spec::abi::Abi; use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef}; @@ -301,8 +301,8 @@ pub enum EvalErrorKind<'tcx, O> { TlsOutOfBounds, AbiViolation(String), AlignmentCheckFailed { - required: Align, - has: Align, + required: AbiAndPrefAlign, + has: AbiAndPrefAlign, }, ValidationFailure(String), CalledClosureAsFunction, @@ -315,7 +315,7 @@ pub enum EvalErrorKind<'tcx, O> { DeallocatedWrongMemoryKind(String, String), ReallocateNonBasePtr, DeallocateNonBasePtr, - IncorrectAllocationInformation(Size, Size, Align, Align), + IncorrectAllocationInformation(Size, Size, AbiAndPrefAlign, AbiAndPrefAlign), Layout(layout::LayoutError<'tcx>), HeapAllocZeroBytes, HeapAllocNonPowerOfTwoAlignment(u64), diff --git a/src/librustc/session/code_stats.rs b/src/librustc/session/code_stats.rs index b1dcfdfcda03..34a89ccf7a21 100644 --- a/src/librustc/session/code_stats.rs +++ b/src/librustc/session/code_stats.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc_target::abi::{Align, Size}; +use rustc_target::abi::{AbiAndPrefAlign, Size}; use rustc_data_structures::fx::{FxHashSet}; use std::cmp::{self, Ordering}; @@ -63,7 +63,7 @@ impl CodeStats { pub fn record_type_size(&mut self, kind: DataTypeKind, type_desc: S, - align: Align, + align: AbiAndPrefAlign, overall_size: Size, packed: bool, opt_discr_size: Option, diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index d7fb8da7acd0..76c3c467febb 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -248,7 +248,7 @@ enum StructKind { /// A univariant, the last field of which may be coerced to unsized. MaybeUnsized, /// A univariant, but with a prefix of an arbitrary size & alignment (e.g. enum tag). - Prefixed(Size, Align), + Prefixed(Size, AbiAndPrefAlign), } let univariant_uninterned = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| { @@ -259,7 +259,7 @@ enum StructKind { let pack = { let pack = repr.pack as u64; - Align::from_bytes(pack, pack).unwrap() + AbiAndPrefAlign::from_bytes(pack, pack).unwrap() }; let mut align = if packed { @@ -352,7 +352,7 @@ enum StructKind { if repr.align > 0 { let repr_align = repr.align as u64; - align = align.max(Align::from_bytes(repr_align, repr_align).unwrap()); + align = align.max(AbiAndPrefAlign::from_bytes(repr_align, repr_align).unwrap()); debug!("univariant repr_align: {:?}", repr_align); } @@ -682,7 +682,7 @@ enum StructKind { let pack = { let pack = def.repr.pack as u64; - Align::from_bytes(pack, pack).unwrap() + AbiAndPrefAlign::from_bytes(pack, pack).unwrap() }; let mut align = if packed { @@ -694,7 +694,7 @@ enum StructKind { if def.repr.align > 0 { let repr_align = def.repr.align as u64; align = align.max( - Align::from_bytes(repr_align, repr_align).unwrap()); + AbiAndPrefAlign::from_bytes(repr_align, repr_align).unwrap()); } let optimize = !def.repr.inhibit_union_abi_opt(); @@ -964,7 +964,7 @@ enum StructKind { let mut size = Size::ZERO; // We're interested in the smallest alignment, so start large. - let mut start_align = Align::from_bytes(256, 256).unwrap(); + let mut start_align = AbiAndPrefAlign::from_bytes(256, 256).unwrap(); assert_eq!(Integer::for_abi_align(dl, start_align), None); // repr(C) on an enum tells us to make a (tag, union) layout, @@ -1994,7 +1994,7 @@ fn hash_stable(&self, Pointer }); -impl<'gcx> HashStable> for Align { +impl<'gcx> HashStable> for AbiAndPrefAlign { fn hash_stable(&self, hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher) { diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 34e4f4d7e183..38400946a914 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -19,7 +19,7 @@ use value::Value; use libc::{c_uint, c_char}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::layout::{self, Align, Size, TyLayout}; +use rustc::ty::layout::{self, AbiAndPrefAlign, Size, TyLayout}; use rustc::session::config; use rustc_data_structures::small_c_str::SmallCStr; use rustc_codegen_ssa::traits::*; @@ -457,7 +457,7 @@ fn not(&mut self, v: &'ll Value) -> &'ll Value { } } - fn alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { + fn alloca(&mut self, ty: &'ll Type, name: &str, align: AbiAndPrefAlign) -> &'ll Value { let mut bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) @@ -465,7 +465,7 @@ fn alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { bx.dynamic_alloca(ty, name, align) } - fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { + fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: AbiAndPrefAlign) -> &'ll Value { self.count_insn("alloca"); unsafe { let alloca = if name.is_empty() { @@ -484,7 +484,7 @@ fn array_alloca(&mut self, ty: &'ll Type, len: &'ll Value, name: &str, - align: Align) -> &'ll Value { + align: AbiAndPrefAlign) -> &'ll Value { self.count_insn("alloca"); unsafe { let alloca = if name.is_empty() { @@ -499,7 +499,7 @@ fn array_alloca(&mut self, } } - fn load(&mut self, ptr: &'ll Value, align: Align) -> &'ll Value { + fn load(&mut self, ptr: &'ll Value, align: AbiAndPrefAlign) -> &'ll Value { self.count_insn("load"); unsafe { let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname()); @@ -639,7 +639,7 @@ fn nonnull_metadata(&mut self, load: &'ll Value) { } } - fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value { + fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: AbiAndPrefAlign) -> &'ll Value { self.store_with_flags(val, ptr, align, MemFlags::empty()) } @@ -647,7 +647,7 @@ fn store_with_flags( &mut self, val: &'ll Value, ptr: &'ll Value, - align: Align, + align: AbiAndPrefAlign, flags: MemFlags, ) -> &'ll Value { debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags); @@ -878,8 +878,8 @@ fn inline_asm_call(&mut self, asm: &CStr, cons: &CStr, } } - fn memcpy(&mut self, dst: &'ll Value, dst_align: Align, - src: &'ll Value, src_align: Align, + fn memcpy(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, + src: &'ll Value, src_align: AbiAndPrefAlign, size: &'ll Value, flags: MemFlags) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. @@ -898,8 +898,8 @@ fn memcpy(&mut self, dst: &'ll Value, dst_align: Align, } } - fn memmove(&mut self, dst: &'ll Value, dst_align: Align, - src: &'ll Value, src_align: Align, + fn memmove(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, + src: &'ll Value, src_align: AbiAndPrefAlign, size: &'ll Value, flags: MemFlags) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memmove. @@ -923,7 +923,7 @@ fn memset( ptr: &'ll Value, fill_byte: &'ll Value, size: &'ll Value, - align: Align, + align: AbiAndPrefAlign, flags: MemFlags, ) { let ptr_width = &self.cx().sess().target.target.target_pointer_width; diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 821ac931aac7..158bc6eb9c10 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -28,7 +28,7 @@ use rustc::ty::{self, Ty}; use rustc_codegen_ssa::traits::*; -use rustc::ty::layout::{self, Size, Align, LayoutOf}; +use rustc::ty::layout::{self, Size, AbiAndPrefAlign, LayoutOf}; use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags}; @@ -89,12 +89,12 @@ pub fn codegen_static_initializer( fn set_global_alignment(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, - mut align: Align) { + mut align: AbiAndPrefAlign) { // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. if let Some(min) = cx.sess().target.target.options.min_global_align { - match ty::layout::Align::from_bits(min, min) { + match ty::layout::AbiAndPrefAlign::from_bits(min, min) { Ok(min) => align = align.max(min), Err(err) => { cx.sess().err(&format!("invalid minimum global alignment: {}", err)); @@ -186,7 +186,7 @@ fn static_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { fn static_addr_of_mut( &self, cv: &'ll Value, - align: Align, + align: AbiAndPrefAlign, kind: Option<&str>, ) -> &'ll Value { unsafe { @@ -212,7 +212,7 @@ fn static_addr_of_mut( fn static_addr_of( &self, cv: &'ll Value, - align: Align, + align: AbiAndPrefAlign, kind: Option<&str>, ) -> &'ll Value { if let Some(&gv) = self.const_globals.borrow().get(&cv) { diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 1c787a969324..42b48b728fd0 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -35,7 +35,7 @@ use rustc::ty::Instance; use common::CodegenCx; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; -use rustc::ty::layout::{self, Align, HasDataLayout, Integer, IntegerExt, LayoutOf, +use rustc::ty::layout::{self, AbiAndPrefAlign, HasDataLayout, Integer, IntegerExt, LayoutOf, PrimitiveExt, Size, TyLayout}; use rustc::session::config; use rustc::util::nodemap::FxHashMap; @@ -923,7 +923,7 @@ struct MemberDescription<'ll> { type_metadata: &'ll DIType, offset: Size, size: Size, - align: Align, + align: AbiAndPrefAlign, flags: DIFlags, discriminant: Option, } @@ -985,13 +985,12 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) f.ident.to_string() }; let field = layout.field(cx, i); - let (size, align) = field.size_and_align(); MemberDescription { name, type_metadata: type_metadata(cx, field.ty, self.span), offset: layout.fields.offset(i), - size, - align, + size: field.size, + align: field.align, flags: DIFlags::FlagZero, discriminant: None, } @@ -1109,13 +1108,12 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec> { self.variant.fields.iter().enumerate().map(|(i, f)| { let field = self.layout.field(cx, i); - let (size, align) = field.size_and_align(); MemberDescription { name: f.ident.to_string(), type_metadata: type_metadata(cx, field.ty, self.span), offset: Size::ZERO, - size, - align, + size: field.size, + align: field.align, flags: DIFlags::FlagZero, discriminant: None, } @@ -1587,8 +1585,6 @@ fn prepare_enum_metadata( _ => {} } - let (enum_type_size, enum_type_align) = layout.size_and_align(); - let enum_name = SmallCStr::new(&enum_name); let unique_type_id_str = SmallCStr::new( debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id) @@ -1610,8 +1606,8 @@ fn prepare_enum_metadata( enum_name.as_ptr(), file_metadata, UNKNOWN_LINE_NUMBER, - enum_type_size.bits(), - enum_type_align.abi_bits() as u32, + layout.size.bits(), + layout.align.abi_bits() as u32, DIFlags::FlagZero, None, 0, // RuntimeLang @@ -1695,8 +1691,8 @@ fn prepare_enum_metadata( ptr::null_mut(), file_metadata, UNKNOWN_LINE_NUMBER, - enum_type_size.bits(), - enum_type_align.abi_bits() as u32, + layout.size.bits(), + layout.align.abi_bits() as u32, DIFlags::FlagZero, discriminator_metadata, empty_array, @@ -1712,8 +1708,8 @@ fn prepare_enum_metadata( enum_name.as_ptr(), file_metadata, UNKNOWN_LINE_NUMBER, - enum_type_size.bits(), - enum_type_align.abi_bits() as u32, + layout.size.bits(), + layout.align.abi_bits() as u32, DIFlags::FlagZero, None, type_array, diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 90c02cddb2b6..a07fa9448919 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -12,7 +12,7 @@ use common::*; use rustc::hir; use rustc::ty::{self, Ty, TypeFoldable}; -use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; +use rustc::ty::layout::{self, AbiAndPrefAlign, LayoutOf, Size, TyLayout}; use rustc_target::abi::FloatTy; use rustc_mir::monomorphize::item::DefPathBasedNames; use type_::Type; @@ -80,7 +80,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, match layout.fields { layout::FieldPlacement::Union(_) => { - let fill = cx.type_padding_filler( layout.size, layout.align); + let fill = cx.type_padding_filler(layout.size, layout.align); let packed = false; match name { None => { @@ -165,7 +165,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } impl<'a, 'tcx> CodegenCx<'a, 'tcx> { - pub fn align_of(&self, ty: Ty<'tcx>) -> Align { + pub fn align_of(&self, ty: Ty<'tcx>) -> AbiAndPrefAlign { self.layout_of(ty).align } @@ -173,8 +173,9 @@ pub fn size_of(&self, ty: Ty<'tcx>) -> Size { self.layout_of(ty).size } - pub fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) { - self.layout_of(ty).size_and_align() + pub fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, AbiAndPrefAlign) { + let layout = self.layout_of(ty); + (layout.size, layout.align) } } @@ -196,7 +197,7 @@ pub enum PointerKind { #[derive(Copy, Clone)] pub struct PointeeInfo { pub size: Size, - pub align: Align, + pub align: AbiAndPrefAlign, pub safe: Option, } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 856bb9533c85..e80ff8b65801 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -31,7 +31,7 @@ use rustc::middle::weak_lang_items; use rustc::mir::mono::{Stats, CodegenUnitNameBuilder}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; +use rustc::ty::layout::{self, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; @@ -410,9 +410,9 @@ pub fn to_immediate_scalar<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( pub fn memcpy_ty<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, dst: Bx::Value, - dst_align: Align, + dst_align: AbiAndPrefAlign, src: Bx::Value, - src_align: Align, + src_align: AbiAndPrefAlign, layout: TyLayout<'tcx>, flags: MemFlags, ) { diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs index 515f36b5c65d..bf4c53f228e3 100644 --- a/src/librustc_codegen_ssa/glue.rs +++ b/src/librustc_codegen_ssa/glue.rs @@ -25,14 +25,12 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( t: Ty<'tcx>, info: Option ) -> (Bx::Value, Bx::Value) { - debug!("calculate size of DST: {}; with lost info: {:?}", - t, info); - if bx.cx().type_is_sized(t) { - let (size, align) = bx.cx().layout_of(t).size_and_align(); - debug!("size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}", - t, info, size, align); - let size = bx.cx().const_usize(size.bytes()); - let align = bx.cx().const_usize(align.abi()); + let layout = bx.cx().layout_of(t); + debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", + t, info, layout); + if !layout.is_unsized() { + let size = bx.cx().const_usize(layout.size.bytes()); + let align = bx.cx().const_usize(layout.align.abi()); return (size, align); } match t.sty { @@ -42,19 +40,17 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( (meth::SIZE.get_usize(bx, vtable), meth::ALIGN.get_usize(bx, vtable)) } ty::Slice(_) | ty::Str => { - let unit = t.sequence_element_type(bx.tcx()); + let unit = layout.field(bx.cx(), 0); // The info in this case is the length of the str, so the size is that // times the unit size. - let (size, align) = bx.cx().layout_of(unit).size_and_align(); - (bx.mul(info.unwrap(), bx.cx().const_usize(size.bytes())), - bx.cx().const_usize(align.abi())) + (bx.mul(info.unwrap(), bx.cx().const_usize(unit.size.bytes())), + bx.cx().const_usize(unit.align.abi())) } _ => { // First get the size of all statically known fields. // Don't use size_of because it also rounds up to alignment, which we // want to avoid, as the unsized field's alignment could be smaller. assert!(!t.is_simd()); - let layout = bx.cx().layout_of(t); debug!("DST {} layout: {:?}", t, layout); let i = layout.fields.count() - 1; diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 06c4f7a87d88..d0b8c166b121 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -100,15 +100,15 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( }) }); - let (size, align) = cx.layout_of(ty).size_and_align(); + let layout = cx.layout_of(ty); // ///////////////////////////////////////////////////////////////////////////////////////////// // If you touch this code, be sure to also make the corresponding changes to // `get_vtable` in rust_mir/interpret/traits.rs // ///////////////////////////////////////////////////////////////////////////////////////////// let components: Vec<_> = [ cx.get_fn(monomorphize::resolve_drop_in_place(cx.tcx(), ty)), - cx.const_usize(size.bytes()), - cx.const_usize(align.abi()) + cx.const_usize(layout.size.bytes()), + cx.const_usize(layout.align.abi()) ].iter().cloned().chain(methods).collect(); let vtable_const = cx.const_struct(&components, false); diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index d574d89d67e3..4c92ab7eda5b 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -11,7 +11,7 @@ use rustc::mir::interpret::{ConstValue, ErrorHandled}; use rustc::mir; use rustc::ty; -use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; +use rustc::ty::layout::{self, AbiAndPrefAlign, LayoutOf, TyLayout}; use base; use MemFlags; @@ -33,7 +33,7 @@ pub enum OperandValue { /// to be valid for the operand's lifetime. /// The second value, if any, is the extra data (vtable or length) /// which indicates that it refers to an unsized rvalue. - Ref(V, Option, Align), + Ref(V, Option, AbiAndPrefAlign), /// A single LLVM value. Immediate(V), /// A pair of immediate LLVM values. Used by fat pointers too. @@ -348,8 +348,8 @@ pub fn store_unsized>( }; // FIXME: choose an appropriate alignment, or use dynamic align somehow - let max_align = Align::from_bits(128, 128).unwrap(); - let min_align = Align::from_bits(8, 8).unwrap(); + let max_align = AbiAndPrefAlign::from_bits(128, 128).unwrap(); + let min_align = AbiAndPrefAlign::from_bits(8, 8).unwrap(); // Allocate an appropriate region on the stack, and copy the value into it let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 5b36ee8fd183..e6216c8724f5 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; +use rustc::ty::layout::{self, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::mir; use rustc::mir::tcx::PlaceTy; use MemFlags; @@ -33,14 +33,14 @@ pub struct PlaceRef<'tcx, V> { pub layout: TyLayout<'tcx>, /// What alignment we know for this place - pub align: Align, + pub align: AbiAndPrefAlign, } impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { pub fn new_sized( llval: V, layout: TyLayout<'tcx>, - align: Align, + align: AbiAndPrefAlign, ) -> PlaceRef<'tcx, V> { assert!(!layout.is_unsized()); PlaceRef { @@ -308,9 +308,8 @@ pub fn codegen_set_discr>( // Issue #34427: As workaround for LLVM bug on ARM, // use memset of 0 before assigning niche value. let fill_byte = bx.cx().const_u8(0); - let (size, align) = self.layout.size_and_align(); - let size = bx.cx().const_usize(size.bytes()); - bx.memset(self.llval, fill_byte, size, align, MemFlags::empty()); + let size = bx.cx().const_usize(self.layout.size.bytes()); + bx.memset(self.llval, fill_byte, size, self.align, MemFlags::empty()); } let niche = self.project_field(bx, 0); diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 6b1efa060fda..167a143ec31e 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -496,10 +496,10 @@ pub fn codegen_rvalue_operand( } mir::Rvalue::NullaryOp(mir::NullOp::Box, content_ty) => { - let content_ty: Ty<'tcx> = self.monomorphize(&content_ty); - let (size, align) = bx.cx().layout_of(content_ty).size_and_align(); - let llsize = bx.cx().const_usize(size.bytes()); - let llalign = bx.cx().const_usize(align.abi()); + let content_ty = self.monomorphize(&content_ty); + let content_layout = bx.cx().layout_of(content_ty); + let llsize = bx.cx().const_usize(content_layout.size.bytes()); + let llalign = bx.cx().const_usize(content_layout.align.abi()); let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty)); let llty_ptr = bx.cx().backend_type(box_layout); diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 3757c514d2ce..02be098599b3 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -15,10 +15,10 @@ use super::type_::ArgTypeMethods; use super::HasCodegen; use common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope}; -use std::ffi::CStr; use mir::operand::OperandRef; use mir::place::PlaceRef; -use rustc::ty::layout::{Align, Size}; +use rustc::ty::layout::{AbiAndPrefAlign, Size}; +use std::ffi::CStr; use MemFlags; use std::borrow::Cow; @@ -97,17 +97,18 @@ fn invoke( fn fneg(&mut self, v: Self::Value) -> Self::Value; fn not(&mut self, v: Self::Value) -> Self::Value; - fn alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; - fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; + fn alloca(&mut self, ty: Self::Type, name: &str, align: AbiAndPrefAlign) -> Self::Value; + fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: AbiAndPrefAlign) + -> Self::Value; fn array_alloca( &mut self, ty: Self::Type, len: Self::Value, name: &str, - align: Align, + align: AbiAndPrefAlign, ) -> Self::Value; - fn load(&mut self, ptr: Self::Value, align: Align) -> Self::Value; + fn load(&mut self, ptr: Self::Value, align: AbiAndPrefAlign) -> Self::Value; fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value; fn atomic_load(&mut self, ptr: Self::Value, order: AtomicOrdering, size: Size) -> Self::Value; fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) @@ -116,12 +117,12 @@ fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) fn range_metadata(&mut self, load: Self::Value, range: Range); fn nonnull_metadata(&mut self, load: Self::Value); - fn store(&mut self, val: Self::Value, ptr: Self::Value, align: Align) -> Self::Value; + fn store(&mut self, val: Self::Value, ptr: Self::Value, align: AbiAndPrefAlign) -> Self::Value; fn store_with_flags( &mut self, val: Self::Value, ptr: Self::Value, - align: Align, + align: AbiAndPrefAlign, flags: MemFlags, ) -> Self::Value; fn atomic_store( @@ -174,18 +175,18 @@ fn inline_asm_call( fn memcpy( &mut self, dst: Self::Value, - dst_align: Align, + dst_align: AbiAndPrefAlign, src: Self::Value, - src_align: Align, + src_align: AbiAndPrefAlign, size: Self::Value, flags: MemFlags, ); fn memmove( &mut self, dst: Self::Value, - dst_align: Align, + dst_align: AbiAndPrefAlign, src: Self::Value, - src_align: Align, + src_align: AbiAndPrefAlign, size: Self::Value, flags: MemFlags, ); @@ -194,7 +195,7 @@ fn memset( ptr: Self::Value, fill_byte: Self::Value, size: Self::Value, - align: Align, + align: AbiAndPrefAlign, flags: MemFlags, ); diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs index 172c48f8a85f..b66f4378c35f 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/src/librustc_codegen_ssa/traits/statics.rs @@ -10,13 +10,23 @@ use super::Backend; use rustc::hir::def_id::DefId; -use rustc::ty::layout::Align; +use rustc::ty::layout::AbiAndPrefAlign; pub trait StaticMethods<'tcx>: Backend<'tcx> { fn static_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; fn static_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; - fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; - fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; + fn static_addr_of_mut( + &self, + cv: Self::Value, + align: AbiAndPrefAlign, + kind: Option<&str>, + ) -> Self::Value; + fn static_addr_of( + &self, + cv: Self::Value, + align: AbiAndPrefAlign, + kind: Option<&str>, + ) -> Self::Value; fn get_static(&self, def_id: DefId) -> Self::Value; fn codegen_static(&self, def_id: DefId, is_mutable: bool); unsafe fn static_replace_all_uses(&self, old_g: Self::Value, new_g: Self::Value); diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 1aa1f45f5174..275f378495d9 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -13,7 +13,7 @@ use super::HasCodegen; use common::{self, TypeKind}; use mir::place::PlaceRef; -use rustc::ty::layout::{self, Align, Size, TyLayout}; +use rustc::ty::layout::{self, AbiAndPrefAlign, Size, TyLayout}; use rustc::ty::{self, Ty}; use rustc::util::nodemap::FxHashMap; use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg}; @@ -120,7 +120,7 @@ fn type_from_integer(&self, i: layout::Integer) -> Self::Type { } } - fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type { + fn type_pointee_for_abi_align(&self, align: AbiAndPrefAlign) -> Self::Type { // FIXME(eddyb) We could find a better approximation if ity.align < align. let ity = layout::Integer::approximate_abi_align(self, align); self.type_from_integer(ity) @@ -128,7 +128,7 @@ fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type { /// Return a LLVM type that has at most the required alignment, /// and exactly the required size, as a best-effort padding array. - fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type { + fn type_padding_filler(&self, size: Size, align: AbiAndPrefAlign) -> Self::Type { let unit = layout::Integer::approximate_abi_align(self, align); let size = size.bytes(); let unit_size = unit.size().bytes(); diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 590834135824..69db638270a5 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -16,7 +16,7 @@ use rustc::hir::def::Def; use rustc::mir; use rustc::ty::layout::{ - self, Size, Align, HasDataLayout, LayoutOf, TyLayout + self, Size, AbiAndPrefAlign, HasDataLayout, LayoutOf, TyLayout }; use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -314,9 +314,9 @@ pub(super) fn size_and_align_of( &self, metadata: Option>, layout: TyLayout<'tcx>, - ) -> EvalResult<'tcx, Option<(Size, Align)>> { + ) -> EvalResult<'tcx, Option<(Size, AbiAndPrefAlign)>> { if !layout.is_unsized() { - return Ok(Some(layout.size_and_align())); + return Ok(Some((layout.size, layout.align))); } match layout.ty.sty { ty::Adt(..) | ty::Tuple(..) => { @@ -391,8 +391,8 @@ pub(super) fn size_and_align_of( ty::Slice(_) | ty::Str => { let len = metadata.expect("slice fat ptr must have vtable").to_usize(self)?; - let (elem_size, align) = layout.field(self, 0)?.size_and_align(); - Ok(Some((elem_size * len, align))) + let elem = layout.field(self, 0)?; + Ok(Some((elem.size * len, elem.align))) } ty::Foreign(_) => { @@ -406,7 +406,7 @@ pub(super) fn size_and_align_of( pub fn size_and_align_of_mplace( &self, mplace: MPlaceTy<'tcx, M::PointerTag> - ) -> EvalResult<'tcx, Option<(Size, Align)>> { + ) -> EvalResult<'tcx, Option<(Size, AbiAndPrefAlign)>> { self.size_and_align_of(mplace.meta, mplace.layout) } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 7dd42c666496..dbb0e5228748 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -21,7 +21,7 @@ use std::borrow::Cow; use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; -use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout}; +use rustc::ty::layout::{self, AbiAndPrefAlign, TargetDataLayout, Size, HasDataLayout}; pub use rustc::mir::interpret::{truncate, write_target_uint, read_target_uint}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; @@ -71,7 +71,7 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> { /// To be able to compare pointers with NULL, and to check alignment for accesses /// to ZSTs (where pointers may dangle), we keep track of the size even for allocations /// that do not exist any more. - dead_alloc_map: FxHashMap, + dead_alloc_map: FxHashMap, /// Lets us implement `HasDataLayout`, which is awfully convenient. pub(super) tcx: TyCtxtAt<'a, 'tcx, 'tcx>, @@ -130,7 +130,7 @@ pub fn allocate_with( pub fn allocate( &mut self, size: Size, - align: Align, + align: AbiAndPrefAlign, kind: MemoryKind, ) -> EvalResult<'tcx, Pointer> { Ok(Pointer::from(self.allocate_with(Allocation::undef(size, align), kind)?)) @@ -140,9 +140,9 @@ pub fn reallocate( &mut self, ptr: Pointer, old_size: Size, - old_align: Align, + old_align: AbiAndPrefAlign, new_size: Size, - new_align: Align, + new_align: AbiAndPrefAlign, kind: MemoryKind, ) -> EvalResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { @@ -179,7 +179,7 @@ pub fn deallocate_local(&mut self, ptr: Pointer) -> EvalResult<'t pub fn deallocate( &mut self, ptr: Pointer, - size_and_align: Option<(Size, Align)>, + size_and_align: Option<(Size, AbiAndPrefAlign)>, kind: MemoryKind, ) -> EvalResult<'tcx> { trace!("deallocating: {}", ptr.alloc_id); @@ -244,7 +244,7 @@ pub fn deallocate( pub fn check_align( &self, ptr: Scalar, - required_align: Align + required_align: AbiAndPrefAlign ) -> EvalResult<'tcx> { // Check non-NULL/Undef, extract offset let (offset, alloc_align) = match ptr { @@ -279,7 +279,7 @@ pub fn check_align( } else { let has = offset % required_align.abi(); err!(AlignmentCheckFailed { - has: Align::from_bytes(has, has).unwrap(), + has: AbiAndPrefAlign::from_bytes(has, has).unwrap(), required: required_align, }) } @@ -443,13 +443,15 @@ pub fn get_mut( } } - pub fn get_size_and_align(&self, id: AllocId) -> (Size, Align) { + pub fn get_size_and_align(&self, id: AllocId) -> (Size, AbiAndPrefAlign) { if let Ok(alloc) = self.get(id) { return (Size::from_bytes(alloc.bytes.len() as u64), alloc.align); } // Could also be a fn ptr or extern static match self.tcx.alloc_map.lock().get(id) { - Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1, 1).unwrap()), + Some(AllocType::Function(..)) => { + (Size::ZERO, AbiAndPrefAlign::from_bytes(1, 1).unwrap()) + } Some(AllocType::Static(did)) => { // The only way `get` couldn't have worked here is if this is an extern static assert!(self.tcx.is_foreign_item(did)); @@ -622,7 +624,7 @@ fn get_bytes_internal( &self, ptr: Pointer, size: Size, - align: Align, + align: AbiAndPrefAlign, check_defined_and_ptr: bool, ) -> EvalResult<'tcx, &[u8]> { assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); @@ -651,7 +653,7 @@ fn get_bytes( &self, ptr: Pointer, size: Size, - align: Align + align: AbiAndPrefAlign ) -> EvalResult<'tcx, &[u8]> { self.get_bytes_internal(ptr, size, align, true) } @@ -663,7 +665,7 @@ fn get_bytes_with_undef_and_ptr( &self, ptr: Pointer, size: Size, - align: Align + align: AbiAndPrefAlign ) -> EvalResult<'tcx, &[u8]> { self.get_bytes_internal(ptr, size, align, false) } @@ -674,7 +676,7 @@ fn get_bytes_mut( &mut self, ptr: Pointer, size: Size, - align: Align, + align: AbiAndPrefAlign, ) -> EvalResult<'tcx, &mut [u8]> { assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); self.check_align(ptr.into(), align)?; @@ -747,9 +749,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { pub fn copy( &mut self, src: Scalar, - src_align: Align, + src_align: AbiAndPrefAlign, dest: Scalar, - dest_align: Align, + dest_align: AbiAndPrefAlign, size: Size, nonoverlapping: bool, ) -> EvalResult<'tcx> { @@ -759,9 +761,9 @@ pub fn copy( pub fn copy_repeatedly( &mut self, src: Scalar, - src_align: Align, + src_align: AbiAndPrefAlign, dest: Scalar, - dest_align: Align, + dest_align: AbiAndPrefAlign, size: Size, length: u64, nonoverlapping: bool, @@ -863,7 +865,7 @@ pub fn check_bytes( allow_ptr_and_undef: bool, ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); @@ -881,7 +883,7 @@ pub fn check_bytes( pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<'tcx, &[u8]> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(&[]); @@ -891,7 +893,7 @@ pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<' pub fn write_bytes(&mut self, ptr: Scalar, src: &[u8]) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); if src.is_empty() { self.check_align(ptr, align)?; return Ok(()); @@ -908,7 +910,7 @@ pub fn write_repeat( count: Size ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = Align::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); if count.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); @@ -924,7 +926,7 @@ pub fn write_repeat( pub fn read_scalar( &self, ptr: Pointer, - ptr_align: Align, + ptr_align: AbiAndPrefAlign, size: Size ) -> EvalResult<'tcx, ScalarMaybeUndef> { // get_bytes_unchecked tests alignment and relocation edges @@ -961,7 +963,7 @@ pub fn read_scalar( pub fn read_ptr_sized( &self, ptr: Pointer, - ptr_align: Align + ptr_align: AbiAndPrefAlign ) -> EvalResult<'tcx, ScalarMaybeUndef> { self.read_scalar(ptr, ptr_align, self.pointer_size()) } @@ -970,7 +972,7 @@ pub fn read_ptr_sized( pub fn write_scalar( &mut self, ptr: Pointer, - ptr_align: Align, + ptr_align: AbiAndPrefAlign, val: ScalarMaybeUndef, type_size: Size, ) -> EvalResult<'tcx> { @@ -1017,14 +1019,14 @@ pub fn write_scalar( pub fn write_ptr_sized( &mut self, ptr: Pointer, - ptr_align: Align, + ptr_align: AbiAndPrefAlign, val: ScalarMaybeUndef ) -> EvalResult<'tcx> { let ptr_size = self.pointer_size(); self.write_scalar(ptr.into(), ptr_align, val, ptr_size) } - fn int_align(&self, size: Size) -> Align { + fn int_align(&self, size: Size) -> AbiAndPrefAlign { // We assume pointer-sized integers have the same alignment as pointers. // We also assume signed and unsigned integers of the same size have the same alignment. let ity = match size.bytes() { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 9f248d463507..bd713d4462d0 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -18,7 +18,7 @@ use rustc::hir; use rustc::mir; use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; +use rustc::ty::layout::{self, Size, AbiAndPrefAlign, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; use super::{ GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic, @@ -32,7 +32,7 @@ pub struct MemPlace { /// be turned back into a reference before ever being dereferenced. /// However, it may never be undef. pub ptr: Scalar, - pub align: Align, + pub align: AbiAndPrefAlign, /// Metadata for unsized places. Interpretation is up to the type. /// Must not be present for sized types, but can be missing for unsized types /// (e.g. `extern type`). @@ -116,7 +116,7 @@ pub fn erase_tag(self) -> MemPlace } #[inline(always)] - pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { + pub fn from_scalar_ptr(ptr: Scalar, align: AbiAndPrefAlign) -> Self { MemPlace { ptr, align, @@ -127,16 +127,16 @@ pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { /// Produces a Place that will error if attempted to be read from or written to #[inline(always)] pub fn null(cx: &impl HasDataLayout) -> Self { - Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1, 1).unwrap()) + Self::from_scalar_ptr(Scalar::ptr_null(cx), AbiAndPrefAlign::from_bytes(1, 1).unwrap()) } #[inline(always)] - pub fn from_ptr(ptr: Pointer, align: Align) -> Self { + pub fn from_ptr(ptr: Pointer, align: AbiAndPrefAlign) -> Self { Self::from_scalar_ptr(ptr.into(), align) } #[inline(always)] - pub fn to_scalar_ptr_align(self) -> (Scalar, Align) { + pub fn to_scalar_ptr_align(self) -> (Scalar, AbiAndPrefAlign) { assert!(self.meta.is_none()); (self.ptr, self.align) } @@ -230,12 +230,12 @@ pub fn null(cx: &impl HasDataLayout) -> Self { } #[inline(always)] - pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { + pub fn from_scalar_ptr(ptr: Scalar, align: AbiAndPrefAlign) -> Self { Place::Ptr(MemPlace::from_scalar_ptr(ptr, align)) } #[inline(always)] - pub fn from_ptr(ptr: Pointer, align: Align) -> Self { + pub fn from_ptr(ptr: Pointer, align: AbiAndPrefAlign) -> Self { Place::Ptr(MemPlace::from_ptr(ptr, align)) } @@ -249,7 +249,7 @@ pub fn to_mem_place(self) -> MemPlace { } #[inline] - pub fn to_scalar_ptr_align(self) -> (Scalar, Align) { + pub fn to_scalar_ptr_align(self) -> (Scalar, AbiAndPrefAlign) { self.to_mem_place().to_scalar_ptr_align() } diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 4b63335ad964..56475dffae42 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -16,7 +16,7 @@ }; use rustc::ty::{self, TyCtxt}; -use rustc::ty::layout::Align; +use rustc::ty::layout::AbiAndPrefAlign; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -276,7 +276,7 @@ struct AllocationSnapshot<'a> { bytes: &'a [u8], relocations: Relocations<(), AllocIdSnapshot<'a>>, undef_mask: &'a UndefMask, - align: &'a Align, + align: &'a AbiAndPrefAlign, mutability: &'a Mutability, } diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index c5366a5ce6a4..f1bedd181e9e 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::{self, Ty}; -use rustc::ty::layout::{Size, Align, LayoutOf}; +use rustc::ty::layout::{Size, AbiAndPrefAlign, LayoutOf}; use rustc::mir::interpret::{Scalar, Pointer, EvalResult, PointerArithmetic}; use super::{EvalContext, Machine, MemoryKind}; @@ -101,7 +101,7 @@ pub fn read_drop_type_from_vtable( pub fn read_size_and_align_from_vtable( &self, vtable: Pointer, - ) -> EvalResult<'tcx, (Size, Align)> { + ) -> EvalResult<'tcx, (Size, AbiAndPrefAlign)> { let pointer_size = self.pointer_size(); let pointer_align = self.tcx.data_layout.pointer_align; let size = self.memory.read_ptr_sized(vtable.offset(pointer_size, self)?,pointer_align)? @@ -110,6 +110,6 @@ pub fn read_size_and_align_from_vtable( vtable.offset(pointer_size * 2, self)?, pointer_align )?.to_bits(pointer_size)? as u64; - Ok((Size::from_bytes(size), Align::from_bytes(align, align).unwrap())) + Ok((Size::from_bytes(size), AbiAndPrefAlign::from_bytes(align, align).unwrap())) } } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index ad7ffd291bed..41358fe0d848 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -13,7 +13,7 @@ use std::ops::RangeInclusive; use syntax_pos::symbol::Symbol; -use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx}; +use rustc::ty::layout::{self, Size, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx}; use rustc::ty; use rustc_data_structures::fx::FxHashSet; use rustc::mir::interpret::{ @@ -355,7 +355,7 @@ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'t // for the purpose of validity, consider foreign types to have // alignment and size determined by the layout (size will be 0, // alignment should take attributes into account). - .unwrap_or_else(|| layout.size_and_align()); + .unwrap_or_else(|| (layout.size, layout.align)); match self.ecx.memory.check_align(ptr, align) { Ok(_) => {}, Err(err) => { @@ -463,7 +463,7 @@ fn visit_scalar( // for function pointers. let non_null = self.ecx.memory.check_align( - Scalar::Ptr(ptr), Align::from_bytes(1, 1).unwrap() + Scalar::Ptr(ptr), AbiAndPrefAlign::from_bytes(1, 1).unwrap() ).is_ok() || self.ecx.memory.get_fn(ptr).is_ok(); if !non_null { diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 8f9ef2544e60..289a76eae8f5 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{self, Abi, Align, FieldPlacement, Size}; +use abi::{self, Abi, AbiAndPrefAlign, FieldPlacement, Size}; use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; use spec::HasTargetSpec; @@ -80,7 +80,7 @@ pub struct ArgAttribute: u16 { pub struct ArgAttributes { pub regular: ArgAttribute, pub pointee_size: Size, - pub pointee_align: Option + pub pointee_align: Option } impl ArgAttributes { @@ -137,7 +137,7 @@ impl Reg { } impl Reg { - pub fn align(&self, cx: &C) -> Align { + pub fn align(&self, cx: &C) -> AbiAndPrefAlign { let dl = cx.data_layout(); match self.kind { RegKind::Integer => { @@ -188,7 +188,7 @@ fn from(unit: Reg) -> Uniform { } impl Uniform { - pub fn align(&self, cx: &C) -> Align { + pub fn align(&self, cx: &C) -> AbiAndPrefAlign { self.unit.align(cx) } } @@ -230,7 +230,7 @@ pub fn size(&self, cx: &C) -> Size { .abi_align(self.rest.align(cx)) + self.rest.total } - pub fn align(&self, cx: &C) -> Align { + pub fn align(&self, cx: &C) -> AbiAndPrefAlign { self.prefix.iter() .filter_map(|x| x.map(|kind| Reg { kind, size: self.prefix_chunk }.align(cx))) .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index f7ef1390f14d..93b8f79ccdc0 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -13,7 +13,7 @@ // need to be fixed when PowerPC vector support is added. use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; -use abi::{Align, Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use abi::{AbiAndPrefAlign, Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; use spec::HasTargetSpec; #[derive(Debug, Clone, Copy, PartialEq)] @@ -120,7 +120,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI) } else { // Aggregates larger than a doubleword should be padded // at the tail to fill out a whole number of doublewords. - let align = Align::from_bits(64, 64).unwrap(); + let align = AbiAndPrefAlign::from_bits(64, 64).unwrap(); (Reg::i64(), size.abi_align(align)) }; diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 22afb0da05bc..7b0b34e207ce 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -24,20 +24,21 @@ /// for a target, which contains everything needed to compute layouts. pub struct TargetDataLayout { pub endian: Endian, - pub i1_align: Align, - pub i8_align: Align, - pub i16_align: Align, - pub i32_align: Align, - pub i64_align: Align, - pub i128_align: Align, - pub f32_align: Align, - pub f64_align: Align, + pub i1_align: AbiAndPrefAlign, + pub i8_align: AbiAndPrefAlign, + pub i16_align: AbiAndPrefAlign, + pub i32_align: AbiAndPrefAlign, + pub i64_align: AbiAndPrefAlign, + pub i128_align: AbiAndPrefAlign, + pub f32_align: AbiAndPrefAlign, + pub f64_align: AbiAndPrefAlign, pub pointer_size: Size, - pub pointer_align: Align, - pub aggregate_align: Align, + pub pointer_align: AbiAndPrefAlign, + pub aggregate_align: AbiAndPrefAlign, /// Alignments for vector types. - pub vector_align: Vec<(Size, Align)>, + pub vector_align: Vec<(Size, AbiAndPrefAlign)>, + pub instruction_address_space: u32, } @@ -46,20 +47,20 @@ impl Default for TargetDataLayout { fn default() -> TargetDataLayout { TargetDataLayout { endian: Endian::Big, - i1_align: Align::from_bits(8, 8).unwrap(), - i8_align: Align::from_bits(8, 8).unwrap(), - i16_align: Align::from_bits(16, 16).unwrap(), - i32_align: Align::from_bits(32, 32).unwrap(), - i64_align: Align::from_bits(32, 64).unwrap(), - i128_align: Align::from_bits(32, 64).unwrap(), - f32_align: Align::from_bits(32, 32).unwrap(), - f64_align: Align::from_bits(64, 64).unwrap(), + i1_align: AbiAndPrefAlign::from_bits(8, 8).unwrap(), + i8_align: AbiAndPrefAlign::from_bits(8, 8).unwrap(), + i16_align: AbiAndPrefAlign::from_bits(16, 16).unwrap(), + i32_align: AbiAndPrefAlign::from_bits(32, 32).unwrap(), + i64_align: AbiAndPrefAlign::from_bits(32, 64).unwrap(), + i128_align: AbiAndPrefAlign::from_bits(32, 64).unwrap(), + f32_align: AbiAndPrefAlign::from_bits(32, 32).unwrap(), + f64_align: AbiAndPrefAlign::from_bits(64, 64).unwrap(), pointer_size: Size::from_bits(64), - pointer_align: Align::from_bits(64, 64).unwrap(), - aggregate_align: Align::from_bits(0, 64).unwrap(), + pointer_align: AbiAndPrefAlign::from_bits(64, 64).unwrap(), + aggregate_align: AbiAndPrefAlign::from_bits(0, 64).unwrap(), vector_align: vec![ - (Size::from_bits(64), Align::from_bits(64, 64).unwrap()), - (Size::from_bits(128), Align::from_bits(128, 128).unwrap()) + (Size::from_bits(64), AbiAndPrefAlign::from_bits(64, 64).unwrap()), + (Size::from_bits(128), AbiAndPrefAlign::from_bits(128, 128).unwrap()) ], instruction_address_space: 0, } @@ -96,7 +97,7 @@ pub fn parse(target: &Target) -> Result { } let abi = parse_bits(s[0], "alignment", cause)?; let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?; - Align::from_bits(abi, pref).map_err(|err| { + AbiAndPrefAlign::from_bits(abi, pref).map_err(|err| { format!("invalid alignment for `{}` in \"data-layout\": {}", cause, err) }) @@ -205,7 +206,7 @@ pub fn ptr_sized_integer(&self) -> Integer { } } - pub fn vector_align(&self, vec_size: Size) -> Align { + pub fn vector_align(&self, vec_size: Size) -> AbiAndPrefAlign { for &(size, align) in &self.vector_align { if size == vec_size { return align; @@ -214,7 +215,7 @@ pub fn vector_align(&self, vec_size: Size) -> Align { // Default to natural alignment, which is what LLVM does. // That is, use the size, rounded up to a power of 2. let align = vec_size.bytes().next_power_of_two(); - Align::from_bytes(align, align).unwrap() + AbiAndPrefAlign::from_bytes(align, align).unwrap() } } @@ -270,13 +271,13 @@ pub fn bits(self) -> u64 { } #[inline] - pub fn abi_align(self, align: Align) -> Size { + pub fn abi_align(self, align: AbiAndPrefAlign) -> Size { let mask = align.abi() - 1; Size::from_bytes((self.bytes() + mask) & !mask) } #[inline] - pub fn is_abi_aligned(self, align: Align) -> bool { + pub fn is_abi_aligned(self, align: AbiAndPrefAlign) -> bool { let mask = align.abi() - 1; self.bytes() & mask == 0 } @@ -358,23 +359,23 @@ fn add_assign(&mut self, other: Size) { } } -/// Alignment of a type in bytes, both ABI-mandated and preferred. +/// Alignments of a type in bytes, both ABI-mandated and preferred. /// Each field is a power of two, giving the alignment a maximum value /// of 2(28 - 1), which is limited by LLVM to a /// maximum capacity of 229 or 536870912. #[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)] -pub struct Align { +pub struct AbiAndPrefAlign { abi_pow2: u8, pref_pow2: u8, } -impl Align { - pub fn from_bits(abi: u64, pref: u64) -> Result { - Align::from_bytes(Size::from_bits(abi).bytes(), +impl AbiAndPrefAlign { + pub fn from_bits(abi: u64, pref: u64) -> Result { + AbiAndPrefAlign::from_bytes(Size::from_bits(abi).bytes(), Size::from_bits(pref).bytes()) } - pub fn from_bytes(abi: u64, pref: u64) -> Result { + pub fn from_bytes(abi: u64, pref: u64) -> Result { let log2 = |align: u64| { // Treat an alignment of 0 bytes like 1-byte alignment. if align == 0 { @@ -396,7 +397,7 @@ pub fn from_bytes(abi: u64, pref: u64) -> Result { } }; - Ok(Align { + Ok(AbiAndPrefAlign { abi_pow2: log2(abi)?, pref_pow2: log2(pref)?, }) @@ -418,15 +419,15 @@ pub fn pref_bits(self) -> u64 { self.pref() * 8 } - pub fn min(self, other: Align) -> Align { - Align { + pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { + AbiAndPrefAlign { abi_pow2: cmp::min(self.abi_pow2, other.abi_pow2), pref_pow2: cmp::min(self.pref_pow2, other.pref_pow2), } } - pub fn max(self, other: Align) -> Align { - Align { + pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { + AbiAndPrefAlign { abi_pow2: cmp::max(self.abi_pow2, other.abi_pow2), pref_pow2: cmp::max(self.pref_pow2, other.pref_pow2), } @@ -436,9 +437,9 @@ pub fn max(self, other: Align) -> Align { /// (the largest power of two that the offset is a multiple of). /// /// NB: for an offset of `0`, this happens to return `2^64`. - pub fn max_for_offset(offset: Size) -> Align { + pub fn max_for_offset(offset: Size) -> AbiAndPrefAlign { let pow2 = offset.bytes().trailing_zeros() as u8; - Align { + AbiAndPrefAlign { abi_pow2: pow2, pref_pow2: pow2, } @@ -446,8 +447,8 @@ pub fn max_for_offset(offset: Size) -> Align { /// Lower the alignment, if necessary, such that the given offset /// is aligned to it (the offset is a multiple of the alignment). - pub fn restrict_for_offset(self, offset: Size) -> Align { - self.min(Align::max_for_offset(offset)) + pub fn restrict_for_offset(self, offset: Size) -> AbiAndPrefAlign { + self.min(AbiAndPrefAlign::max_for_offset(offset)) } } @@ -472,7 +473,7 @@ pub fn size(self) -> Size { } } - pub fn align(self, cx: &C) -> Align { + pub fn align(self, cx: &C) -> AbiAndPrefAlign { let dl = cx.data_layout(); match self { @@ -507,7 +508,7 @@ pub fn fit_unsigned(x: u128) -> Integer { } /// Find the smallest integer with the given alignment. - pub fn for_abi_align(cx: &C, align: Align) -> Option { + pub fn for_abi_align(cx: &C, align: AbiAndPrefAlign) -> Option { let dl = cx.data_layout(); let wanted = align.abi(); @@ -520,7 +521,7 @@ pub fn for_abi_align(cx: &C, align: Align) -> Option } /// Find the largest integer with the given alignment or less. - pub fn approximate_abi_align(cx: &C, align: Align) -> Integer { + pub fn approximate_abi_align(cx: &C, align: AbiAndPrefAlign) -> Integer { let dl = cx.data_layout(); let wanted = align.abi(); @@ -597,7 +598,7 @@ pub fn size(self, cx: &C) -> Size { } } - pub fn align(self, cx: &C) -> Align { + pub fn align(self, cx: &C) -> AbiAndPrefAlign { let dl = cx.data_layout(); match self { @@ -868,7 +869,7 @@ pub struct LayoutDetails { pub variants: Variants, pub fields: FieldPlacement, pub abi: Abi, - pub align: Align, + pub align: AbiAndPrefAlign, pub size: Size } @@ -949,8 +950,4 @@ pub fn is_zst(&self) -> bool { Abi::Aggregate { sized } => sized && self.size.bytes() == 0 } } - - pub fn size_and_align(&self) -> (Size, Align) { - (self.size, self.align) - } } From 3ce8d444affefb61ee733aa21da7f1ebc1b515e9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 9 Sep 2018 00:22:22 +0300 Subject: [PATCH 63/75] rustc_target: separate out an individual Align from AbiAndPrefAlign. --- src/librustc/mir/interpret/allocation.rs | 4 +- src/librustc/mir/interpret/error.rs | 7 +- src/librustc/session/code_stats.rs | 2 +- src/librustc/ty/layout.rs | 32 +-- src/librustc_codegen_llvm/abi.rs | 4 +- src/librustc_codegen_llvm/builder.rs | 18 +- src/librustc_codegen_llvm/consts.rs | 10 +- .../debuginfo/metadata.rs | 28 +-- src/librustc_codegen_llvm/debuginfo/mod.rs | 2 +- src/librustc_codegen_llvm/intrinsic.rs | 12 +- src/librustc_codegen_llvm/type_of.rs | 10 +- src/librustc_codegen_ssa/glue.rs | 6 +- src/librustc_codegen_ssa/meth.rs | 2 +- src/librustc_codegen_ssa/mir/block.rs | 6 +- src/librustc_codegen_ssa/mir/operand.rs | 6 +- src/librustc_codegen_ssa/mir/place.rs | 8 +- src/librustc_codegen_ssa/mir/rvalue.rs | 2 +- src/librustc_mir/const_eval.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 4 +- src/librustc_mir/interpret/intrinsics.rs | 2 +- src/librustc_mir/interpret/memory.rs | 22 +- src/librustc_mir/interpret/place.rs | 15 +- src/librustc_mir/interpret/traits.rs | 6 +- src/librustc_mir/interpret/validity.rs | 4 +- src/librustc_mir/util/alignment.rs | 2 +- src/librustc_target/abi/call/arm.rs | 2 +- src/librustc_target/abi/call/powerpc64.rs | 6 +- src/librustc_target/abi/mod.rs | 194 +++++++++--------- src/librustc_typeck/check/mod.rs | 2 +- 29 files changed, 215 insertions(+), 205 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index eb44c3c8c5f7..4e83cc16ab3e 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -12,7 +12,7 @@ use super::{Pointer, EvalResult, AllocId}; -use ty::layout::{Size, AbiAndPrefAlign}; +use ty::layout::{Size, Align, AbiAndPrefAlign}; use syntax::ast::Mutability; use std::iter; use mir; @@ -104,7 +104,7 @@ pub fn from_bytes(slice: &[u8], align: AbiAndPrefAlign) -> Self { } pub fn from_byte_aligned_bytes(slice: &[u8]) -> Self { - Allocation::from_bytes(slice, AbiAndPrefAlign::from_bytes(1, 1).unwrap()) + Allocation::from_bytes(slice, AbiAndPrefAlign::new(Align::from_bytes(1).unwrap())) } pub fn undef(size: Size, align: AbiAndPrefAlign) -> Self { diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index bae53a9216a4..1a33d3623964 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -527,7 +527,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), AlignmentCheckFailed { required, has } => write!(f, "tried to access memory with alignment {}, but alignment {} is required", - has.abi(), required.abi()), + has.abi.bytes(), required.abi.bytes()), TypeNotPrimitive(ty) => write!(f, "expected primitive type, got {}", ty), Layout(ref err) => @@ -537,8 +537,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { MachineError(ref inner) => write!(f, "{}", inner), IncorrectAllocationInformation(size, size2, align, align2) => - write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and \ - align {}", size.bytes(), align.abi(), size2.bytes(), align2.abi()), + write!(f, "incorrect alloc info: expected size {} and align {}, \ + got size {} and align {}", + size.bytes(), align.abi.bytes(), size2.bytes(), align2.abi.bytes()), Panic { ref msg, line, col, ref file } => write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), InvalidDiscriminant(val) => diff --git a/src/librustc/session/code_stats.rs b/src/librustc/session/code_stats.rs index 34a89ccf7a21..7a5ac36420fb 100644 --- a/src/librustc/session/code_stats.rs +++ b/src/librustc/session/code_stats.rs @@ -71,7 +71,7 @@ pub fn record_type_size(&mut self, let info = TypeSizeInfo { kind, type_description: type_desc.to_string(), - align: align.abi(), + align: align.abi.bytes(), overall_size: overall_size.bytes(), packed: packed, opt_discr_size: opt_discr_size.map(|s| s.bytes()), diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 76c3c467febb..637686fd50ea 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -259,7 +259,7 @@ enum StructKind { let pack = { let pack = repr.pack as u64; - AbiAndPrefAlign::from_bytes(pack, pack).unwrap() + AbiAndPrefAlign::new(Align::from_bytes(pack).unwrap()) }; let mut align = if packed { @@ -274,7 +274,7 @@ enum StructKind { let mut optimize = !repr.inhibit_struct_field_reordering_opt(); if let StructKind::Prefixed(_, align) = kind { - optimize &= align.abi() == 1; + optimize &= align.abi.bytes() == 1; } if optimize { @@ -285,7 +285,7 @@ enum StructKind { }; let optimizing = &mut inverse_memory_index[..end]; let field_align = |f: &TyLayout<'_>| { - if packed { f.align.min(pack).abi() } else { f.align.abi() } + if packed { f.align.min(pack).abi } else { f.align.abi } }; match kind { StructKind::AlwaysSized | @@ -352,7 +352,7 @@ enum StructKind { if repr.align > 0 { let repr_align = repr.align as u64; - align = align.max(AbiAndPrefAlign::from_bytes(repr_align, repr_align).unwrap()); + align = align.max(AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap())); debug!("univariant repr_align: {:?}", repr_align); } @@ -394,7 +394,7 @@ enum StructKind { (Some((i, field)), None, None) => { // Field fills the struct and it has a scalar or scalar pair ABI. if offsets[i].bytes() == 0 && - align.abi() == field.align.abi() && + align.abi == field.align.abi && size == field.size { match field.abi { // For plain scalars, or vectors of them, we can't unpack @@ -682,7 +682,7 @@ enum StructKind { let pack = { let pack = def.repr.pack as u64; - AbiAndPrefAlign::from_bytes(pack, pack).unwrap() + AbiAndPrefAlign::new(Align::from_bytes(pack).unwrap()) }; let mut align = if packed { @@ -694,7 +694,7 @@ enum StructKind { if def.repr.align > 0 { let repr_align = def.repr.align as u64; align = align.max( - AbiAndPrefAlign::from_bytes(repr_align, repr_align).unwrap()); + AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap())); } let optimize = !def.repr.inhibit_union_abi_opt(); @@ -964,7 +964,7 @@ enum StructKind { let mut size = Size::ZERO; // We're interested in the smallest alignment, so start large. - let mut start_align = AbiAndPrefAlign::from_bytes(256, 256).unwrap(); + let mut start_align = AbiAndPrefAlign::new(Align::from_bytes(256).unwrap()); assert_eq!(Integer::for_abi_align(dl, start_align), None); // repr(C) on an enum tells us to make a (tag, union) layout, @@ -989,7 +989,7 @@ enum StructKind { // Find the first field we can't move later // to make room for a larger discriminant. for field in st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) { - if !field.is_zst() || field.align.abi() != 1 { + if !field.is_zst() || field.align.abi.bytes() != 1 { start_align = start_align.min(field.align); break; } @@ -1251,7 +1251,7 @@ fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) { name: name.to_string(), offset: offset.bytes(), size: field_layout.size.bytes(), - align: field_layout.align.abi(), + align: field_layout.align.abi.bytes(), } } } @@ -1264,7 +1264,7 @@ fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) { } else { session::SizeKind::Exact }, - align: layout.align.abi(), + align: layout.align.abi.bytes(), size: if min_size.bytes() == 0 { layout.size.bytes() } else { @@ -1994,12 +1994,16 @@ fn hash_stable(&self, Pointer }); -impl<'gcx> HashStable> for AbiAndPrefAlign { +impl_stable_hash_for!(struct ::ty::layout::AbiAndPrefAlign { + abi, + pref +}); + +impl<'gcx> HashStable> for Align { fn hash_stable(&self, hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher) { - self.abi().hash_stable(hcx, hasher); - self.pref().hash_stable(hcx, hasher); + self.bytes().hash_stable(hcx, hasher); } } diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index 76fc5a6eeec7..ccab0ce69e3a 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -73,7 +73,7 @@ fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) { if let Some(align) = self.pointee_align { llvm::LLVMRustAddAlignmentAttr(llfn, idx.as_uint(), - align.abi() as u32); + align.abi.bytes() as u32); } regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn)); } @@ -98,7 +98,7 @@ fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) { if let Some(align) = self.pointee_align { llvm::LLVMRustAddAlignmentCallSiteAttr(callsite, idx.as_uint(), - align.abi() as u32); + align.abi.bytes() as u32); } regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite)); } diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 38400946a914..8da64edc92f0 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -475,7 +475,7 @@ fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: AbiAndPrefAlign) llvm::LLVMBuildAlloca(self.llbuilder, ty, name.as_ptr()) }; - llvm::LLVMSetAlignment(alloca, align.abi() as c_uint); + llvm::LLVMSetAlignment(alloca, align.abi.bytes() as c_uint); alloca } } @@ -494,7 +494,7 @@ fn array_alloca(&mut self, llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, name.as_ptr()) }; - llvm::LLVMSetAlignment(alloca, align.abi() as c_uint); + llvm::LLVMSetAlignment(alloca, align.abi.bytes() as c_uint); alloca } } @@ -503,7 +503,7 @@ fn load(&mut self, ptr: &'ll Value, align: AbiAndPrefAlign) -> &'ll Value { self.count_insn("load"); unsafe { let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname()); - llvm::LLVMSetAlignment(load, align.abi() as c_uint); + llvm::LLVMSetAlignment(load, align.abi.bytes() as c_uint); load } } @@ -658,7 +658,7 @@ fn store_with_flags( let align = if flags.contains(MemFlags::UNALIGNED) { 1 } else { - align.abi() as c_uint + align.abi.bytes() as c_uint }; llvm::LLVMSetAlignment(store, align); if flags.contains(MemFlags::VOLATILE) { @@ -893,8 +893,8 @@ fn memcpy(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, let dst = self.pointercast(dst, self.cx().type_i8p()); let src = self.pointercast(src, self.cx().type_i8p()); unsafe { - llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.abi() as c_uint, - src, src_align.abi() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.abi.bytes() as c_uint, + src, src_align.abi.bytes() as c_uint, size, is_volatile); } } @@ -913,8 +913,8 @@ fn memmove(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, let dst = self.pointercast(dst, self.cx().type_i8p()); let src = self.pointercast(src, self.cx().type_i8p()); unsafe { - llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.abi() as c_uint, - src, src_align.abi() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.abi.bytes() as c_uint, + src, src_align.abi.bytes() as c_uint, size, is_volatile); } } @@ -930,7 +930,7 @@ fn memset( let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width); let llintrinsicfn = self.cx().get_intrinsic(&intrinsic_key); let ptr = self.pointercast(ptr, self.cx().type_i8p()); - let align = self.cx().const_u32(align.abi() as u32); + let align = self.cx().const_u32(align.abi.bytes() as u32); let volatile = self.cx().const_bool(flags.contains(MemFlags::VOLATILE)); self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None); } diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 158bc6eb9c10..b5b2e22fed06 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -28,7 +28,7 @@ use rustc::ty::{self, Ty}; use rustc_codegen_ssa::traits::*; -use rustc::ty::layout::{self, Size, AbiAndPrefAlign, LayoutOf}; +use rustc::ty::layout::{self, Size, Align, AbiAndPrefAlign, LayoutOf}; use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags}; @@ -94,15 +94,15 @@ fn set_global_alignment(cx: &CodegenCx<'ll, '_>, // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. if let Some(min) = cx.sess().target.target.options.min_global_align { - match ty::layout::AbiAndPrefAlign::from_bits(min, min) { - Ok(min) => align = align.max(min), + match Align::from_bits(min) { + Ok(min) => align = align.max(AbiAndPrefAlign::new(min)), Err(err) => { cx.sess().err(&format!("invalid minimum global alignment: {}", err)); } } } unsafe { - llvm::LLVMSetAlignment(gv, align.abi() as u32); + llvm::LLVMSetAlignment(gv, align.abi.bytes() as u32); } } @@ -219,7 +219,7 @@ fn static_addr_of( unsafe { // Upgrade the alignment in cases where the same constant is used with different // alignment requirements - let llalign = align.abi() as u32; + let llalign = align.abi.bytes() as u32; if llalign > llvm::LLVMGetAlignment(gv) { llvm::LLVMSetAlignment(gv, llalign); } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 42b48b728fd0..4cee39570423 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -323,7 +323,7 @@ fn fixed_vec_metadata( llvm::LLVMRustDIBuilderCreateArrayType( DIB(cx), size.bits(), - align.abi_bits() as u32, + align.abi.bits() as u32, element_type_metadata, subscripts) }; @@ -787,7 +787,7 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { DIB(cx), name.as_ptr(), size.bits(), - align.abi_bits() as u32, + align.abi.bits() as u32, encoding) }; @@ -818,7 +818,7 @@ fn pointer_type_metadata( DIB(cx), pointee_type_metadata, pointer_size.bits(), - pointer_align.abi_bits() as u32, + pointer_align.abi.bits() as u32, name.as_ptr()) } } @@ -1563,7 +1563,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, discriminant_size.bits(), - discriminant_align.abi_bits() as u32, + discriminant_align.abi.bits() as u32, create_DIArray(DIB(cx), &enumerators_metadata), discriminant_base_type_metadata, true) }; @@ -1607,7 +1607,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, layout.size.bits(), - layout.align.abi_bits() as u32, + layout.align.abi.bits() as u32, DIFlags::FlagZero, None, 0, // RuntimeLang @@ -1655,7 +1655,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, size.bits(), - align.abi_bits() as u32, + align.abi.bits() as u32, layout.fields.offset(0).bits(), DIFlags::FlagArtificial, discr_metadata)) @@ -1675,7 +1675,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, size.bits(), - align.abi_bits() as u32, + align.abi.bits() as u32, layout.fields.offset(0).bits(), DIFlags::FlagArtificial, discr_metadata)) @@ -1692,7 +1692,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, layout.size.bits(), - layout.align.abi_bits() as u32, + layout.align.abi.bits() as u32, DIFlags::FlagZero, discriminator_metadata, empty_array, @@ -1709,7 +1709,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, layout.size.bits(), - layout.align.abi_bits() as u32, + layout.align.abi.bits() as u32, DIFlags::FlagZero, None, type_array, @@ -1803,7 +1803,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>, unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, member_description.size.bits(), - member_description.align.abi_bits() as u32, + member_description.align.abi.bits() as u32, member_description.offset.bits(), match member_description.discriminant { None => None, @@ -1851,7 +1851,7 @@ fn create_struct_stub( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, struct_size.bits(), - struct_align.abi_bits() as u32, + struct_align.abi.bits() as u32, DIFlags::FlagZero, None, empty_array, @@ -1889,7 +1889,7 @@ fn create_union_stub( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, union_size.bits(), - union_align.abi_bits() as u32, + union_align.abi.bits() as u32, DIFlags::FlagZero, Some(empty_array), 0, // RuntimeLang @@ -1958,7 +1958,7 @@ pub fn create_global_var_metadata( is_local_to_unit, global, None, - global_align.abi() as u32, + global_align.abi.bytes() as u32, ); } } @@ -1996,7 +1996,7 @@ pub fn create_vtable_metadata( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, Size::ZERO.bits(), - cx.tcx.data_layout.pointer_align.abi_bits() as u32, + cx.tcx.data_layout.pointer_align.abi.bits() as u32, DIFlags::FlagArtificial, None, empty_array, diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 9784cc6cf9c8..199402982c6e 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -201,7 +201,7 @@ fn declare_local( cx.sess().opts.optimize != config::OptLevel::No, DIFlags::FlagZero, argument_index, - align.abi() as u32, + align.abi.bytes() as u32, ) }; source_loc::set_debug_location(self, diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index b2f1f933da4d..1756fd5b0b19 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -158,7 +158,7 @@ fn codegen_intrinsic_call( } "min_align_of" => { let tp_ty = substs.type_at(0); - self.cx().const_usize(self.cx().align_of(tp_ty).abi()) + self.cx().const_usize(self.cx().align_of(tp_ty).abi.bytes()) } "min_align_of_val" => { let tp_ty = substs.type_at(0); @@ -167,12 +167,12 @@ fn codegen_intrinsic_call( glue::size_and_align_of_dst(self, tp_ty, Some(meta)); llalign } else { - self.cx().const_usize(self.cx().align_of(tp_ty).abi()) + self.cx().const_usize(self.cx().align_of(tp_ty).abi.bytes()) } } "pref_align_of" => { let tp_ty = substs.type_at(0); - self.cx().const_usize(self.cx().align_of(tp_ty).pref()) + self.cx().const_usize(self.cx().align_of(tp_ty).pref.bytes()) } "type_name" => { let tp_ty = substs.type_at(0); @@ -261,7 +261,7 @@ fn codegen_intrinsic_call( let align = if name == "unaligned_volatile_load" { 1 } else { - self.cx().align_of(tp_ty).abi() as u32 + self.cx().align_of(tp_ty).abi.bytes() as u32 }; unsafe { llvm::LLVMSetAlignment(load, align); @@ -1436,7 +1436,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty { // Alignment of T, must be a constant integer value: let alignment_ty = bx.cx().type_i32(); - let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi() as i32); + let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi.bytes() as i32); // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { @@ -1536,7 +1536,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty { // Alignment of T, must be a constant integer value: let alignment_ty = bx.cx().type_i32(); - let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi() as i32); + let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi.bytes() as i32); // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index a07fa9448919..8ce3be36d0bb 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -125,14 +125,14 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, for i in layout.fields.index_by_increasing_offset() { let target_offset = layout.fields.offset(i as usize); let field = layout.field(cx, i); - let effective_field_align = layout.align - .min(field.align) - .restrict_for_offset(target_offset); - packed |= effective_field_align.abi() < field.align.abi(); + let effective_field_align = AbiAndPrefAlign::new(layout.align.abi + .min(field.align.abi) + .restrict_for_offset(target_offset)); + packed |= effective_field_align.abi < field.align.abi; debug!("struct_llfields: {}: {:?} offset: {:?} target_offset: {:?} \ effective_field_align: {}", - i, field, offset, target_offset, effective_field_align.abi()); + i, field, offset, target_offset, effective_field_align.abi.bytes()); assert!(target_offset >= offset); let padding = target_offset - offset; let padding_align = prev_effective_align.min(effective_field_align); diff --git a/src/librustc_codegen_ssa/glue.rs b/src/librustc_codegen_ssa/glue.rs index bf4c53f228e3..bb28ea74dc00 100644 --- a/src/librustc_codegen_ssa/glue.rs +++ b/src/librustc_codegen_ssa/glue.rs @@ -30,7 +30,7 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( t, info, layout); if !layout.is_unsized() { let size = bx.cx().const_usize(layout.size.bytes()); - let align = bx.cx().const_usize(layout.align.abi()); + let align = bx.cx().const_usize(layout.align.abi.bytes()); return (size, align); } match t.sty { @@ -44,7 +44,7 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( // The info in this case is the length of the str, so the size is that // times the unit size. (bx.mul(info.unwrap(), bx.cx().const_usize(unit.size.bytes())), - bx.cx().const_usize(unit.align.abi())) + bx.cx().const_usize(unit.align.abi.bytes())) } _ => { // First get the size of all statically known fields. @@ -55,7 +55,7 @@ pub fn size_and_align_of_dst<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let i = layout.fields.count() - 1; let sized_size = layout.fields.offset(i).bytes(); - let sized_align = layout.align.abi(); + let sized_align = layout.align.abi.bytes(); debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align); let sized_size = bx.cx().const_usize(sized_size); diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index d0b8c166b121..60268533c85d 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -108,7 +108,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( let components: Vec<_> = [ cx.get_fn(monomorphize::resolve_drop_in_place(cx.tcx(), ty)), cx.const_usize(layout.size.bytes()), - cx.const_usize(layout.align.abi()) + cx.const_usize(layout.align.abi.bytes()) ].iter().cloned().chain(methods).collect(); let vtable_const = cx.const_struct(&components, false); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 1702ad19b76f..693addd441ff 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -280,7 +280,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( scratch.llval } Ref(llval, _, align) => { - assert_eq!(align.abi(), op.layout.align.abi(), + assert_eq!(align.abi, op.layout.align.abi, "return place is unaligned!"); llval } @@ -805,7 +805,7 @@ fn codegen_argument( } } Ref(llval, _, align) => { - if arg.is_indirect() && align.abi() < arg.layout.align.abi() { + if arg.is_indirect() && align.abi < arg.layout.align.abi { // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't // have scary latent bugs around. @@ -1006,7 +1006,7 @@ fn make_return_dest( self.codegen_place(bx, dest) }; if fn_ret.is_indirect() { - if dest.align.abi() < dest.layout.align.abi() { + if dest.align.abi < dest.layout.align.abi { // Currently, MIR code generation does not create calls // that store directly to fields of packed structs (in // fact, the calls it creates write only to temps), diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 4c92ab7eda5b..c604386456c4 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -11,7 +11,7 @@ use rustc::mir::interpret::{ConstValue, ErrorHandled}; use rustc::mir; use rustc::ty; -use rustc::ty::layout::{self, AbiAndPrefAlign, LayoutOf, TyLayout}; +use rustc::ty::layout::{self, Align, AbiAndPrefAlign, LayoutOf, TyLayout}; use base; use MemFlags; @@ -348,8 +348,8 @@ pub fn store_unsized>( }; // FIXME: choose an appropriate alignment, or use dynamic align somehow - let max_align = AbiAndPrefAlign::from_bits(128, 128).unwrap(); - let min_align = AbiAndPrefAlign::from_bits(8, 8).unwrap(); + let max_align = AbiAndPrefAlign::new(Align::from_bits(128).unwrap()); + let min_align = AbiAndPrefAlign::new(Align::from_bits(8).unwrap()); // Allocate an appropriate region on the stack, and copy the value into it let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index e6216c8724f5..f78f7a50561d 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -101,7 +101,7 @@ pub fn project_field>( ) -> Self { let field = self.layout.field(bx.cx(), ix); let offset = self.layout.fields.offset(ix); - let effective_field_align = self.align.restrict_for_offset(offset); + let effective_field_align = self.align.abi.restrict_for_offset(offset); let mut simple = || { // Unions and newtypes only use an offset of 0. @@ -123,7 +123,7 @@ pub fn project_field>( None }, layout: field, - align: effective_field_align, + align: AbiAndPrefAlign::new(effective_field_align), } }; @@ -143,7 +143,7 @@ pub fn project_field>( if def.repr.packed() { // FIXME(eddyb) generalize the adjustment when we // start supporting packing to larger alignments. - assert_eq!(self.layout.align.abi(), 1); + assert_eq!(self.layout.align.abi.bytes(), 1); return simple(); } } @@ -197,7 +197,7 @@ pub fn project_field>( llval: bx.pointercast(byte_ptr, bx.cx().type_ptr_to(ll_fty)), llextra: self.llextra, layout: field, - align: effective_field_align, + align: AbiAndPrefAlign::new(effective_field_align), } } diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 167a143ec31e..805c1a343d04 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -499,7 +499,7 @@ pub fn codegen_rvalue_operand( let content_ty = self.monomorphize(&content_ty); let content_layout = bx.cx().layout_of(content_ty); let llsize = bx.cx().const_usize(content_layout.size.bytes()); - let llalign = bx.cx().const_usize(content_layout.align.abi()); + let llalign = bx.cx().const_usize(content_layout.align.abi.bytes()); let box_layout = bx.cx().layout_of(bx.tcx().mk_box(content_ty)); let llty_ptr = bx.cx().backend_type(box_layout); diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 3b32fe21adf8..6a8a9fe817c0 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -129,7 +129,7 @@ pub fn op_to_const<'tcx>( assert!(meta.is_none()); let ptr = ptr.to_ptr()?; let alloc = ecx.memory.get(ptr.alloc_id)?; - assert!(alloc.align.abi() >= align.abi()); + assert!(alloc.align.abi >= align.abi); assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= op.layout.size.bytes()); let mut alloc = alloc.clone(); alloc.align = align; diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 69db638270a5..b3e9008a6b73 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -636,7 +636,7 @@ pub fn dump_place(&self, place: Place) { let (ptr, align) = mplace.to_scalar_ptr_align(); match ptr { Scalar::Ptr(ptr) => { - write!(msg, " by align({}) ref:", align.abi()).unwrap(); + write!(msg, " by align({}) ref:", align.abi.bytes()).unwrap(); allocs.push(ptr.alloc_id); } ptr => write!(msg, " by integral ref: {:?}", ptr).unwrap(), @@ -665,7 +665,7 @@ pub fn dump_place(&self, place: Place) { Place::Ptr(mplace) => { match mplace.ptr { Scalar::Ptr(ptr) => { - trace!("by align({}) ref:", mplace.align.abi()); + trace!("by align({}) ref:", mplace.align.abi.bytes()); self.memory.dump_alloc(ptr.alloc_id); } ptr => trace!(" integral by ref: {:?}", ptr), diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 7ef940059705..bbee6e0b49ae 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -60,7 +60,7 @@ pub fn emulate_intrinsic( match intrinsic_name { "min_align_of" => { let elem_ty = substs.type_at(0); - let elem_align = self.layout_of(elem_ty)?.align.abi(); + let elem_align = self.layout_of(elem_ty)?.align.abi.bytes(); let align_val = Scalar::from_uint(elem_align, dest.layout.size); self.write_scalar(align_val, dest)?; } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index dbb0e5228748..681e73297542 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -21,7 +21,7 @@ use std::borrow::Cow; use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; -use rustc::ty::layout::{self, AbiAndPrefAlign, TargetDataLayout, Size, HasDataLayout}; +use rustc::ty::layout::{self, Align, AbiAndPrefAlign, TargetDataLayout, Size, HasDataLayout}; pub use rustc::mir::interpret::{truncate, write_target_uint, read_target_uint}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; @@ -268,18 +268,18 @@ pub fn check_align( } }; // Check alignment - if alloc_align.abi() < required_align.abi() { + if alloc_align.abi < required_align.abi { return err!(AlignmentCheckFailed { has: alloc_align, required: required_align, }); } - if offset % required_align.abi() == 0 { + if offset % required_align.abi.bytes() == 0 { Ok(()) } else { - let has = offset % required_align.abi(); + let has = offset % required_align.abi.bytes(); err!(AlignmentCheckFailed { - has: AbiAndPrefAlign::from_bytes(has, has).unwrap(), + has: AbiAndPrefAlign::new(Align::from_bytes(has).unwrap()), required: required_align, }) } @@ -450,7 +450,7 @@ pub fn get_size_and_align(&self, id: AllocId) -> (Size, AbiAndPrefAlign) { // Could also be a fn ptr or extern static match self.tcx.alloc_map.lock().get(id) { Some(AllocType::Function(..)) => { - (Size::ZERO, AbiAndPrefAlign::from_bytes(1, 1).unwrap()) + (Size::ZERO, AbiAndPrefAlign::new(Align::from_bytes(1).unwrap())) } Some(AllocType::Static(did)) => { // The only way `get` couldn't have worked here is if this is an extern static @@ -523,7 +523,7 @@ fn dump_alloc_helper( "{}({} bytes, alignment {}){}", msg, alloc.bytes.len(), - alloc.align.abi(), + alloc.align.abi.bytes(), extra ); @@ -865,7 +865,7 @@ pub fn check_bytes( allow_ptr_and_undef: bool, ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); @@ -883,7 +883,7 @@ pub fn check_bytes( pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<'tcx, &[u8]> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(&[]); @@ -893,7 +893,7 @@ pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<' pub fn write_bytes(&mut self, ptr: Scalar, src: &[u8]) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); if src.is_empty() { self.check_align(ptr, align)?; return Ok(()); @@ -910,7 +910,7 @@ pub fn write_repeat( count: Size ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::from_bytes(1, 1).unwrap(); + let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); if count.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index bd713d4462d0..ed8b7cf1f90d 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -18,7 +18,8 @@ use rustc::hir; use rustc::mir; use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, Size, AbiAndPrefAlign, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; +use rustc::ty::layout::{self, Size, Align, + AbiAndPrefAlign, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; use super::{ GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic, @@ -127,7 +128,8 @@ pub fn from_scalar_ptr(ptr: Scalar, align: AbiAndPrefAlign) -> Self { /// Produces a Place that will error if attempted to be read from or written to #[inline(always)] pub fn null(cx: &impl HasDataLayout) -> Self { - Self::from_scalar_ptr(Scalar::ptr_null(cx), AbiAndPrefAlign::from_bytes(1, 1).unwrap()) + Self::from_scalar_ptr(Scalar::ptr_null(cx), + AbiAndPrefAlign::new(Align::from_bytes(1).unwrap())) } #[inline(always)] @@ -167,7 +169,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> { pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self { MPlaceTy { mplace: MemPlace::from_scalar_ptr( - Scalar::from_uint(layout.align.abi(), cx.pointer_size()), + Scalar::from_uint(layout.align.abi.bytes(), cx.pointer_size()), layout.align ), layout @@ -368,10 +370,10 @@ pub fn mplace_field( }; let ptr = base.ptr.ptr_offset(offset, self)?; - let align = base.align + let align = AbiAndPrefAlign::new(base.align.abi // We do not look at `base.layout.align` nor `field_layout.align`, unlike // codegen -- mostly to see if we can get away with that - .restrict_for_offset(offset); // must be last thing that happens + .restrict_for_offset(offset)); // must be last thing that happens Ok(MPlaceTy { mplace: MemPlace { ptr, align, meta }, layout: field_layout }) } @@ -998,7 +1000,8 @@ pub(super) fn unpack_dyn_trait(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) if cfg!(debug_assertions) { let (size, align) = self.read_size_and_align_from_vtable(vtable)?; assert_eq!(size, layout.size); - assert_eq!(align.abi(), layout.align.abi()); // only ABI alignment is preserved + // only ABI alignment is preserved + assert_eq!(align.abi, layout.align.abi); } let mplace = MPlaceTy { diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index f1bedd181e9e..02843b898124 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::{self, Ty}; -use rustc::ty::layout::{Size, AbiAndPrefAlign, LayoutOf}; +use rustc::ty::layout::{Size, Align, AbiAndPrefAlign, LayoutOf}; use rustc::mir::interpret::{Scalar, Pointer, EvalResult, PointerArithmetic}; use super::{EvalContext, Machine, MemoryKind}; @@ -42,7 +42,7 @@ pub fn get_vtable( let layout = self.layout_of(ty)?; assert!(!layout.is_unsized(), "can't create a vtable for an unsized type"); let size = layout.size.bytes(); - let align = layout.align.abi(); + let align = layout.align.abi.bytes(); let ptr_size = self.pointer_size(); let ptr_align = self.tcx.data_layout.pointer_align; @@ -110,6 +110,6 @@ pub fn read_size_and_align_from_vtable( vtable.offset(pointer_size * 2, self)?, pointer_align )?.to_bits(pointer_size)? as u64; - Ok((Size::from_bytes(size), AbiAndPrefAlign::from_bytes(align, align).unwrap())) + Ok((Size::from_bytes(size), AbiAndPrefAlign::new(Align::from_bytes(align).unwrap()))) } } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 41358fe0d848..352569b3b64f 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -13,7 +13,7 @@ use std::ops::RangeInclusive; use syntax_pos::symbol::Symbol; -use rustc::ty::layout::{self, Size, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx}; +use rustc::ty::layout::{self, Size, Align, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx}; use rustc::ty; use rustc_data_structures::fx::FxHashSet; use rustc::mir::interpret::{ @@ -463,7 +463,7 @@ fn visit_scalar( // for function pointers. let non_null = self.ecx.memory.check_align( - Scalar::Ptr(ptr), AbiAndPrefAlign::from_bytes(1, 1).unwrap() + Scalar::Ptr(ptr), AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()) ).is_ok() || self.ecx.memory.get_fn(ptr).is_ok(); if !non_null { diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs index 8717bd08ae4a..a96c5dd68706 100644 --- a/src/librustc_mir/util/alignment.rs +++ b/src/librustc_mir/util/alignment.rs @@ -30,7 +30,7 @@ pub fn is_disaligned<'a, 'tcx, L>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let ty = place.ty(local_decls, tcx).to_ty(tcx); match tcx.layout_raw(param_env.and(ty)) { - Ok(layout) if layout.align.abi() == 1 => { + Ok(layout) if layout.align.abi.bytes() == 1 => { // if the alignment is 1, the type can't be further // disaligned. debug!("is_disaligned({:?}) - align = 1", place); diff --git a/src/librustc_target/abi/call/arm.rs b/src/librustc_target/abi/call/arm.rs index b4ffae7385aa..bf497c09bdc7 100644 --- a/src/librustc_target/abi/call/arm.rs +++ b/src/librustc_target/abi/call/arm.rs @@ -93,7 +93,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, vfp: bool) } } - let align = arg.layout.align.abi(); + let align = arg.layout.align.abi.bytes(); let total = arg.layout.size; arg.cast_to(Uniform { unit: if align <= 4 { Reg::i32() } else { Reg::i64() }, diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 93b8f79ccdc0..7d78d1d75d52 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -13,7 +13,7 @@ // need to be fixed when PowerPC vector support is added. use abi::call::{FnType, ArgType, Reg, RegKind, Uniform}; -use abi::{AbiAndPrefAlign, Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; +use abi::{Endian, HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; use spec::HasTargetSpec; #[derive(Debug, Clone, Copy, PartialEq)] @@ -120,8 +120,8 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI) } else { // Aggregates larger than a doubleword should be padded // at the tail to fill out a whole number of doublewords. - let align = AbiAndPrefAlign::from_bits(64, 64).unwrap(); - (Reg::i64(), size.abi_align(align)) + let reg_i64 = Reg::i64(); + (reg_i64, size.abi_align(reg_i64.align(cx))) }; arg.cast_to(Uniform { diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 7b0b34e207ce..2eabe94754de 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -13,7 +13,7 @@ use spec::Target; -use std::{cmp, fmt}; +use std::fmt; use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; @@ -45,22 +45,23 @@ pub struct TargetDataLayout { impl Default for TargetDataLayout { /// Creates an instance of `TargetDataLayout`. fn default() -> TargetDataLayout { + let align = |bits| Align::from_bits(bits).unwrap(); TargetDataLayout { endian: Endian::Big, - i1_align: AbiAndPrefAlign::from_bits(8, 8).unwrap(), - i8_align: AbiAndPrefAlign::from_bits(8, 8).unwrap(), - i16_align: AbiAndPrefAlign::from_bits(16, 16).unwrap(), - i32_align: AbiAndPrefAlign::from_bits(32, 32).unwrap(), - i64_align: AbiAndPrefAlign::from_bits(32, 64).unwrap(), - i128_align: AbiAndPrefAlign::from_bits(32, 64).unwrap(), - f32_align: AbiAndPrefAlign::from_bits(32, 32).unwrap(), - f64_align: AbiAndPrefAlign::from_bits(64, 64).unwrap(), + i1_align: AbiAndPrefAlign::new(align(8)), + i8_align: AbiAndPrefAlign::new(align(8)), + i16_align: AbiAndPrefAlign::new(align(16)), + i32_align: AbiAndPrefAlign::new(align(32)), + i64_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, + i128_align: AbiAndPrefAlign { abi: align(32), pref: align(64) }, + f32_align: AbiAndPrefAlign::new(align(32)), + f64_align: AbiAndPrefAlign::new(align(64)), pointer_size: Size::from_bits(64), - pointer_align: AbiAndPrefAlign::from_bits(64, 64).unwrap(), - aggregate_align: AbiAndPrefAlign::from_bits(0, 64).unwrap(), + pointer_align: AbiAndPrefAlign::new(align(64)), + aggregate_align: AbiAndPrefAlign { abi: align(0), pref: align(64) }, vector_align: vec![ - (Size::from_bits(64), AbiAndPrefAlign::from_bits(64, 64).unwrap()), - (Size::from_bits(128), AbiAndPrefAlign::from_bits(128, 128).unwrap()) + (Size::from_bits(64), AbiAndPrefAlign::new(align(64))), + (Size::from_bits(128), AbiAndPrefAlign::new(align(128))), ], instruction_address_space: 0, } @@ -95,11 +96,17 @@ pub fn parse(target: &Target) -> Result { if s.is_empty() { return Err(format!("missing alignment for `{}` in \"data-layout\"", cause)); } + let align_from_bits = |bits| { + Align::from_bits(bits).map_err(|err| { + format!("invalid alignment for `{}` in \"data-layout\": {}", + cause, err) + }) + }; let abi = parse_bits(s[0], "alignment", cause)?; let pref = s.get(1).map_or(Ok(abi), |pref| parse_bits(pref, "alignment", cause))?; - AbiAndPrefAlign::from_bits(abi, pref).map_err(|err| { - format!("invalid alignment for `{}` in \"data-layout\": {}", - cause, err) + Ok(AbiAndPrefAlign { + abi: align_from_bits(abi)?, + pref: align_from_bits(pref)?, }) }; @@ -214,8 +221,7 @@ pub fn vector_align(&self, vec_size: Size) -> AbiAndPrefAlign { } // Default to natural alignment, which is what LLVM does. // That is, use the size, rounded up to a power of 2. - let align = vec_size.bytes().next_power_of_two(); - AbiAndPrefAlign::from_bytes(align, align).unwrap() + AbiAndPrefAlign::new(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap()) } } @@ -272,13 +278,13 @@ pub fn bits(self) -> u64 { #[inline] pub fn abi_align(self, align: AbiAndPrefAlign) -> Size { - let mask = align.abi() - 1; + let mask = align.abi.bytes() - 1; Size::from_bytes((self.bytes() + mask) & !mask) } #[inline] pub fn is_abi_aligned(self, align: AbiAndPrefAlign) -> bool { - let mask = align.abi() - 1; + let mask = align.abi.bytes() - 1; self.bytes() & mask == 0 } @@ -359,96 +365,92 @@ fn add_assign(&mut self, other: Size) { } } -/// Alignments of a type in bytes, both ABI-mandated and preferred. -/// Each field is a power of two, giving the alignment a maximum value -/// of 2(28 - 1), which is limited by LLVM to a -/// maximum capacity of 229 or 536870912. -#[derive(Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Debug, RustcEncodable, RustcDecodable)] -pub struct AbiAndPrefAlign { - abi_pow2: u8, - pref_pow2: u8, +/// Alignment of a type in bytes (always a power of two). +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +pub struct Align { + pow2: u8, } -impl AbiAndPrefAlign { - pub fn from_bits(abi: u64, pref: u64) -> Result { - AbiAndPrefAlign::from_bytes(Size::from_bits(abi).bytes(), - Size::from_bits(pref).bytes()) +impl Align { + pub fn from_bits(bits: u64) -> Result { + Align::from_bytes(Size::from_bits(bits).bytes()) } - pub fn from_bytes(abi: u64, pref: u64) -> Result { - let log2 = |align: u64| { - // Treat an alignment of 0 bytes like 1-byte alignment. - if align == 0 { - return Ok(0); - } - - let mut bytes = align; - let mut pow: u8 = 0; - while (bytes & 1) == 0 { - pow += 1; - bytes >>= 1; - } - if bytes != 1 { - Err(format!("`{}` is not a power of 2", align)) - } else if pow > 29 { - Err(format!("`{}` is too large", align)) - } else { - Ok(pow) - } - }; - - Ok(AbiAndPrefAlign { - abi_pow2: log2(abi)?, - pref_pow2: log2(pref)?, - }) - } - - pub fn abi(self) -> u64 { - 1 << self.abi_pow2 - } - - pub fn pref(self) -> u64 { - 1 << self.pref_pow2 - } - - pub fn abi_bits(self) -> u64 { - self.abi() * 8 - } - - pub fn pref_bits(self) -> u64 { - self.pref() * 8 - } - - pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { - AbiAndPrefAlign { - abi_pow2: cmp::min(self.abi_pow2, other.abi_pow2), - pref_pow2: cmp::min(self.pref_pow2, other.pref_pow2), + pub fn from_bytes(align: u64) -> Result { + // Treat an alignment of 0 bytes like 1-byte alignment. + if align == 0 { + return Ok(Align { pow2: 0 }); } + + let mut bytes = align; + let mut pow2: u8 = 0; + while (bytes & 1) == 0 { + pow2 += 1; + bytes >>= 1; + } + if bytes != 1 { + return Err(format!("`{}` is not a power of 2", align)); + } + if pow2 > 29 { + return Err(format!("`{}` is too large", align)); + } + + Ok(Align { pow2 }) } - pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { - AbiAndPrefAlign { - abi_pow2: cmp::max(self.abi_pow2, other.abi_pow2), - pref_pow2: cmp::max(self.pref_pow2, other.pref_pow2), - } + pub fn bytes(self) -> u64 { + 1 << self.pow2 + } + + pub fn bits(self) -> u64 { + self.bytes() * 8 } /// Compute the best alignment possible for the given offset /// (the largest power of two that the offset is a multiple of). /// /// NB: for an offset of `0`, this happens to return `2^64`. - pub fn max_for_offset(offset: Size) -> AbiAndPrefAlign { - let pow2 = offset.bytes().trailing_zeros() as u8; - AbiAndPrefAlign { - abi_pow2: pow2, - pref_pow2: pow2, + pub fn max_for_offset(offset: Size) -> Align { + Align { + pow2: offset.bytes().trailing_zeros() as u8, } } /// Lower the alignment, if necessary, such that the given offset /// is aligned to it (the offset is a multiple of the alignment). - pub fn restrict_for_offset(self, offset: Size) -> AbiAndPrefAlign { - self.min(AbiAndPrefAlign::max_for_offset(offset)) + pub fn restrict_for_offset(self, offset: Size) -> Align { + self.min(Align::max_for_offset(offset)) + } +} + +/// A pair of aligments, ABI-mandated and preferred. +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(PartialOrd, Ord)] // FIXME(eddyb) remove (error prone/incorrect) +pub struct AbiAndPrefAlign { + pub abi: Align, + pub pref: Align, +} + +impl AbiAndPrefAlign { + pub fn new(align: Align) -> AbiAndPrefAlign { + AbiAndPrefAlign { + abi: align, + pref: align, + } + } + + pub fn min(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { + AbiAndPrefAlign { + abi: self.abi.min(other.abi), + pref: self.pref.min(other.pref), + } + } + + pub fn max(self, other: AbiAndPrefAlign) -> AbiAndPrefAlign { + AbiAndPrefAlign { + abi: self.abi.max(other.abi), + pref: self.pref.max(other.pref), + } } } @@ -511,9 +513,9 @@ pub fn fit_unsigned(x: u128) -> Integer { pub fn for_abi_align(cx: &C, align: AbiAndPrefAlign) -> Option { let dl = cx.data_layout(); - let wanted = align.abi(); + let wanted = align.abi; for &candidate in &[I8, I16, I32, I64, I128] { - if wanted == candidate.align(dl).abi() && wanted == candidate.size().bytes() { + if wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes() { return Some(candidate); } } @@ -524,10 +526,10 @@ pub fn for_abi_align(cx: &C, align: AbiAndPrefAlign) -> Option pub fn approximate_abi_align(cx: &C, align: AbiAndPrefAlign) -> Integer { let dl = cx.data_layout(); - let wanted = align.abi(); + let wanted = align.abi; // FIXME(eddyb) maybe include I128 in the future, when it works everywhere. for &candidate in &[I64, I32, I16] { - if wanted >= candidate.align(dl).abi() && wanted >= candidate.size().bytes() { + if wanted >= candidate.align(dl).abi && wanted.bytes() >= candidate.size().bytes() { return candidate; } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index eed5d909063b..02b89a842685 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1779,7 +1779,7 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De // We are currently checking the type this field came from, so it must be local let span = tcx.hir.span_if_local(field.did).unwrap(); let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false); - let align1 = layout.map(|layout| layout.align.abi() == 1).unwrap_or(false); + let align1 = layout.map(|layout| layout.align.abi.bytes() == 1).unwrap_or(false); (span, zst, align1) }); From 5b4747ded7c964ea4e871b3ea6b10bf20862462a Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 9 Sep 2018 01:16:45 +0300 Subject: [PATCH 64/75] rustc_target: avoid using AbiAndPrefAlign where possible. --- src/librustc/mir/interpret/allocation.rs | 10 +-- src/librustc/mir/interpret/error.rs | 12 +-- src/librustc/session/code_stats.rs | 6 +- src/librustc/ty/layout.rs | 87 +++++++++---------- src/librustc_codegen_llvm/abi.rs | 14 +-- src/librustc_codegen_llvm/builder.rs | 42 ++++----- src/librustc_codegen_llvm/common.rs | 2 +- src/librustc_codegen_llvm/consts.rs | 14 +-- .../debuginfo/metadata.rs | 36 ++++---- src/librustc_codegen_llvm/debuginfo/mod.rs | 2 +- src/librustc_codegen_llvm/intrinsic.rs | 26 +++--- src/librustc_codegen_llvm/type_of.rs | 32 +++---- src/librustc_codegen_ssa/base.rs | 6 +- src/librustc_codegen_ssa/meth.rs | 6 +- src/librustc_codegen_ssa/mir/block.rs | 26 +++--- src/librustc_codegen_ssa/mir/mod.rs | 4 +- src/librustc_codegen_ssa/mir/operand.rs | 14 +-- src/librustc_codegen_ssa/mir/place.rs | 22 ++--- src/librustc_codegen_ssa/traits/builder.rs | 25 +++--- src/librustc_codegen_ssa/traits/statics.rs | 16 +--- src/librustc_codegen_ssa/traits/type_.rs | 10 +-- src/librustc_mir/const_eval.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 18 ++-- src/librustc_mir/interpret/memory.rs | 68 +++++++-------- src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/interpret/place.rs | 44 +++++----- src/librustc_mir/interpret/snapshot.rs | 4 +- src/librustc_mir/interpret/terminator.rs | 2 +- src/librustc_mir/interpret/traits.rs | 12 +-- src/librustc_mir/interpret/validity.rs | 6 +- src/librustc_target/abi/call/mips.rs | 6 +- src/librustc_target/abi/call/mips64.rs | 4 +- src/librustc_target/abi/call/mod.rs | 34 ++++---- src/librustc_target/abi/call/powerpc.rs | 6 +- src/librustc_target/abi/call/powerpc64.rs | 2 +- src/librustc_target/abi/call/sparc.rs | 6 +- src/librustc_target/abi/call/x86_64.rs | 2 +- src/librustc_target/abi/mod.rs | 15 ++-- 38 files changed, 311 insertions(+), 334 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 4e83cc16ab3e..3250ea266a58 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -12,7 +12,7 @@ use super::{Pointer, EvalResult, AllocId}; -use ty::layout::{Size, Align, AbiAndPrefAlign}; +use ty::layout::{Size, Align}; use syntax::ast::Mutability; use std::iter; use mir; @@ -40,7 +40,7 @@ pub struct Allocation { /// Denotes undefined memory. Reading from undefined memory is forbidden in miri pub undef_mask: UndefMask, /// The alignment of the allocation to detect unaligned reads. - pub align: AbiAndPrefAlign, + pub align: Align, /// Whether the allocation is mutable. /// Also used by codegen to determine if a static should be put into mutable memory, /// which happens for `static mut` and `static` with interior mutability. @@ -90,7 +90,7 @@ impl AllocationExtra<()> for () {} impl Allocation { /// Creates a read-only allocation initialized by the given bytes - pub fn from_bytes(slice: &[u8], align: AbiAndPrefAlign) -> Self { + pub fn from_bytes(slice: &[u8], align: Align) -> Self { let mut undef_mask = UndefMask::new(Size::ZERO); undef_mask.grow(Size::from_bytes(slice.len() as u64), true); Self { @@ -104,10 +104,10 @@ pub fn from_bytes(slice: &[u8], align: AbiAndPrefAlign) -> Self { } pub fn from_byte_aligned_bytes(slice: &[u8]) -> Self { - Allocation::from_bytes(slice, AbiAndPrefAlign::new(Align::from_bytes(1).unwrap())) + Allocation::from_bytes(slice, Align::from_bytes(1).unwrap()) } - pub fn undef(size: Size, align: AbiAndPrefAlign) -> Self { + pub fn undef(size: Size, align: Align) -> Self { assert_eq!(size.bytes() as usize as u64, size.bytes()); Allocation { bytes: vec![0; size.bytes() as usize], diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 1a33d3623964..7477343891e2 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -13,7 +13,7 @@ use hir::map::definitions::DefPathData; use mir; use ty::{self, Ty, layout}; -use ty::layout::{Size, AbiAndPrefAlign, LayoutError}; +use ty::layout::{Size, Align, LayoutError}; use rustc_target::spec::abi::Abi; use super::{RawConst, Pointer, InboundsCheck, ScalarMaybeUndef}; @@ -301,8 +301,8 @@ pub enum EvalErrorKind<'tcx, O> { TlsOutOfBounds, AbiViolation(String), AlignmentCheckFailed { - required: AbiAndPrefAlign, - has: AbiAndPrefAlign, + required: Align, + has: Align, }, ValidationFailure(String), CalledClosureAsFunction, @@ -315,7 +315,7 @@ pub enum EvalErrorKind<'tcx, O> { DeallocatedWrongMemoryKind(String, String), ReallocateNonBasePtr, DeallocateNonBasePtr, - IncorrectAllocationInformation(Size, Size, AbiAndPrefAlign, AbiAndPrefAlign), + IncorrectAllocationInformation(Size, Size, Align, Align), Layout(layout::LayoutError<'tcx>), HeapAllocZeroBytes, HeapAllocNonPowerOfTwoAlignment(u64), @@ -527,7 +527,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), AlignmentCheckFailed { required, has } => write!(f, "tried to access memory with alignment {}, but alignment {} is required", - has.abi.bytes(), required.abi.bytes()), + has.bytes(), required.bytes()), TypeNotPrimitive(ty) => write!(f, "expected primitive type, got {}", ty), Layout(ref err) => @@ -539,7 +539,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { IncorrectAllocationInformation(size, size2, align, align2) => write!(f, "incorrect alloc info: expected size {} and align {}, \ got size {} and align {}", - size.bytes(), align.abi.bytes(), size2.bytes(), align2.abi.bytes()), + size.bytes(), align.bytes(), size2.bytes(), align2.bytes()), Panic { ref msg, line, col, ref file } => write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), InvalidDiscriminant(val) => diff --git a/src/librustc/session/code_stats.rs b/src/librustc/session/code_stats.rs index 7a5ac36420fb..b8f5ce3cdbc7 100644 --- a/src/librustc/session/code_stats.rs +++ b/src/librustc/session/code_stats.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc_target::abi::{AbiAndPrefAlign, Size}; +use rustc_target::abi::{Align, Size}; use rustc_data_structures::fx::{FxHashSet}; use std::cmp::{self, Ordering}; @@ -63,7 +63,7 @@ impl CodeStats { pub fn record_type_size(&mut self, kind: DataTypeKind, type_desc: S, - align: AbiAndPrefAlign, + align: Align, overall_size: Size, packed: bool, opt_discr_size: Option, @@ -71,7 +71,7 @@ pub fn record_type_size(&mut self, let info = TypeSizeInfo { kind, type_description: type_desc.to_string(), - align: align.abi.bytes(), + align: align.bytes(), overall_size: overall_size.bytes(), packed: packed, opt_discr_size: opt_discr_size.map(|s| s.bytes()), diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 637686fd50ea..da0a9acede20 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -226,9 +226,10 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value))) }; let scalar_pair = |a: Scalar, b: Scalar| { - let align = a.value.align(dl).max(b.value.align(dl)).max(dl.aggregate_align); - let b_offset = a.value.size(dl).abi_align(b.value.align(dl)); - let size = (b_offset + b.value.size(dl)).abi_align(align); + let b_align = b.value.align(dl); + let align = a.value.align(dl).max(b_align).max(dl.aggregate_align); + let b_offset = a.value.size(dl).align_to(b_align.abi); + let size = (b_offset + b.value.size(dl)).align_to(align.abi); LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Arbitrary { @@ -248,7 +249,7 @@ enum StructKind { /// A univariant, the last field of which may be coerced to unsized. MaybeUnsized, /// A univariant, but with a prefix of an arbitrary size & alignment (e.g. enum tag). - Prefixed(Size, AbiAndPrefAlign), + Prefixed(Size, Align), } let univariant_uninterned = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| { @@ -257,10 +258,7 @@ enum StructKind { bug!("struct cannot be packed and aligned"); } - let pack = { - let pack = repr.pack as u64; - AbiAndPrefAlign::new(Align::from_bytes(pack).unwrap()) - }; + let pack = Align::from_bytes(repr.pack as u64).unwrap(); let mut align = if packed { dl.i8_align @@ -274,7 +272,7 @@ enum StructKind { let mut optimize = !repr.inhibit_struct_field_reordering_opt(); if let StructKind::Prefixed(_, align) = kind { - optimize &= align.abi.bytes() == 1; + optimize &= align.bytes() == 1; } if optimize { @@ -285,7 +283,7 @@ enum StructKind { }; let optimizing = &mut inverse_memory_index[..end]; let field_align = |f: &TyLayout<'_>| { - if packed { f.align.min(pack).abi } else { f.align.abi } + if packed { f.align.abi.min(pack) } else { f.align.abi } }; match kind { StructKind::AlwaysSized | @@ -312,13 +310,13 @@ enum StructKind { let mut offset = Size::ZERO; if let StructKind::Prefixed(prefix_size, prefix_align) = kind { - if packed { - let prefix_align = prefix_align.min(pack); - align = align.max(prefix_align); + let prefix_align = if packed { + prefix_align.min(pack) } else { - align = align.max(prefix_align); - } - offset = prefix_size.abi_align(prefix_align); + prefix_align + }; + align = align.max(AbiAndPrefAlign::new(prefix_align)); + offset = prefix_size.align_to(prefix_align); } for &i in &inverse_memory_index { @@ -333,15 +331,13 @@ enum StructKind { } // Invariant: offset < dl.obj_size_bound() <= 1<<61 - if packed { - let field_pack = field.align.min(pack); - offset = offset.abi_align(field_pack); - align = align.max(field_pack); - } - else { - offset = offset.abi_align(field.align); - align = align.max(field.align); - } + let field_align = if packed { + field.align.min(AbiAndPrefAlign::new(pack)) + } else { + field.align + }; + offset = offset.align_to(field_align.abi); + align = align.max(field_align); debug!("univariant offset: {:?} field: {:#?}", offset, field); offsets[i as usize] = offset; @@ -377,7 +373,7 @@ enum StructKind { memory_index = inverse_memory_index; } - let size = min_size.abi_align(align); + let size = min_size.align_to(align.abi); let mut abi = Abi::Aggregate { sized }; // Unpack newtype ABIs and find scalar pairs. @@ -648,7 +644,7 @@ enum StructKind { let size = element.size.checked_mul(count, dl) .ok_or(LayoutError::SizeOverflow(ty))?; let align = dl.vector_align(size); - let size = size.abi_align(align); + let size = size.align_to(align.abi); tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, @@ -680,10 +676,7 @@ enum StructKind { bug!("Union cannot be packed and aligned"); } - let pack = { - let pack = def.repr.pack as u64; - AbiAndPrefAlign::new(Align::from_bytes(pack).unwrap()) - }; + let pack = Align::from_bytes(def.repr.pack as u64).unwrap(); let mut align = if packed { dl.i8_align @@ -704,12 +697,12 @@ enum StructKind { for field in &variants[index] { assert!(!field.is_unsized()); - if packed { - let field_pack = field.align.min(pack); - align = align.max(field_pack); + let field_align = if packed { + field.align.min(AbiAndPrefAlign::new(pack)) } else { - align = align.max(field.align); - } + field.align + }; + align = align.max(field_align); // If all non-ZST fields have the same ABI, forward this ABI if optimize && !field.is_zst() { @@ -749,7 +742,7 @@ enum StructKind { fields: FieldPlacement::Union(variants[index].len()), abi, align, - size: size.abi_align(align) + size: size.align_to(align.abi) })); } @@ -964,19 +957,19 @@ enum StructKind { let mut size = Size::ZERO; // We're interested in the smallest alignment, so start large. - let mut start_align = AbiAndPrefAlign::new(Align::from_bytes(256).unwrap()); - assert_eq!(Integer::for_abi_align(dl, start_align), None); + let mut start_align = Align::from_bytes(256).unwrap(); + assert_eq!(Integer::for_align(dl, start_align), None); // repr(C) on an enum tells us to make a (tag, union) layout, // so we need to grow the prefix alignment to be at least // the alignment of the union. (This value is used both for // determining the alignment of the overall enum, and the // determining the alignment of the payload after the tag.) - let mut prefix_align = min_ity.align(dl); + let mut prefix_align = min_ity.align(dl).abi; if def.repr.c() { for fields in &variants { for field in fields { - prefix_align = prefix_align.max(field.align); + prefix_align = prefix_align.max(field.align.abi); } } } @@ -990,7 +983,7 @@ enum StructKind { // to make room for a larger discriminant. for field in st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) { if !field.is_zst() || field.align.abi.bytes() != 1 { - start_align = start_align.min(field.align); + start_align = start_align.min(field.align.abi); break; } } @@ -1000,7 +993,7 @@ enum StructKind { }).collect::, _>>()?; // Align the maximum variant size to the largest alignment. - size = size.abi_align(align); + size = size.align_to(align.abi); if size.bytes() >= dl.obj_size_bound() { return Err(LayoutError::SizeOverflow(ty)); @@ -1036,7 +1029,7 @@ enum StructKind { let mut ity = if def.repr.c() || def.repr.int.is_some() { min_ity } else { - Integer::for_abi_align(dl, start_align).unwrap_or(min_ity) + Integer::for_align(dl, start_align).unwrap_or(min_ity) }; // If the alignment is not larger than the chosen discriminant size, @@ -1204,7 +1197,7 @@ fn record_layout_for_printing_outlined(&self, layout: TyLayout<'tcx>) { let type_desc = format!("{:?}", layout.ty); self.tcx.sess.code_stats.borrow_mut().record_type_size(kind, type_desc, - layout.align, + layout.align.abi, layout.size, packed, opt_discr_size, @@ -1823,7 +1816,9 @@ fn find_niche(&self, layout: TyLayout<'tcx>) -> Result, LayoutErro Abi::ScalarPair(ref a, ref b) => { // HACK(nox): We iter on `b` and then `a` because `max_by_key` // returns the last maximum. - let niche = iter::once((b, a.value.size(self).abi_align(b.value.align(self)))) + let niche = iter::once( + (b, a.value.size(self).align_to(b.value.align(self).abi)) + ) .chain(iter::once((a, Size::ZERO))) .filter_map(|(scalar, offset)| scalar_niche(scalar, offset)) .max_by_key(|niche| niche.available); diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs index ccab0ce69e3a..3470d6fd0e72 100644 --- a/src/librustc_codegen_llvm/abi.rs +++ b/src/librustc_codegen_llvm/abi.rs @@ -73,7 +73,7 @@ fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) { if let Some(align) = self.pointee_align { llvm::LLVMRustAddAlignmentAttr(llfn, idx.as_uint(), - align.abi.bytes() as u32); + align.bytes() as u32); } regular.for_each_kind(|attr| attr.apply_llfn(idx, llfn)); } @@ -98,7 +98,7 @@ fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) { if let Some(align) = self.pointee_align { llvm::LLVMRustAddAlignmentCallSiteAttr(callsite, idx.as_uint(), - align.abi.bytes() as u32); + align.bytes() as u32); } regular.for_each_kind(|attr| attr.apply_callsite(idx, callsite)); } @@ -204,7 +204,7 @@ fn store( return; } if self.is_sized_indirect() { - OperandValue::Ref(val, None, self.layout.align).store(bx, dst) + OperandValue::Ref(val, None, self.layout.align.abi).store(bx, dst) } else if self.is_unsized_indirect() { bug!("unsized ArgType must be handled through store_fn_arg"); } else if let PassMode::Cast(cast) = self.mode { @@ -214,7 +214,7 @@ fn store( if can_store_through_cast_ptr { let cast_ptr_llty = bx.cx().type_ptr_to(cast.llvm_type(bx.cx())); let cast_dst = bx.pointercast(dst.llval, cast_ptr_llty); - bx.store(val, cast_dst, self.layout.align); + bx.store(val, cast_dst, self.layout.align.abi); } else { // The actual return type is a struct, but the ABI // adaptation code has cast it into some scalar type. The @@ -242,7 +242,7 @@ fn store( // ...and then memcpy it to the intended destination. bx.memcpy( dst.llval, - self.layout.align, + self.layout.align.abi, llscratch, scratch_align, bx.cx().const_usize(self.layout.size.bytes()), @@ -273,7 +273,7 @@ fn store_fn_arg( OperandValue::Pair(next(), next()).store(bx, dst); } PassMode::Indirect(_, Some(_)) => { - OperandValue::Ref(next(), Some(next()), self.layout.align).store(bx, dst); + OperandValue::Ref(next(), Some(next()), self.layout.align.abi).store(bx, dst); } PassMode::Direct(_) | PassMode::Indirect(_, None) | PassMode::Cast(_) => { self.store(bx, next(), dst); @@ -545,7 +545,7 @@ fn new_internal( adjust_for_rust_scalar(&mut b_attrs, b, arg.layout, - a.value.size(cx).abi_align(b.value.align(cx)), + a.value.size(cx).align_to(b.value.align(cx).abi), false); arg.mode = PassMode::Pair(a_attrs, b_attrs); return arg; diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 8da64edc92f0..d2a99eae3406 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -19,7 +19,7 @@ use value::Value; use libc::{c_uint, c_char}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::layout::{self, AbiAndPrefAlign, Size, TyLayout}; +use rustc::ty::layout::{self, Align, Size, TyLayout}; use rustc::session::config; use rustc_data_structures::small_c_str::SmallCStr; use rustc_codegen_ssa::traits::*; @@ -457,7 +457,7 @@ fn not(&mut self, v: &'ll Value) -> &'ll Value { } } - fn alloca(&mut self, ty: &'ll Type, name: &str, align: AbiAndPrefAlign) -> &'ll Value { + fn alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { let mut bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) @@ -465,7 +465,7 @@ fn alloca(&mut self, ty: &'ll Type, name: &str, align: AbiAndPrefAlign) -> &'ll bx.dynamic_alloca(ty, name, align) } - fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: AbiAndPrefAlign) -> &'ll Value { + fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { self.count_insn("alloca"); unsafe { let alloca = if name.is_empty() { @@ -475,7 +475,7 @@ fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: AbiAndPrefAlign) llvm::LLVMBuildAlloca(self.llbuilder, ty, name.as_ptr()) }; - llvm::LLVMSetAlignment(alloca, align.abi.bytes() as c_uint); + llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); alloca } } @@ -484,7 +484,7 @@ fn array_alloca(&mut self, ty: &'ll Type, len: &'ll Value, name: &str, - align: AbiAndPrefAlign) -> &'ll Value { + align: Align) -> &'ll Value { self.count_insn("alloca"); unsafe { let alloca = if name.is_empty() { @@ -494,16 +494,16 @@ fn array_alloca(&mut self, llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, name.as_ptr()) }; - llvm::LLVMSetAlignment(alloca, align.abi.bytes() as c_uint); + llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); alloca } } - fn load(&mut self, ptr: &'ll Value, align: AbiAndPrefAlign) -> &'ll Value { + fn load(&mut self, ptr: &'ll Value, align: Align) -> &'ll Value { self.count_insn("load"); unsafe { let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname()); - llvm::LLVMSetAlignment(load, align.abi.bytes() as c_uint); + llvm::LLVMSetAlignment(load, align.bytes() as c_uint); load } } @@ -639,7 +639,7 @@ fn nonnull_metadata(&mut self, load: &'ll Value) { } } - fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: AbiAndPrefAlign) -> &'ll Value { + fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value { self.store_with_flags(val, ptr, align, MemFlags::empty()) } @@ -647,7 +647,7 @@ fn store_with_flags( &mut self, val: &'ll Value, ptr: &'ll Value, - align: AbiAndPrefAlign, + align: Align, flags: MemFlags, ) -> &'ll Value { debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags); @@ -658,7 +658,7 @@ fn store_with_flags( let align = if flags.contains(MemFlags::UNALIGNED) { 1 } else { - align.abi.bytes() as c_uint + align.bytes() as c_uint }; llvm::LLVMSetAlignment(store, align); if flags.contains(MemFlags::VOLATILE) { @@ -878,8 +878,8 @@ fn inline_asm_call(&mut self, asm: &CStr, cons: &CStr, } } - fn memcpy(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, - src: &'ll Value, src_align: AbiAndPrefAlign, + fn memcpy(&mut self, dst: &'ll Value, dst_align: Align, + src: &'ll Value, src_align: Align, size: &'ll Value, flags: MemFlags) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. @@ -893,13 +893,13 @@ fn memcpy(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, let dst = self.pointercast(dst, self.cx().type_i8p()); let src = self.pointercast(src, self.cx().type_i8p()); unsafe { - llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.abi.bytes() as c_uint, - src, src_align.abi.bytes() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.bytes() as c_uint, + src, src_align.bytes() as c_uint, size, is_volatile); } } - fn memmove(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, - src: &'ll Value, src_align: AbiAndPrefAlign, + fn memmove(&mut self, dst: &'ll Value, dst_align: Align, + src: &'ll Value, src_align: Align, size: &'ll Value, flags: MemFlags) { if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memmove. @@ -913,8 +913,8 @@ fn memmove(&mut self, dst: &'ll Value, dst_align: AbiAndPrefAlign, let dst = self.pointercast(dst, self.cx().type_i8p()); let src = self.pointercast(src, self.cx().type_i8p()); unsafe { - llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.abi.bytes() as c_uint, - src, src_align.abi.bytes() as c_uint, size, is_volatile); + llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.bytes() as c_uint, + src, src_align.bytes() as c_uint, size, is_volatile); } } @@ -923,14 +923,14 @@ fn memset( ptr: &'ll Value, fill_byte: &'ll Value, size: &'ll Value, - align: AbiAndPrefAlign, + align: Align, flags: MemFlags, ) { let ptr_width = &self.cx().sess().target.target.target_pointer_width; let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width); let llintrinsicfn = self.cx().get_intrinsic(&intrinsic_key); let ptr = self.pointercast(ptr, self.cx().type_i8p()); - let align = self.cx().const_u32(align.abi.bytes() as u32); + let align = self.cx().const_u32(align.bytes() as u32); let volatile = self.cx().const_bool(flags.contains(MemFlags::VOLATILE)); self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None); } diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 2fc505d42db5..cd74a5854a92 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -357,7 +357,7 @@ fn from_const_alloc( offset: Size, ) -> PlaceRef<'tcx, &'ll Value> { let init = const_alloc_to_llvm(self, alloc); - let base_addr = self.static_addr_of(init, layout.align, None); + let base_addr = self.static_addr_of(init, layout.align.abi, None); let llval = unsafe { llvm::LLVMConstInBoundsGEP( self.static_bitcast(base_addr, self.type_i8p()), diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index b5b2e22fed06..07dde2d0301f 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -28,7 +28,7 @@ use rustc::ty::{self, Ty}; use rustc_codegen_ssa::traits::*; -use rustc::ty::layout::{self, Size, Align, AbiAndPrefAlign, LayoutOf}; +use rustc::ty::layout::{self, Size, Align, LayoutOf}; use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags}; @@ -89,20 +89,20 @@ pub fn codegen_static_initializer( fn set_global_alignment(cx: &CodegenCx<'ll, '_>, gv: &'ll Value, - mut align: AbiAndPrefAlign) { + mut align: Align) { // The target may require greater alignment for globals than the type does. // Note: GCC and Clang also allow `__attribute__((aligned))` on variables, // which can force it to be smaller. Rust doesn't support this yet. if let Some(min) = cx.sess().target.target.options.min_global_align { match Align::from_bits(min) { - Ok(min) => align = align.max(AbiAndPrefAlign::new(min)), + Ok(min) => align = align.max(min), Err(err) => { cx.sess().err(&format!("invalid minimum global alignment: {}", err)); } } } unsafe { - llvm::LLVMSetAlignment(gv, align.abi.bytes() as u32); + llvm::LLVMSetAlignment(gv, align.bytes() as u32); } } @@ -186,7 +186,7 @@ fn static_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value { fn static_addr_of_mut( &self, cv: &'ll Value, - align: AbiAndPrefAlign, + align: Align, kind: Option<&str>, ) -> &'ll Value { unsafe { @@ -212,14 +212,14 @@ fn static_addr_of_mut( fn static_addr_of( &self, cv: &'ll Value, - align: AbiAndPrefAlign, + align: Align, kind: Option<&str>, ) -> &'ll Value { if let Some(&gv) = self.const_globals.borrow().get(&cv) { unsafe { // Upgrade the alignment in cases where the same constant is used with different // alignment requirements - let llalign = align.abi.bytes() as u32; + let llalign = align.bytes() as u32; if llalign > llvm::LLVMGetAlignment(gv) { llvm::LLVMSetAlignment(gv, llalign); } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 4cee39570423..81f2769800d2 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -35,7 +35,7 @@ use rustc::ty::Instance; use common::CodegenCx; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; -use rustc::ty::layout::{self, AbiAndPrefAlign, HasDataLayout, Integer, IntegerExt, LayoutOf, +use rustc::ty::layout::{self, Align, HasDataLayout, Integer, IntegerExt, LayoutOf, PrimitiveExt, Size, TyLayout}; use rustc::session::config; use rustc::util::nodemap::FxHashMap; @@ -323,7 +323,7 @@ fn fixed_vec_metadata( llvm::LLVMRustDIBuilderCreateArrayType( DIB(cx), size.bits(), - align.abi.bits() as u32, + align.bits() as u32, element_type_metadata, subscripts) }; @@ -465,7 +465,7 @@ fn trait_pointer_metadata( syntax_pos::DUMMY_SP), offset: layout.fields.offset(0), size: data_ptr_field.size, - align: data_ptr_field.align, + align: data_ptr_field.align.abi, flags: DIFlags::FlagArtificial, discriminant: None, }, @@ -474,7 +474,7 @@ fn trait_pointer_metadata( type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP), offset: layout.fields.offset(1), size: vtable_field.size, - align: vtable_field.align, + align: vtable_field.align.abi, flags: DIFlags::FlagArtificial, discriminant: None, }, @@ -787,7 +787,7 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType { DIB(cx), name.as_ptr(), size.bits(), - align.abi.bits() as u32, + align.bits() as u32, encoding) }; @@ -818,7 +818,7 @@ fn pointer_type_metadata( DIB(cx), pointee_type_metadata, pointer_size.bits(), - pointer_align.abi.bits() as u32, + pointer_align.bits() as u32, name.as_ptr()) } } @@ -923,7 +923,7 @@ struct MemberDescription<'ll> { type_metadata: &'ll DIType, offset: Size, size: Size, - align: AbiAndPrefAlign, + align: Align, flags: DIFlags, discriminant: Option, } @@ -990,7 +990,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) type_metadata: type_metadata(cx, field.ty, self.span), offset: layout.fields.offset(i), size: field.size, - align: field.align, + align: field.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1113,7 +1113,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) type_metadata: type_metadata(cx, field.ty, self.span), offset: Size::ZERO, size: field.size, - align: field.align, + align: field.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1226,7 +1226,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, - align: self.layout.align, + align: self.layout.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1265,7 +1265,7 @@ fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, - align: self.layout.align, + align: self.layout.align.abi, flags: DIFlags::FlagZero, discriminant: Some(self.layout.ty.ty_adt_def().unwrap() .discriminant_for_variant(cx.tcx, i) @@ -1334,7 +1334,7 @@ fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, type_metadata: variant_type_metadata, offset: Size::ZERO, size: variant.size, - align: variant.align, + align: variant.align.abi, flags: DIFlags::FlagZero, discriminant: None, } @@ -1372,7 +1372,7 @@ fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, - align: self.layout.align, + align: self.layout.align.abi, flags: DIFlags::FlagZero, discriminant: niche_value, } @@ -1675,7 +1675,7 @@ fn prepare_enum_metadata( file_metadata, UNKNOWN_LINE_NUMBER, size.bits(), - align.abi.bits() as u32, + align.bits() as u32, layout.fields.offset(0).bits(), DIFlags::FlagArtificial, discr_metadata)) @@ -1803,7 +1803,7 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>, unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, member_description.size.bits(), - member_description.align.abi.bits() as u32, + member_description.align.bits() as u32, member_description.offset.bits(), match member_description.discriminant { None => None, @@ -1851,7 +1851,7 @@ fn create_struct_stub( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, struct_size.bits(), - struct_align.abi.bits() as u32, + struct_align.bits() as u32, DIFlags::FlagZero, None, empty_array, @@ -1889,7 +1889,7 @@ fn create_union_stub( unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, union_size.bits(), - union_align.abi.bits() as u32, + union_align.bits() as u32, DIFlags::FlagZero, Some(empty_array), 0, // RuntimeLang @@ -1958,7 +1958,7 @@ pub fn create_global_var_metadata( is_local_to_unit, global, None, - global_align.abi.bytes() as u32, + global_align.bytes() as u32, ); } } diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 199402982c6e..e200da2b0909 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -201,7 +201,7 @@ fn declare_local( cx.sess().opts.optimize != config::OptLevel::No, DIFlags::FlagZero, argument_index, - align.abi.bytes() as u32, + align.bytes() as u32, ) }; source_loc::set_debug_location(self, diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 1756fd5b0b19..3548ccfd5a53 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -110,7 +110,7 @@ fn codegen_intrinsic_call( let name = &*tcx.item_name(def_id).as_str(); let llret_ty = self.cx().layout_of(ret_ty).llvm_type(self.cx()); - let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align); + let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align.abi); let simple = get_simple_intrinsic(self.cx(), name); let llval = match name { @@ -158,7 +158,7 @@ fn codegen_intrinsic_call( } "min_align_of" => { let tp_ty = substs.type_at(0); - self.cx().const_usize(self.cx().align_of(tp_ty).abi.bytes()) + self.cx().const_usize(self.cx().align_of(tp_ty).bytes()) } "min_align_of_val" => { let tp_ty = substs.type_at(0); @@ -167,12 +167,12 @@ fn codegen_intrinsic_call( glue::size_and_align_of_dst(self, tp_ty, Some(meta)); llalign } else { - self.cx().const_usize(self.cx().align_of(tp_ty).abi.bytes()) + self.cx().const_usize(self.cx().align_of(tp_ty).bytes()) } } "pref_align_of" => { let tp_ty = substs.type_at(0); - self.cx().const_usize(self.cx().align_of(tp_ty).pref.bytes()) + self.cx().const_usize(self.cx().layout_of(tp_ty).align.pref.bytes()) } "type_name" => { let tp_ty = substs.type_at(0); @@ -261,7 +261,7 @@ fn codegen_intrinsic_call( let align = if name == "unaligned_volatile_load" { 1 } else { - self.cx().align_of(tp_ty).abi.bytes() as u32 + self.cx().align_of(tp_ty).bytes() as u32 }; unsafe { llvm::LLVMSetAlignment(load, align); @@ -815,7 +815,7 @@ fn try_intrinsic( ) { if bx.cx().sess().no_landing_pads() { bx.call(func, &[data], None); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; bx.store(bx.cx().const_null(bx.cx().type_i8p()), dest, ptr_align); } else if wants_msvc_seh(bx.cx().sess()) { codegen_msvc_try(bx, func, data, local_ptr, dest); @@ -890,7 +890,7 @@ fn codegen_msvc_try( // // More information can be found in libstd's seh.rs implementation. let i64p = bx.cx().type_ptr_to(bx.cx().type_i64()); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; let slot = bx.alloca(i64p, "slot", ptr_align); bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None); @@ -906,7 +906,7 @@ fn codegen_msvc_try( let funclet = catchpad.catch_pad(cs, &[tydesc, bx.cx().const_i32(0), slot]); let addr = catchpad.load(slot, ptr_align); - let i64_align = bx.tcx().data_layout.i64_align; + let i64_align = bx.tcx().data_layout.i64_align.abi; let arg1 = catchpad.load(addr, i64_align); let val1 = bx.cx().const_i32(1); let gep1 = catchpad.inbounds_gep(addr, &[val1]); @@ -923,7 +923,7 @@ fn codegen_msvc_try( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llfn, &[func, data, local_ptr], None); - let i32_align = bx.tcx().data_layout.i32_align; + let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -982,7 +982,7 @@ fn codegen_gnu_try( let vals = catch.landing_pad(lpad_ty, bx.cx().eh_personality(), 1); catch.add_clause(vals, bx.cx().const_null(bx.cx().type_i8p())); let ptr = catch.extract_value(vals, 0); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; let bitcast = catch.bitcast(local_ptr, bx.cx().type_ptr_to(bx.cx().type_i8p())); catch.store(ptr, bitcast, ptr_align); catch.ret(bx.cx().const_i32(1)); @@ -991,7 +991,7 @@ fn codegen_gnu_try( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). let ret = bx.call(llfn, &[func, data, local_ptr], None); - let i32_align = bx.tcx().data_layout.i32_align; + let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -1436,7 +1436,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty { // Alignment of T, must be a constant integer value: let alignment_ty = bx.cx().type_i32(); - let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi.bytes() as i32); + let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).bytes() as i32); // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { @@ -1536,7 +1536,7 @@ fn non_ptr(t: ty::Ty) -> ty::Ty { // Alignment of T, must be a constant integer value: let alignment_ty = bx.cx().type_i32(); - let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).abi.bytes() as i32); + let alignment = bx.cx().const_i32(bx.cx().align_of(in_elem).bytes() as i32); // Truncate the mask vector to a vector of i1s: let (mask, mask_ty) = { diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index 8ce3be36d0bb..15b5bdeb44d6 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -12,7 +12,7 @@ use common::*; use rustc::hir; use rustc::ty::{self, Ty, TypeFoldable}; -use rustc::ty::layout::{self, AbiAndPrefAlign, LayoutOf, Size, TyLayout}; +use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout}; use rustc_target::abi::FloatTy; use rustc_mir::monomorphize::item::DefPathBasedNames; use type_::Type; @@ -80,7 +80,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, match layout.fields { layout::FieldPlacement::Union(_) => { - let fill = cx.type_padding_filler(layout.size, layout.align); + let fill = cx.type_padding_filler(layout.size, layout.align.abi); let packed = false; match name { None => { @@ -120,23 +120,23 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let mut packed = false; let mut offset = Size::ZERO; - let mut prev_effective_align = layout.align; + let mut prev_effective_align = layout.align.abi; let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2); for i in layout.fields.index_by_increasing_offset() { let target_offset = layout.fields.offset(i as usize); let field = layout.field(cx, i); - let effective_field_align = AbiAndPrefAlign::new(layout.align.abi + let effective_field_align = layout.align.abi .min(field.align.abi) - .restrict_for_offset(target_offset)); - packed |= effective_field_align.abi < field.align.abi; + .restrict_for_offset(target_offset); + packed |= effective_field_align < field.align.abi; debug!("struct_llfields: {}: {:?} offset: {:?} target_offset: {:?} \ effective_field_align: {}", - i, field, offset, target_offset, effective_field_align.abi.bytes()); + i, field, offset, target_offset, effective_field_align.bytes()); assert!(target_offset >= offset); let padding = target_offset - offset; let padding_align = prev_effective_align.min(effective_field_align); - assert_eq!(offset.abi_align(padding_align) + padding, target_offset); + assert_eq!(offset.align_to(padding_align) + padding, target_offset); result.push(cx.type_padding_filler( padding, padding_align)); debug!(" padding before: {:?}", padding); @@ -151,7 +151,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } let padding = layout.size - offset; let padding_align = prev_effective_align; - assert_eq!(offset.abi_align(padding_align) + padding, layout.size); + assert_eq!(offset.align_to(padding_align) + padding, layout.size); debug!("struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}", padding, offset, layout.size); result.push(cx.type_padding_filler(padding, padding_align)); @@ -165,17 +165,17 @@ fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } impl<'a, 'tcx> CodegenCx<'a, 'tcx> { - pub fn align_of(&self, ty: Ty<'tcx>) -> AbiAndPrefAlign { - self.layout_of(ty).align + pub fn align_of(&self, ty: Ty<'tcx>) -> Align { + self.layout_of(ty).align.abi } pub fn size_of(&self, ty: Ty<'tcx>) -> Size { self.layout_of(ty).size } - pub fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, AbiAndPrefAlign) { + pub fn size_and_align_of(&self, ty: Ty<'tcx>) -> (Size, Align) { let layout = self.layout_of(ty); - (layout.size, layout.align) + (layout.size, layout.align.abi) } } @@ -197,7 +197,7 @@ pub enum PointerKind { #[derive(Copy, Clone)] pub struct PointeeInfo { pub size: Size, - pub align: AbiAndPrefAlign, + pub align: Align, pub safe: Option, } @@ -333,7 +333,7 @@ fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, layout::Pointer => { // If we know the alignment, pick something better than i8. let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) { - cx.type_pointee_for_abi_align( pointee.align) + cx.type_pointee_for_align(pointee.align) } else { cx.type_i8() }; @@ -377,7 +377,7 @@ fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>, let offset = if index == 0 { Size::ZERO } else { - a.value.size(cx).abi_align(b.value.align(cx)) + a.value.size(cx).align_to(b.value.align(cx).abi) }; self.scalar_llvm_type_at(cx, scalar, offset) } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index e80ff8b65801..856bb9533c85 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -31,7 +31,7 @@ use rustc::middle::weak_lang_items; use rustc::mir::mono::{Stats, CodegenUnitNameBuilder}; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::ty::layout::{self, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; +use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::ty::query::Providers; use rustc::middle::cstore::{self, LinkagePreference}; use rustc::util::common::{time, print_time_passes_entry}; @@ -410,9 +410,9 @@ pub fn to_immediate_scalar<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( pub fn memcpy_ty<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, dst: Bx::Value, - dst_align: AbiAndPrefAlign, + dst_align: Align, src: Bx::Value, - src_align: AbiAndPrefAlign, + src_align: Align, layout: TyLayout<'tcx>, flags: MemFlags, ) { diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 60268533c85d..e45cccee3494 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -41,7 +41,7 @@ pub fn get_fn>( llvtable, bx.cx().type_ptr_to(bx.cx().fn_ptr_backend_type(fn_ty)) ); - let ptr_align = bx.tcx().data_layout.pointer_align; + let ptr_align = bx.tcx().data_layout.pointer_align.abi; let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]); let ptr = bx.load(gep, ptr_align); bx.nonnull_metadata(ptr); @@ -59,7 +59,7 @@ pub fn get_usize>( debug!("get_int({:?}, {:?})", llvtable, self); let llvtable = bx.pointercast(llvtable, bx.cx().type_ptr_to(bx.cx().type_isize())); - let usize_align = bx.tcx().data_layout.pointer_align; + let usize_align = bx.tcx().data_layout.pointer_align.abi; let gep = bx.inbounds_gep(llvtable, &[bx.cx().const_usize(self.0)]); let ptr = bx.load(gep, usize_align); // Vtable loads are invariant @@ -112,7 +112,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( ].iter().cloned().chain(methods).collect(); let vtable_const = cx.const_struct(&components, false); - let align = cx.data_layout().pointer_align; + let align = cx.data_layout().pointer_align.abi; let vtable = cx.static_addr_of(vtable_const, align, Some("vtable")); cx.create_vtable_metadata(ty, vtable); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 693addd441ff..75a6f07124ae 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -280,7 +280,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( scratch.llval } Ref(llval, _, align) => { - assert_eq!(align.abi, op.layout.align.abi, + assert_eq!(align, op.layout.align.abi, "return place is unaligned!"); llval } @@ -288,7 +288,7 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let addr = bx.pointercast(llslot, bx.cx().type_ptr_to( bx.cx().cast_backend_type(&cast_ty) )); - bx.load(addr, self.fn_ty.ret.layout.align) + bx.load(addr, self.fn_ty.ret.layout.align.abi) } }; bx.ret(llval); @@ -386,9 +386,9 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let filename = bx.cx().const_str_slice(filename); let line = bx.cx().const_u32(loc.line as u32); let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1); - let align = tcx.data_layout.aggregate_align - .max(tcx.data_layout.i32_align) - .max(tcx.data_layout.pointer_align); + let align = tcx.data_layout.aggregate_align.abi + .max(tcx.data_layout.i32_align.abi) + .max(tcx.data_layout.pointer_align.abi); // Put together the arguments to the panic entry point. let (lang_item, args) = match *msg { @@ -522,9 +522,9 @@ fn funclet_closure_factory<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let filename = bx.cx().const_str_slice(filename); let line = bx.cx().const_u32(loc.line as u32); let col = bx.cx().const_u32(loc.col.to_usize() as u32 + 1); - let align = tcx.data_layout.aggregate_align - .max(tcx.data_layout.i32_align) - .max(tcx.data_layout.pointer_align); + let align = tcx.data_layout.aggregate_align.abi + .max(tcx.data_layout.i32_align.abi) + .max(tcx.data_layout.pointer_align.abi); let str = format!( "Attempted to instantiate uninhabited type {} using mem::{}", @@ -800,12 +800,12 @@ fn codegen_argument( (scratch.llval, scratch.align, true) } _ => { - (op.immediate_or_packed_pair(bx), arg.layout.align, false) + (op.immediate_or_packed_pair(bx), arg.layout.align.abi, false) } } } Ref(llval, _, align) => { - if arg.is_indirect() && align.abi < arg.layout.align.abi { + if arg.is_indirect() && align < arg.layout.align.abi { // `foo(packed.large_field)`. We can't pass the (unaligned) field directly. I // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't // have scary latent bugs around. @@ -826,7 +826,7 @@ fn codegen_argument( let addr = bx.pointercast(llval, bx.cx().type_ptr_to( bx.cx().cast_backend_type(&ty)) ); - llval = bx.load(addr, align.min(arg.layout.align)); + llval = bx.load(addr, align.min(arg.layout.align.abi)); } else { // We can't use `PlaceRef::load` here because the argument // may have a type we don't treat as immediate, but the ABI @@ -1006,7 +1006,7 @@ fn make_return_dest( self.codegen_place(bx, dest) }; if fn_ret.is_indirect() { - if dest.align.abi < dest.layout.align.abi { + if dest.align < dest.layout.align.abi { // Currently, MIR code generation does not create calls // that store directly to fields of packed structs (in // fact, the calls it creates write only to temps), @@ -1062,7 +1062,7 @@ fn codegen_transmute_into( let src = self.codegen_operand(bx, src); let llty = bx.cx().backend_type(src.layout); let cast_ptr = bx.pointercast(dst.llval, bx.cx().type_ptr_to(llty)); - let align = src.layout.align.min(dst.layout.align); + let align = src.layout.align.abi.min(dst.align); src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align)); } diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 0579afe1d49c..fdc9a37a9eb3 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -304,7 +304,7 @@ pub fn codegen_mir<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( if local == mir::RETURN_PLACE && fx.fn_ty.ret.is_indirect() { debug!("alloc: {:?} (return place) -> place", local); let llretptr = fx.cx.get_param(llfn, 0); - LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align)) + LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align.abi)) } else if memory_locals.contains(local) { debug!("alloc: {:?} -> place", local); if layout.is_unsized() { @@ -555,7 +555,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let llarg = bx.cx().get_param(bx.llfn(), llarg_idx as c_uint); bx.set_value_name(llarg, &name); llarg_idx += 1; - PlaceRef::new_sized(llarg, arg.layout, arg.layout.align) + PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi) } else if arg.is_unsized_indirect() { // As the storage for the indirect argument lives during // the whole function call, we just copy the fat pointer. diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index c604386456c4..f6917906d4a8 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -11,7 +11,7 @@ use rustc::mir::interpret::{ConstValue, ErrorHandled}; use rustc::mir; use rustc::ty; -use rustc::ty::layout::{self, Align, AbiAndPrefAlign, LayoutOf, TyLayout}; +use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; use base; use MemFlags; @@ -33,7 +33,7 @@ pub enum OperandValue { /// to be valid for the operand's lifetime. /// The second value, if any, is the extra data (vtable or length) /// which indicates that it refers to an unsized rvalue. - Ref(V, Option, AbiAndPrefAlign), + Ref(V, Option, Align), /// A single LLVM value. Immediate(V), /// A pair of immediate LLVM values. Used by fat pointers too. @@ -152,7 +152,7 @@ pub fn deref>( llval: llptr, llextra, layout, - align: layout.align, + align: layout.align.abi, } } @@ -228,7 +228,7 @@ pub fn extract_field>( OperandValue::Immediate(a_llval) } else { assert_eq!(offset, a.value.size(bx.cx()) - .abi_align(b.value.align(bx.cx()))); + .align_to(b.value.align(bx.cx()).abi)); assert_eq!(field.size, b.value.size(bx.cx())); OperandValue::Immediate(b_llval) } @@ -348,8 +348,8 @@ pub fn store_unsized>( }; // FIXME: choose an appropriate alignment, or use dynamic align somehow - let max_align = AbiAndPrefAlign::new(Align::from_bits(128).unwrap()); - let min_align = AbiAndPrefAlign::new(Align::from_bits(8).unwrap()); + let max_align = Align::from_bits(128).unwrap(); + let min_align = Align::from_bits(8).unwrap(); // Allocate an appropriate region on the stack, and copy the value into it let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); @@ -470,7 +470,7 @@ pub fn codegen_operand( bx.load_operand(PlaceRef::new_sized( bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))), layout, - layout.align, + layout.align.abi, )) }) } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index f78f7a50561d..e6fd6dfca736 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; +use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; use rustc::mir; use rustc::mir::tcx::PlaceTy; use MemFlags; @@ -33,14 +33,14 @@ pub struct PlaceRef<'tcx, V> { pub layout: TyLayout<'tcx>, /// What alignment we know for this place - pub align: AbiAndPrefAlign, + pub align: Align, } impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { pub fn new_sized( llval: V, layout: TyLayout<'tcx>, - align: AbiAndPrefAlign, + align: Align, ) -> PlaceRef<'tcx, V> { assert!(!layout.is_unsized()); PlaceRef { @@ -58,8 +58,8 @@ pub fn alloca>( ) -> Self { debug!("alloca({:?}: {:?})", name, layout); assert!(!layout.is_unsized(), "tried to statically allocate unsized place"); - let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align); - Self::new_sized(tmp, layout, layout.align) + let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align.abi); + Self::new_sized(tmp, layout, layout.align.abi) } /// Returns a place for an indirect reference to an unsized place. @@ -101,7 +101,7 @@ pub fn project_field>( ) -> Self { let field = self.layout.field(bx.cx(), ix); let offset = self.layout.fields.offset(ix); - let effective_field_align = self.align.abi.restrict_for_offset(offset); + let effective_field_align = self.align.restrict_for_offset(offset); let mut simple = || { // Unions and newtypes only use an offset of 0. @@ -109,7 +109,7 @@ pub fn project_field>( self.llval } else if let layout::Abi::ScalarPair(ref a, ref b) = self.layout.abi { // Offsets have to match either first or second field. - assert_eq!(offset, a.value.size(bx.cx()).abi_align(b.value.align(bx.cx()))); + assert_eq!(offset, a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi)); bx.struct_gep(self.llval, 1) } else { bx.struct_gep(self.llval, bx.cx().backend_field_index(self.layout, ix)) @@ -123,7 +123,7 @@ pub fn project_field>( None }, layout: field, - align: AbiAndPrefAlign::new(effective_field_align), + align: effective_field_align, } }; @@ -197,7 +197,7 @@ pub fn project_field>( llval: bx.pointercast(byte_ptr, bx.cx().type_ptr_to(ll_fty)), llextra: self.llextra, layout: field, - align: AbiAndPrefAlign::new(effective_field_align), + align: effective_field_align, } } @@ -418,13 +418,13 @@ pub fn codegen_place( let llval = bx.cx().const_undef( bx.cx().type_ptr_to(bx.cx().backend_type(layout)) ); - PlaceRef::new_sized(llval, layout, layout.align) + PlaceRef::new_sized(llval, layout, layout.align.abi) } } } mir::Place::Static(box mir::Static { def_id, ty }) => { let layout = cx.layout_of(self.monomorphize(&ty)); - PlaceRef::new_sized(cx.get_static(def_id), layout, layout.align) + PlaceRef::new_sized(cx.get_static(def_id), layout, layout.align.abi) }, mir::Place::Projection(box mir::Projection { ref base, diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 02be098599b3..0b3066f561cc 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -17,7 +17,7 @@ use common::{AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope}; use mir::operand::OperandRef; use mir::place::PlaceRef; -use rustc::ty::layout::{AbiAndPrefAlign, Size}; +use rustc::ty::layout::{Align, Size}; use std::ffi::CStr; use MemFlags; @@ -97,18 +97,17 @@ fn invoke( fn fneg(&mut self, v: Self::Value) -> Self::Value; fn not(&mut self, v: Self::Value) -> Self::Value; - fn alloca(&mut self, ty: Self::Type, name: &str, align: AbiAndPrefAlign) -> Self::Value; - fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: AbiAndPrefAlign) - -> Self::Value; + fn alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; + fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; fn array_alloca( &mut self, ty: Self::Type, len: Self::Value, name: &str, - align: AbiAndPrefAlign, + align: Align, ) -> Self::Value; - fn load(&mut self, ptr: Self::Value, align: AbiAndPrefAlign) -> Self::Value; + fn load(&mut self, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value; fn atomic_load(&mut self, ptr: Self::Value, order: AtomicOrdering, size: Size) -> Self::Value; fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) @@ -117,12 +116,12 @@ fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) fn range_metadata(&mut self, load: Self::Value, range: Range); fn nonnull_metadata(&mut self, load: Self::Value); - fn store(&mut self, val: Self::Value, ptr: Self::Value, align: AbiAndPrefAlign) -> Self::Value; + fn store(&mut self, val: Self::Value, ptr: Self::Value, align: Align) -> Self::Value; fn store_with_flags( &mut self, val: Self::Value, ptr: Self::Value, - align: AbiAndPrefAlign, + align: Align, flags: MemFlags, ) -> Self::Value; fn atomic_store( @@ -175,18 +174,18 @@ fn inline_asm_call( fn memcpy( &mut self, dst: Self::Value, - dst_align: AbiAndPrefAlign, + dst_align: Align, src: Self::Value, - src_align: AbiAndPrefAlign, + src_align: Align, size: Self::Value, flags: MemFlags, ); fn memmove( &mut self, dst: Self::Value, - dst_align: AbiAndPrefAlign, + dst_align: Align, src: Self::Value, - src_align: AbiAndPrefAlign, + src_align: Align, size: Self::Value, flags: MemFlags, ); @@ -195,7 +194,7 @@ fn memset( ptr: Self::Value, fill_byte: Self::Value, size: Self::Value, - align: AbiAndPrefAlign, + align: Align, flags: MemFlags, ); diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs index b66f4378c35f..172c48f8a85f 100644 --- a/src/librustc_codegen_ssa/traits/statics.rs +++ b/src/librustc_codegen_ssa/traits/statics.rs @@ -10,23 +10,13 @@ use super::Backend; use rustc::hir::def_id::DefId; -use rustc::ty::layout::AbiAndPrefAlign; +use rustc::ty::layout::Align; pub trait StaticMethods<'tcx>: Backend<'tcx> { fn static_ptrcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; fn static_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value; - fn static_addr_of_mut( - &self, - cv: Self::Value, - align: AbiAndPrefAlign, - kind: Option<&str>, - ) -> Self::Value; - fn static_addr_of( - &self, - cv: Self::Value, - align: AbiAndPrefAlign, - kind: Option<&str>, - ) -> Self::Value; + fn static_addr_of_mut(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; + fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value; fn get_static(&self, def_id: DefId) -> Self::Value; fn codegen_static(&self, def_id: DefId, is_mutable: bool); unsafe fn static_replace_all_uses(&self, old_g: Self::Value, new_g: Self::Value); diff --git a/src/librustc_codegen_ssa/traits/type_.rs b/src/librustc_codegen_ssa/traits/type_.rs index 275f378495d9..15976ac516dc 100644 --- a/src/librustc_codegen_ssa/traits/type_.rs +++ b/src/librustc_codegen_ssa/traits/type_.rs @@ -13,7 +13,7 @@ use super::HasCodegen; use common::{self, TypeKind}; use mir::place::PlaceRef; -use rustc::ty::layout::{self, AbiAndPrefAlign, Size, TyLayout}; +use rustc::ty::layout::{self, Align, Size, TyLayout}; use rustc::ty::{self, Ty}; use rustc::util::nodemap::FxHashMap; use rustc_target::abi::call::{ArgType, CastTarget, FnType, Reg}; @@ -120,16 +120,16 @@ fn type_from_integer(&self, i: layout::Integer) -> Self::Type { } } - fn type_pointee_for_abi_align(&self, align: AbiAndPrefAlign) -> Self::Type { + fn type_pointee_for_align(&self, align: Align) -> Self::Type { // FIXME(eddyb) We could find a better approximation if ity.align < align. - let ity = layout::Integer::approximate_abi_align(self, align); + let ity = layout::Integer::approximate_align(self, align); self.type_from_integer(ity) } /// Return a LLVM type that has at most the required alignment, /// and exactly the required size, as a best-effort padding array. - fn type_padding_filler(&self, size: Size, align: AbiAndPrefAlign) -> Self::Type { - let unit = layout::Integer::approximate_abi_align(self, align); + fn type_padding_filler(&self, size: Size, align: Align) -> Self::Type { + let unit = layout::Integer::approximate_align(self, align); let size = size.bytes(); let unit_size = unit.size().bytes(); assert_eq!(size % unit_size, 0); diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 6a8a9fe817c0..1bc3b322717e 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -129,7 +129,7 @@ pub fn op_to_const<'tcx>( assert!(meta.is_none()); let ptr = ptr.to_ptr()?; let alloc = ecx.memory.get(ptr.alloc_id)?; - assert!(alloc.align.abi >= align.abi); + assert!(alloc.align >= align); assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= op.layout.size.bytes()); let mut alloc = alloc.clone(); alloc.align = align; diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b3e9008a6b73..936b476df39b 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -16,7 +16,7 @@ use rustc::hir::def::Def; use rustc::mir; use rustc::ty::layout::{ - self, Size, AbiAndPrefAlign, HasDataLayout, LayoutOf, TyLayout + self, Size, Align, HasDataLayout, LayoutOf, TyLayout }; use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -314,9 +314,9 @@ pub(super) fn size_and_align_of( &self, metadata: Option>, layout: TyLayout<'tcx>, - ) -> EvalResult<'tcx, Option<(Size, AbiAndPrefAlign)>> { + ) -> EvalResult<'tcx, Option<(Size, Align)>> { if !layout.is_unsized() { - return Ok(Some((layout.size, layout.align))); + return Ok(Some((layout.size, layout.align.abi))); } match layout.ty.sty { ty::Adt(..) | ty::Tuple(..) => { @@ -328,7 +328,7 @@ pub(super) fn size_and_align_of( trace!("DST layout: {:?}", layout); let sized_size = layout.fields.offset(layout.fields.count() - 1); - let sized_align = layout.align; + let sized_align = layout.align.abi; trace!( "DST {} statically sized prefix size: {:?} align: {:?}", layout.ty, @@ -381,7 +381,7 @@ pub(super) fn size_and_align_of( // // `(size + (align-1)) & -align` - Ok(Some((size.abi_align(align), align))) + Ok(Some((size.align_to(align), align))) } ty::Dynamic(..) => { let vtable = metadata.expect("dyn trait fat ptr must have vtable").to_ptr()?; @@ -392,7 +392,7 @@ pub(super) fn size_and_align_of( ty::Slice(_) | ty::Str => { let len = metadata.expect("slice fat ptr must have vtable").to_usize(self)?; let elem = layout.field(self, 0)?; - Ok(Some((elem.size * len, elem.align))) + Ok(Some((elem.size * len, elem.align.abi))) } ty::Foreign(_) => { @@ -406,7 +406,7 @@ pub(super) fn size_and_align_of( pub fn size_and_align_of_mplace( &self, mplace: MPlaceTy<'tcx, M::PointerTag> - ) -> EvalResult<'tcx, Option<(Size, AbiAndPrefAlign)>> { + ) -> EvalResult<'tcx, Option<(Size, Align)>> { self.size_and_align_of(mplace.meta, mplace.layout) } @@ -636,7 +636,7 @@ pub fn dump_place(&self, place: Place) { let (ptr, align) = mplace.to_scalar_ptr_align(); match ptr { Scalar::Ptr(ptr) => { - write!(msg, " by align({}) ref:", align.abi.bytes()).unwrap(); + write!(msg, " by align({}) ref:", align.bytes()).unwrap(); allocs.push(ptr.alloc_id); } ptr => write!(msg, " by integral ref: {:?}", ptr).unwrap(), @@ -665,7 +665,7 @@ pub fn dump_place(&self, place: Place) { Place::Ptr(mplace) => { match mplace.ptr { Scalar::Ptr(ptr) => { - trace!("by align({}) ref:", mplace.align.abi.bytes()); + trace!("by align({}) ref:", mplace.align.bytes()); self.memory.dump_alloc(ptr.alloc_id); } ptr => trace!(" integral by ref: {:?}", ptr), diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 681e73297542..898600d8322d 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -21,7 +21,7 @@ use std::borrow::Cow; use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; -use rustc::ty::layout::{self, Align, AbiAndPrefAlign, TargetDataLayout, Size, HasDataLayout}; +use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout}; pub use rustc::mir::interpret::{truncate, write_target_uint, read_target_uint}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; @@ -71,7 +71,7 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> { /// To be able to compare pointers with NULL, and to check alignment for accesses /// to ZSTs (where pointers may dangle), we keep track of the size even for allocations /// that do not exist any more. - dead_alloc_map: FxHashMap, + dead_alloc_map: FxHashMap, /// Lets us implement `HasDataLayout`, which is awfully convenient. pub(super) tcx: TyCtxtAt<'a, 'tcx, 'tcx>, @@ -130,7 +130,7 @@ pub fn allocate_with( pub fn allocate( &mut self, size: Size, - align: AbiAndPrefAlign, + align: Align, kind: MemoryKind, ) -> EvalResult<'tcx, Pointer> { Ok(Pointer::from(self.allocate_with(Allocation::undef(size, align), kind)?)) @@ -140,9 +140,9 @@ pub fn reallocate( &mut self, ptr: Pointer, old_size: Size, - old_align: AbiAndPrefAlign, + old_align: Align, new_size: Size, - new_align: AbiAndPrefAlign, + new_align: Align, kind: MemoryKind, ) -> EvalResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { @@ -179,7 +179,7 @@ pub fn deallocate_local(&mut self, ptr: Pointer) -> EvalResult<'t pub fn deallocate( &mut self, ptr: Pointer, - size_and_align: Option<(Size, AbiAndPrefAlign)>, + size_and_align: Option<(Size, Align)>, kind: MemoryKind, ) -> EvalResult<'tcx> { trace!("deallocating: {}", ptr.alloc_id); @@ -244,7 +244,7 @@ pub fn deallocate( pub fn check_align( &self, ptr: Scalar, - required_align: AbiAndPrefAlign + required_align: Align ) -> EvalResult<'tcx> { // Check non-NULL/Undef, extract offset let (offset, alloc_align) = match ptr { @@ -268,18 +268,18 @@ pub fn check_align( } }; // Check alignment - if alloc_align.abi < required_align.abi { + if alloc_align.bytes() < required_align.bytes() { return err!(AlignmentCheckFailed { has: alloc_align, required: required_align, }); } - if offset % required_align.abi.bytes() == 0 { + if offset % required_align.bytes() == 0 { Ok(()) } else { - let has = offset % required_align.abi.bytes(); + let has = offset % required_align.bytes(); err!(AlignmentCheckFailed { - has: AbiAndPrefAlign::new(Align::from_bytes(has).unwrap()), + has: Align::from_bytes(has).unwrap(), required: required_align, }) } @@ -443,22 +443,20 @@ pub fn get_mut( } } - pub fn get_size_and_align(&self, id: AllocId) -> (Size, AbiAndPrefAlign) { + pub fn get_size_and_align(&self, id: AllocId) -> (Size, Align) { if let Ok(alloc) = self.get(id) { return (Size::from_bytes(alloc.bytes.len() as u64), alloc.align); } // Could also be a fn ptr or extern static match self.tcx.alloc_map.lock().get(id) { - Some(AllocType::Function(..)) => { - (Size::ZERO, AbiAndPrefAlign::new(Align::from_bytes(1).unwrap())) - } + Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1).unwrap()), Some(AllocType::Static(did)) => { // The only way `get` couldn't have worked here is if this is an extern static assert!(self.tcx.is_foreign_item(did)); // Use size and align of the type let ty = self.tcx.type_of(did); let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); - (layout.size, layout.align) + (layout.size, layout.align.abi) } _ => { // Must be a deallocated pointer @@ -523,7 +521,7 @@ fn dump_alloc_helper( "{}({} bytes, alignment {}){}", msg, alloc.bytes.len(), - alloc.align.abi.bytes(), + alloc.align.bytes(), extra ); @@ -624,7 +622,7 @@ fn get_bytes_internal( &self, ptr: Pointer, size: Size, - align: AbiAndPrefAlign, + align: Align, check_defined_and_ptr: bool, ) -> EvalResult<'tcx, &[u8]> { assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); @@ -653,7 +651,7 @@ fn get_bytes( &self, ptr: Pointer, size: Size, - align: AbiAndPrefAlign + align: Align ) -> EvalResult<'tcx, &[u8]> { self.get_bytes_internal(ptr, size, align, true) } @@ -665,7 +663,7 @@ fn get_bytes_with_undef_and_ptr( &self, ptr: Pointer, size: Size, - align: AbiAndPrefAlign + align: Align ) -> EvalResult<'tcx, &[u8]> { self.get_bytes_internal(ptr, size, align, false) } @@ -676,7 +674,7 @@ fn get_bytes_mut( &mut self, ptr: Pointer, size: Size, - align: AbiAndPrefAlign, + align: Align, ) -> EvalResult<'tcx, &mut [u8]> { assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`"); self.check_align(ptr.into(), align)?; @@ -749,9 +747,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { pub fn copy( &mut self, src: Scalar, - src_align: AbiAndPrefAlign, + src_align: Align, dest: Scalar, - dest_align: AbiAndPrefAlign, + dest_align: Align, size: Size, nonoverlapping: bool, ) -> EvalResult<'tcx> { @@ -761,9 +759,9 @@ pub fn copy( pub fn copy_repeatedly( &mut self, src: Scalar, - src_align: AbiAndPrefAlign, + src_align: Align, dest: Scalar, - dest_align: AbiAndPrefAlign, + dest_align: Align, size: Size, length: u64, nonoverlapping: bool, @@ -865,7 +863,7 @@ pub fn check_bytes( allow_ptr_and_undef: bool, ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); + let align = Align::from_bytes(1).unwrap(); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); @@ -883,7 +881,7 @@ pub fn check_bytes( pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<'tcx, &[u8]> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); + let align = Align::from_bytes(1).unwrap(); if size.bytes() == 0 { self.check_align(ptr, align)?; return Ok(&[]); @@ -893,7 +891,7 @@ pub fn read_bytes(&self, ptr: Scalar, size: Size) -> EvalResult<' pub fn write_bytes(&mut self, ptr: Scalar, src: &[u8]) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); + let align = Align::from_bytes(1).unwrap(); if src.is_empty() { self.check_align(ptr, align)?; return Ok(()); @@ -910,7 +908,7 @@ pub fn write_repeat( count: Size ) -> EvalResult<'tcx> { // Empty accesses don't need to be valid pointers, but they should still be non-NULL - let align = AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()); + let align = Align::from_bytes(1).unwrap(); if count.bytes() == 0 { self.check_align(ptr, align)?; return Ok(()); @@ -926,7 +924,7 @@ pub fn write_repeat( pub fn read_scalar( &self, ptr: Pointer, - ptr_align: AbiAndPrefAlign, + ptr_align: Align, size: Size ) -> EvalResult<'tcx, ScalarMaybeUndef> { // get_bytes_unchecked tests alignment and relocation edges @@ -963,7 +961,7 @@ pub fn read_scalar( pub fn read_ptr_sized( &self, ptr: Pointer, - ptr_align: AbiAndPrefAlign + ptr_align: Align ) -> EvalResult<'tcx, ScalarMaybeUndef> { self.read_scalar(ptr, ptr_align, self.pointer_size()) } @@ -972,7 +970,7 @@ pub fn read_ptr_sized( pub fn write_scalar( &mut self, ptr: Pointer, - ptr_align: AbiAndPrefAlign, + ptr_align: Align, val: ScalarMaybeUndef, type_size: Size, ) -> EvalResult<'tcx> { @@ -1019,14 +1017,14 @@ pub fn write_scalar( pub fn write_ptr_sized( &mut self, ptr: Pointer, - ptr_align: AbiAndPrefAlign, + ptr_align: Align, val: ScalarMaybeUndef ) -> EvalResult<'tcx> { let ptr_size = self.pointer_size(); self.write_scalar(ptr.into(), ptr_align, val, ptr_size) } - fn int_align(&self, size: Size) -> AbiAndPrefAlign { + fn int_align(&self, size: Size) -> Align { // We assume pointer-sized integers have the same alignment as pointers. // We also assume signed and unsigned integers of the same size have the same alignment. let ity = match size.bytes() { @@ -1037,7 +1035,7 @@ fn int_align(&self, size: Size) -> AbiAndPrefAlign { 16 => layout::I128, _ => bug!("bad integer size: {}", size.bytes()), }; - ity.align(self) + ity.align(self).abi } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 5d993cfee084..8238d580022a 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -285,7 +285,7 @@ pub(super) fn try_read_immediate_from_mplace( let (a, b) = (&a.value, &b.value); let (a_size, b_size) = (a.size(self), b.size(self)); let a_ptr = ptr; - let b_offset = a_size.abi_align(b.align(self)); + let b_offset = a_size.align_to(b.align(self).abi); assert!(b_offset.bytes() > 0); // we later use the offset to test which field to use let b_ptr = ptr.offset(b_offset, self)?.into(); let a_val = self.memory.read_scalar(a_ptr, ptr_align, a_size)?; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index ed8b7cf1f90d..7ef3dd5f7201 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -18,8 +18,7 @@ use rustc::hir; use rustc::mir; use rustc::ty::{self, Ty}; -use rustc::ty::layout::{self, Size, Align, - AbiAndPrefAlign, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; +use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx}; use super::{ GlobalId, AllocId, Allocation, Scalar, EvalResult, Pointer, PointerArithmetic, @@ -33,7 +32,7 @@ pub struct MemPlace { /// be turned back into a reference before ever being dereferenced. /// However, it may never be undef. pub ptr: Scalar, - pub align: AbiAndPrefAlign, + pub align: Align, /// Metadata for unsized places. Interpretation is up to the type. /// Must not be present for sized types, but can be missing for unsized types /// (e.g. `extern type`). @@ -117,7 +116,7 @@ pub fn erase_tag(self) -> MemPlace } #[inline(always)] - pub fn from_scalar_ptr(ptr: Scalar, align: AbiAndPrefAlign) -> Self { + pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { MemPlace { ptr, align, @@ -128,17 +127,16 @@ pub fn from_scalar_ptr(ptr: Scalar, align: AbiAndPrefAlign) -> Self { /// Produces a Place that will error if attempted to be read from or written to #[inline(always)] pub fn null(cx: &impl HasDataLayout) -> Self { - Self::from_scalar_ptr(Scalar::ptr_null(cx), - AbiAndPrefAlign::new(Align::from_bytes(1).unwrap())) + Self::from_scalar_ptr(Scalar::ptr_null(cx), Align::from_bytes(1).unwrap()) } #[inline(always)] - pub fn from_ptr(ptr: Pointer, align: AbiAndPrefAlign) -> Self { + pub fn from_ptr(ptr: Pointer, align: Align) -> Self { Self::from_scalar_ptr(ptr.into(), align) } #[inline(always)] - pub fn to_scalar_ptr_align(self) -> (Scalar, AbiAndPrefAlign) { + pub fn to_scalar_ptr_align(self) -> (Scalar, Align) { assert!(self.meta.is_none()); (self.ptr, self.align) } @@ -170,7 +168,7 @@ pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self { MPlaceTy { mplace: MemPlace::from_scalar_ptr( Scalar::from_uint(layout.align.abi.bytes(), cx.pointer_size()), - layout.align + layout.align.abi ), layout } @@ -178,7 +176,7 @@ pub fn dangling(layout: TyLayout<'tcx>, cx: &impl HasDataLayout) -> Self { #[inline] fn from_aligned_ptr(ptr: Pointer, layout: TyLayout<'tcx>) -> Self { - MPlaceTy { mplace: MemPlace::from_ptr(ptr, layout.align), layout } + MPlaceTy { mplace: MemPlace::from_ptr(ptr, layout.align.abi), layout } } #[inline] @@ -232,12 +230,12 @@ pub fn null(cx: &impl HasDataLayout) -> Self { } #[inline(always)] - pub fn from_scalar_ptr(ptr: Scalar, align: AbiAndPrefAlign) -> Self { + pub fn from_scalar_ptr(ptr: Scalar, align: Align) -> Self { Place::Ptr(MemPlace::from_scalar_ptr(ptr, align)) } #[inline(always)] - pub fn from_ptr(ptr: Pointer, align: AbiAndPrefAlign) -> Self { + pub fn from_ptr(ptr: Pointer, align: Align) -> Self { Place::Ptr(MemPlace::from_ptr(ptr, align)) } @@ -251,7 +249,7 @@ pub fn to_mem_place(self) -> MemPlace { } #[inline] - pub fn to_scalar_ptr_align(self) -> (Scalar, AbiAndPrefAlign) { + pub fn to_scalar_ptr_align(self) -> (Scalar, Align) { self.to_mem_place().to_scalar_ptr_align() } @@ -289,7 +287,7 @@ pub fn ref_to_mplace( let mplace = MemPlace { ptr: val.to_scalar_ptr()?, - align: layout.align, + align: layout.align.abi, meta: val.to_meta()?, }; Ok(MPlaceTy { mplace, layout }) @@ -358,11 +356,11 @@ pub fn mplace_field( // FIXME: Once we have made decisions for how to handle size and alignment // of `extern type`, this should be adapted. It is just a temporary hack // to get some code to work that probably ought to work. - field_layout.align, + field_layout.align.abi, None => bug!("Cannot compute offset for extern type field at non-0 offset"), }; - (base.meta, offset.abi_align(align)) + (base.meta, offset.align_to(align)) } else { // base.meta could be present; we might be accessing a sized field of an unsized // struct. @@ -370,10 +368,10 @@ pub fn mplace_field( }; let ptr = base.ptr.ptr_offset(offset, self)?; - let align = AbiAndPrefAlign::new(base.align.abi + let align = base.align // We do not look at `base.layout.align` nor `field_layout.align`, unlike // codegen -- mostly to see if we can get away with that - .restrict_for_offset(offset)); // must be last thing that happens + .restrict_for_offset(offset); // must be last thing that happens Ok(MPlaceTy { mplace: MemPlace { ptr, align, meta }, layout: field_layout }) } @@ -732,7 +730,7 @@ fn write_immediate_to_mplace_no_validate( } self.memory.write_scalar( - ptr, ptr_align.min(dest.layout.align), scalar, dest.layout.size + ptr, ptr_align.min(dest.layout.align.abi), scalar, dest.layout.size ) } Immediate::ScalarPair(a_val, b_val) => { @@ -742,8 +740,8 @@ fn write_immediate_to_mplace_no_validate( dest.layout) }; let (a_size, b_size) = (a.size(self), b.size(self)); - let (a_align, b_align) = (a.align(self), b.align(self)); - let b_offset = a_size.abi_align(b_align); + let (a_align, b_align) = (a.align(self).abi, b.align(self).abi); + let b_offset = a_size.align_to(b_align); let b_ptr = ptr.offset(b_offset, self)?.into(); // It is tempting to verify `b_offset` against `layout.fields.offset(1)`, @@ -901,7 +899,7 @@ pub fn allocate( // FIXME: What should we do here? We should definitely also tag! Ok(MPlaceTy::dangling(layout, self)) } else { - let ptr = self.memory.allocate(layout.size, layout.align, kind)?; + let ptr = self.memory.allocate(layout.size, layout.align.abi, kind)?; let ptr = M::tag_new_allocation(self, ptr, kind)?; Ok(MPlaceTy::from_aligned_ptr(ptr, layout)) } @@ -1001,7 +999,7 @@ pub(super) fn unpack_dyn_trait(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) let (size, align) = self.read_size_and_align_from_vtable(vtable)?; assert_eq!(size, layout.size); // only ABI alignment is preserved - assert_eq!(align.abi, layout.align.abi); + assert_eq!(align, layout.align.abi); } let mplace = MPlaceTy { diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 56475dffae42..4b63335ad964 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -16,7 +16,7 @@ }; use rustc::ty::{self, TyCtxt}; -use rustc::ty::layout::AbiAndPrefAlign; +use rustc::ty::layout::Align; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; @@ -276,7 +276,7 @@ struct AllocationSnapshot<'a> { bytes: &'a [u8], relocations: Relocations<(), AllocIdSnapshot<'a>>, undef_mask: &'a UndefMask, - align: &'a AbiAndPrefAlign, + align: &'a Align, mutability: &'a Mutability, } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 6070b31d3e7a..fd17a4a71295 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -401,7 +401,7 @@ fn eval_fn_call( // cannot use the shim here, because that will only result in infinite recursion ty::InstanceDef::Virtual(_, idx) => { let ptr_size = self.pointer_size(); - let ptr_align = self.tcx.data_layout.pointer_align; + let ptr_align = self.tcx.data_layout.pointer_align.abi; let ptr = self.deref_operand(args[0])?; let vtable = ptr.vtable()?; let fn_ptr = self.memory.read_ptr_sized( diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 02843b898124..f11fd45b753f 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -9,7 +9,7 @@ // except according to those terms. use rustc::ty::{self, Ty}; -use rustc::ty::layout::{Size, Align, AbiAndPrefAlign, LayoutOf}; +use rustc::ty::layout::{Size, Align, LayoutOf}; use rustc::mir::interpret::{Scalar, Pointer, EvalResult, PointerArithmetic}; use super::{EvalContext, Machine, MemoryKind}; @@ -45,7 +45,7 @@ pub fn get_vtable( let align = layout.align.abi.bytes(); let ptr_size = self.pointer_size(); - let ptr_align = self.tcx.data_layout.pointer_align; + let ptr_align = self.tcx.data_layout.pointer_align.abi; // ///////////////////////////////////////////////////////////////////////////////////////// // If you touch this code, be sure to also make the corresponding changes to // `get_vtable` in rust_codegen_llvm/meth.rs @@ -87,7 +87,7 @@ pub fn read_drop_type_from_vtable( vtable: Pointer, ) -> EvalResult<'tcx, (ty::Instance<'tcx>, ty::Ty<'tcx>)> { // we don't care about the pointee type, we just want a pointer - let pointer_align = self.tcx.data_layout.pointer_align; + let pointer_align = self.tcx.data_layout.pointer_align.abi; let drop_fn = self.memory.read_ptr_sized(vtable, pointer_align)?.to_ptr()?; let drop_instance = self.memory.get_fn(drop_fn)?; trace!("Found drop fn: {:?}", drop_instance); @@ -101,15 +101,15 @@ pub fn read_drop_type_from_vtable( pub fn read_size_and_align_from_vtable( &self, vtable: Pointer, - ) -> EvalResult<'tcx, (Size, AbiAndPrefAlign)> { + ) -> EvalResult<'tcx, (Size, Align)> { let pointer_size = self.pointer_size(); - let pointer_align = self.tcx.data_layout.pointer_align; + let pointer_align = self.tcx.data_layout.pointer_align.abi; let size = self.memory.read_ptr_sized(vtable.offset(pointer_size, self)?,pointer_align)? .to_bits(pointer_size)? as u64; let align = self.memory.read_ptr_sized( vtable.offset(pointer_size * 2, self)?, pointer_align )?.to_bits(pointer_size)? as u64; - Ok((Size::from_bytes(size), AbiAndPrefAlign::new(Align::from_bytes(align).unwrap()))) + Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap())) } } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 352569b3b64f..6d1cacfa1479 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -13,7 +13,7 @@ use std::ops::RangeInclusive; use syntax_pos::symbol::Symbol; -use rustc::ty::layout::{self, Size, Align, AbiAndPrefAlign, TyLayout, LayoutOf, VariantIdx}; +use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx}; use rustc::ty; use rustc_data_structures::fx::FxHashSet; use rustc::mir::interpret::{ @@ -355,7 +355,7 @@ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'t // for the purpose of validity, consider foreign types to have // alignment and size determined by the layout (size will be 0, // alignment should take attributes into account). - .unwrap_or_else(|| (layout.size, layout.align)); + .unwrap_or_else(|| (layout.size, layout.align.abi)); match self.ecx.memory.check_align(ptr, align) { Ok(_) => {}, Err(err) => { @@ -463,7 +463,7 @@ fn visit_scalar( // for function pointers. let non_null = self.ecx.memory.check_align( - Scalar::Ptr(ptr), AbiAndPrefAlign::new(Align::from_bytes(1).unwrap()) + Scalar::Ptr(ptr), Align::from_bytes(1).unwrap() ).is_ok() || self.ecx.memory.get_fn(ptr).is_ok(); if !non_null { diff --git a/src/librustc_target/abi/call/mips.rs b/src/librustc_target/abi/call/mips.rs index a40cb6c76f0c..abe0bd07892d 100644 --- a/src/librustc_target/abi/call/mips.rs +++ b/src/librustc_target/abi/call/mips.rs @@ -27,21 +27,21 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) { let dl = cx.data_layout(); let size = arg.layout.size; - let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); + let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_abi_aligned(align) { + if !offset.is_aligned(align) { arg.pad_with(Reg::i32()); } } else { arg.extend_integer_width_to(32); } - *offset = offset.abi_align(align) + size.abi_align(align); + *offset = offset.align_to(align) + size.align_to(align); } pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) diff --git a/src/librustc_target/abi/call/mips64.rs b/src/librustc_target/abi/call/mips64.rs index adf5a3c94ea0..d375b163164d 100644 --- a/src/librustc_target/abi/call/mips64.rs +++ b/src/librustc_target/abi/call/mips64.rs @@ -118,9 +118,9 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>) // We only care about aligned doubles if let abi::Abi::Scalar(ref scalar) = field.abi { if let abi::Float(abi::FloatTy::F64) = scalar.value { - if offset.is_abi_aligned(dl.f64_align) { + if offset.is_aligned(dl.f64_align.abi) { // Insert enough integers to cover [last_offset, offset) - assert!(last_offset.is_abi_aligned(dl.f64_align)); + assert!(last_offset.is_aligned(dl.f64_align.abi)); for _ in 0..((offset - last_offset).bits() / 64) .min((prefix.len() - prefix_index) as u64) { diff --git a/src/librustc_target/abi/call/mod.rs b/src/librustc_target/abi/call/mod.rs index 289a76eae8f5..489bb37fc26f 100644 --- a/src/librustc_target/abi/call/mod.rs +++ b/src/librustc_target/abi/call/mod.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use abi::{self, Abi, AbiAndPrefAlign, FieldPlacement, Size}; +use abi::{self, Abi, Align, FieldPlacement, Size}; use abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods}; use spec::HasTargetSpec; @@ -80,7 +80,7 @@ pub struct ArgAttribute: u16 { pub struct ArgAttributes { pub regular: ArgAttribute, pub pointee_size: Size, - pub pointee_align: Option + pub pointee_align: Option } impl ArgAttributes { @@ -137,28 +137,28 @@ impl Reg { } impl Reg { - pub fn align(&self, cx: &C) -> AbiAndPrefAlign { + pub fn align(&self, cx: &C) -> Align { let dl = cx.data_layout(); match self.kind { RegKind::Integer => { match self.size.bits() { - 1 => dl.i1_align, - 2..=8 => dl.i8_align, - 9..=16 => dl.i16_align, - 17..=32 => dl.i32_align, - 33..=64 => dl.i64_align, - 65..=128 => dl.i128_align, + 1 => dl.i1_align.abi, + 2..=8 => dl.i8_align.abi, + 9..=16 => dl.i16_align.abi, + 17..=32 => dl.i32_align.abi, + 33..=64 => dl.i64_align.abi, + 65..=128 => dl.i128_align.abi, _ => panic!("unsupported integer: {:?}", self) } } RegKind::Float => { match self.size.bits() { - 32 => dl.f32_align, - 64 => dl.f64_align, + 32 => dl.f32_align.abi, + 64 => dl.f64_align.abi, _ => panic!("unsupported float: {:?}", self) } } - RegKind::Vector => dl.vector_align(self.size) + RegKind::Vector => dl.vector_align(self.size).abi, } } } @@ -188,7 +188,7 @@ fn from(unit: Reg) -> Uniform { } impl Uniform { - pub fn align(&self, cx: &C) -> AbiAndPrefAlign { + pub fn align(&self, cx: &C) -> Align { self.unit.align(cx) } } @@ -227,13 +227,13 @@ pub fn pair(a: Reg, b: Reg) -> CastTarget { pub fn size(&self, cx: &C) -> Size { (self.prefix_chunk * self.prefix.iter().filter(|x| x.is_some()).count() as u64) - .abi_align(self.rest.align(cx)) + self.rest.total + .align_to(self.rest.align(cx)) + self.rest.total } - pub fn align(&self, cx: &C) -> AbiAndPrefAlign { + pub fn align(&self, cx: &C) -> Align { self.prefix.iter() .filter_map(|x| x.map(|kind| Reg { kind, size: self.prefix_chunk }.align(cx))) - .fold(cx.data_layout().aggregate_align.max(self.rest.align(cx)), + .fold(cx.data_layout().aggregate_align.abi.max(self.rest.align(cx)), |acc, align| acc.max(align)) } } @@ -369,7 +369,7 @@ pub fn make_indirect(&mut self) { attrs.pointee_size = self.layout.size; // FIXME(eddyb) We should be doing this, but at least on // i686-pc-windows-msvc, it results in wrong stack offsets. - // attrs.pointee_align = Some(self.layout.align); + // attrs.pointee_align = Some(self.layout.align.abi); let extra_attrs = if self.layout.is_unsized() { Some(ArgAttributes::new()) diff --git a/src/librustc_target/abi/call/powerpc.rs b/src/librustc_target/abi/call/powerpc.rs index b9b012020b7f..a71f32263208 100644 --- a/src/librustc_target/abi/call/powerpc.rs +++ b/src/librustc_target/abi/call/powerpc.rs @@ -27,21 +27,21 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) { let dl = cx.data_layout(); let size = arg.layout.size; - let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); + let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_abi_aligned(align) { + if !offset.is_aligned(align) { arg.pad_with(Reg::i32()); } } else { arg.extend_integer_width_to(32); } - *offset = offset.abi_align(align) + size.abi_align(align); + *offset = offset.align_to(align) + size.align_to(align); } pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) diff --git a/src/librustc_target/abi/call/powerpc64.rs b/src/librustc_target/abi/call/powerpc64.rs index 7d78d1d75d52..99f07c5702a8 100644 --- a/src/librustc_target/abi/call/powerpc64.rs +++ b/src/librustc_target/abi/call/powerpc64.rs @@ -121,7 +121,7 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType<'a, Ty>, abi: ABI) // Aggregates larger than a doubleword should be padded // at the tail to fill out a whole number of doublewords. let reg_i64 = Reg::i64(); - (reg_i64, size.abi_align(reg_i64.align(cx))) + (reg_i64, size.align_to(reg_i64.align(cx))) }; arg.cast_to(Uniform { diff --git a/src/librustc_target/abi/call/sparc.rs b/src/librustc_target/abi/call/sparc.rs index a40cb6c76f0c..abe0bd07892d 100644 --- a/src/librustc_target/abi/call/sparc.rs +++ b/src/librustc_target/abi/call/sparc.rs @@ -27,21 +27,21 @@ fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgType, offset: &mut Size) { let dl = cx.data_layout(); let size = arg.layout.size; - let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align); + let align = arg.layout.align.max(dl.i32_align).min(dl.i64_align).abi; if arg.layout.is_aggregate() { arg.cast_to(Uniform { unit: Reg::i32(), total: size }); - if !offset.is_abi_aligned(align) { + if !offset.is_aligned(align) { arg.pad_with(Reg::i32()); } } else { arg.extend_integer_width_to(32); } - *offset = offset.abi_align(align) + size.abi_align(align); + *offset = offset.align_to(align) + size.align_to(align); } pub fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnType) diff --git a/src/librustc_target/abi/call/x86_64.rs b/src/librustc_target/abi/call/x86_64.rs index 4c9446508939..f091f80924d5 100644 --- a/src/librustc_target/abi/call/x86_64.rs +++ b/src/librustc_target/abi/call/x86_64.rs @@ -41,7 +41,7 @@ fn classify<'a, Ty, C>(cx: &C, layout: TyLayout<'a, Ty>, where Ty: TyLayoutMethods<'a, C> + Copy, C: LayoutOf> + HasDataLayout { - if !off.is_abi_aligned(layout.align) { + if !off.is_aligned(layout.align.abi) { if !layout.is_zst() { return Err(Memory); } diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 2eabe94754de..50ce0ad6915d 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -277,14 +277,14 @@ pub fn bits(self) -> u64 { } #[inline] - pub fn abi_align(self, align: AbiAndPrefAlign) -> Size { - let mask = align.abi.bytes() - 1; + pub fn align_to(self, align: Align) -> Size { + let mask = align.bytes() - 1; Size::from_bytes((self.bytes() + mask) & !mask) } #[inline] - pub fn is_abi_aligned(self, align: AbiAndPrefAlign) -> bool { - let mask = align.abi.bytes() - 1; + pub fn is_aligned(self, align: Align) -> bool { + let mask = align.bytes() - 1; self.bytes() & mask == 0 } @@ -425,7 +425,6 @@ pub fn restrict_for_offset(self, offset: Size) -> Align { /// A pair of aligments, ABI-mandated and preferred. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] -#[derive(PartialOrd, Ord)] // FIXME(eddyb) remove (error prone/incorrect) pub struct AbiAndPrefAlign { pub abi: Align, pub pref: Align, @@ -510,10 +509,9 @@ pub fn fit_unsigned(x: u128) -> Integer { } /// Find the smallest integer with the given alignment. - pub fn for_abi_align(cx: &C, align: AbiAndPrefAlign) -> Option { + pub fn for_align(cx: &C, wanted: Align) -> Option { let dl = cx.data_layout(); - let wanted = align.abi; for &candidate in &[I8, I16, I32, I64, I128] { if wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes() { return Some(candidate); @@ -523,10 +521,9 @@ pub fn for_abi_align(cx: &C, align: AbiAndPrefAlign) -> Option } /// Find the largest integer with the given alignment or less. - pub fn approximate_abi_align(cx: &C, align: AbiAndPrefAlign) -> Integer { + pub fn approximate_align(cx: &C, wanted: Align) -> Integer { let dl = cx.data_layout(); - let wanted = align.abi; // FIXME(eddyb) maybe include I128 in the future, when it works everywhere. for &candidate in &[I64, I32, I16] { if wanted >= candidate.align(dl).abi && wanted.bytes() >= candidate.size().bytes() { From 7c166f54b201dbefe27d4ab61dfdf640ac3a2722 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 22 Aug 2018 05:50:46 +0300 Subject: [PATCH 65/75] Move Cargo.{toml,lock} to the repository root directory. --- CONTRIBUTING.md | 7 +-- src/Cargo.lock => Cargo.lock | 0 src/Cargo.toml => Cargo.toml | 60 +++++++++---------- src/bootstrap/bootstrap.py | 2 +- src/bootstrap/dist.rs | 6 +- src/bootstrap/test.rs | 1 + src/bootstrap/tool.rs | 28 +++++++-- .../rustdoc-ui/failed-doctest-output.stdout | 4 +- src/tools/tidy/src/deps.rs | 8 +-- src/tools/tidy/src/extdeps.rs | 4 +- src/tools/tidy/src/lib.rs | 2 +- 11 files changed, 70 insertions(+), 52 deletions(-) rename src/Cargo.lock => Cargo.lock (100%) rename src/Cargo.toml => Cargo.toml (53%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fe6bea9d8dc3..e04b1bdfefdd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -494,16 +494,11 @@ the version in `Cargo.lock`, so the build can no longer continue. To resolve this, we need to update `Cargo.lock`. Luckily, cargo provides a command to do this easily. -First, go into the `src/` directory since that is where `Cargo.toml` is in -the rust repository. Then run, `cargo update -p rustfmt-nightly` to solve -the problem. - ``` -$ cd src $ cargo update -p rustfmt-nightly ``` -This should change the version listed in `src/Cargo.lock` to the new version you updated +This should change the version listed in `Cargo.lock` to the new version you updated the submodule to. Running `./x.py build` should work now. ## Writing Documentation diff --git a/src/Cargo.lock b/Cargo.lock similarity index 100% rename from src/Cargo.lock rename to Cargo.lock diff --git a/src/Cargo.toml b/Cargo.toml similarity index 53% rename from src/Cargo.toml rename to Cargo.toml index e8c44ea57c2e..1e1d7a40967b 100644 --- a/src/Cargo.toml +++ b/Cargo.toml @@ -1,31 +1,31 @@ [workspace] members = [ - "bootstrap", - "rustc", - "libstd", - "libtest", - "librustc_codegen_llvm", - "tools/cargotest", - "tools/clippy", - "tools/compiletest", - "tools/error_index_generator", - "tools/linkchecker", - "tools/rustbook", - "tools/unstable-book-gen", - "tools/tidy", - "tools/build-manifest", - "tools/remote-test-client", - "tools/remote-test-server", - "tools/rust-installer", - "tools/cargo", - "tools/rustdoc", - "tools/rls", - "tools/rustfmt", - "tools/miri", - "tools/rustdoc-themes", + "src/bootstrap", + "src/rustc", + "src/libstd", + "src/libtest", + "src/librustc_codegen_llvm", + "src/tools/cargotest", + "src/tools/clippy", + "src/tools/compiletest", + "src/tools/error_index_generator", + "src/tools/linkchecker", + "src/tools/rustbook", + "src/tools/unstable-book-gen", + "src/tools/tidy", + "src/tools/build-manifest", + "src/tools/remote-test-client", + "src/tools/remote-test-server", + "src/tools/rust-installer", + "src/tools/cargo", + "src/tools/rustdoc", + "src/tools/rls", + "src/tools/rustfmt", + "src/tools/miri", + "src/tools/rustdoc-themes", ] exclude = [ - "tools/rls/test_data", + "src/tools/rls/test_data", ] # Curiously, LLVM 7.0 will segfault if compiled with opt-level=3 @@ -50,18 +50,18 @@ debug-assertions = false # so we use a `[patch]` here to override the github repository with our local # vendored copy. [patch."https://github.com/rust-lang/cargo"] -cargo = { path = "tools/cargo" } +cargo = { path = "src/tools/cargo" } [patch.crates-io] # Similar to Cargo above we want the RLS to use a vendored version of `rustfmt` # that we're shipping as well (to ensure that the rustfmt in RLS and the # `rustfmt` executable are the same exact version). -rustfmt-nightly = { path = "tools/rustfmt" } +rustfmt-nightly = { path = "src/tools/rustfmt" } -# See comments in `tools/rustc-workspace-hack/README.md` for what's going on +# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on # here -rustc-workspace-hack = { path = 'tools/rustc-workspace-hack' } +rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' } [patch."https://github.com/rust-lang-nursery/rust-clippy"] -clippy_lints = { path = "tools/clippy/clippy_lints" } -rustc_tools_util = { path = "tools/clippy/rustc_tools_util" } +clippy_lints = { path = "src/tools/clippy/clippy_lints" } +rustc_tools_util = { path = "src/tools/clippy/rustc_tools_util" } diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index cd48e6aa4c4b..d143dffb24be 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -801,7 +801,7 @@ def bootstrap(help_triggered): registry = 'https://example.com' [source.vendored-sources] - directory = '{}/src/vendor' + directory = '{}/vendor' """.format(build.rust_root)) else: if os.path.exists('.cargo'): diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 0aab64465fd1..cd8d5642b257 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -851,7 +851,7 @@ fn run(self, builder: &Builder) -> PathBuf { t!(fs::create_dir_all(&dst_src)); let src_files = [ - "src/Cargo.lock", + "Cargo.lock", ]; // This is the reduced set of paths which will become the rust-src component // (essentially libstd and all of its path dependencies) @@ -949,6 +949,8 @@ fn run(self, builder: &Builder) -> PathBuf { "configure", "x.py", "config.toml.example", + "Cargo.toml", + "Cargo.lock", ]; let src_dirs = [ "src", @@ -992,7 +994,7 @@ fn run(self, builder: &Builder) -> PathBuf { // Vendor all Cargo dependencies let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("vendor") - .current_dir(&plain_dst_src.join("src")); + .current_dir(&plain_dst_src); builder.run(&mut cmd); } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index e55773011df8..c50e6a270339 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1934,6 +1934,7 @@ fn run(self, builder: &Builder) { .arg("generate-lockfile") .arg("--manifest-path") .arg(&toml) + .env("__CARGO_TEST_ROOT", &dir) .current_dir(&dir), ); } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d8e86644ee05..4acc739db57b 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -260,8 +260,13 @@ pub fn prepare_tool_cargo( } macro_rules! tool { - ($($name:ident, $path:expr, $tool_name:expr, $mode:expr - $(,llvm_tools = $llvm:expr)* $(,is_external_tool = $external:expr)*;)+) => { + ($( + $name:ident, $path:expr, $tool_name:expr, $mode:expr + $(,llvm_tools = $llvm:expr)* + $(,is_external_tool = $external:expr)* + $(,cargo_test_root = $cargo_test_root:expr)* + ; + )+) => { #[derive(Copy, PartialEq, Eq, Clone)] pub enum Tool { $( @@ -283,6 +288,15 @@ pub fn uses_llvm_tools(&self) -> bool { $(Tool::$name => false $(|| $llvm)*,)+ } } + + /// Whether this tool requires may run Cargo for test crates, + /// which currently needs setting the environment variable + /// `__CARGO_TEST_ROOT` to separate it from the workspace. + pub fn needs_cargo_test_root(&self) -> bool { + match self { + $(Tool::$name => false $(|| $cargo_test_root)*,)+ + } + } } impl<'a> Builder<'a> { @@ -358,8 +372,9 @@ fn run(self, builder: &Builder) -> PathBuf { UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolBootstrap; Tidy, "src/tools/tidy", "tidy", Mode::ToolBootstrap; Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolBootstrap; - CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolBootstrap; - Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, llvm_tools = true; + CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolBootstrap, cargo_test_root = true; + Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, + llvm_tools = true, cargo_test_root = true; BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolBootstrap; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolBootstrap; RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap, @@ -678,6 +693,11 @@ fn prepare_tool_cmd(&self, compiler: Compiler, tool: Tool, cmd: &mut Command) { } } + // Set `__CARGO_TEST_ROOT` to the build directory if needed. + if tool.needs_cargo_test_root() { + cmd.env("__CARGO_TEST_ROOT", &self.config.out); + } + add_lib_path(lib_paths, cmd); } diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 527f1355a9ef..cab7bda6c672 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -12,7 +12,7 @@ error[E0425]: cannot find value `no` in this scope 3 | no | ^^ not found in this scope -thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', librustdoc/test.rs:323:13 +thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:323:13 note: Run with `RUST_BACKTRACE=1` for a backtrace. ---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ---- @@ -21,7 +21,7 @@ thread '$DIR/failed-doctest-output.rs - SomeStruct (line 21)' panicked at 'test thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1 note: Run with `RUST_BACKTRACE=1` for a backtrace. -', librustdoc/test.rs:358:17 +', src/librustdoc/test.rs:358:17 failures: diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 2dfb9fc68ac1..a40ae8894d5e 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Check license of third-party deps by inspecting src/vendor +//! Check license of third-party deps by inspecting vendor use std::collections::{BTreeSet, HashSet, HashMap}; use std::fs::File; @@ -203,7 +203,7 @@ fn from(cv: CrateVersion<'a>) -> Crate<'a> { /// Specifically, this checks that the license is correct. pub fn check(path: &Path, bad: &mut bool) { // Check licences - let path = path.join("vendor"); + let path = path.join("../vendor"); assert!(path.exists(), "vendor directory missing"); let mut saw_dir = false; for dir in t!(path.read_dir()) { @@ -215,7 +215,7 @@ pub fn check(path: &Path, bad: &mut bool) { dir.path() .to_str() .unwrap() - .contains(&format!("src/vendor/{}", exception)) + .contains(&format!("vendor/{}", exception)) }); if is_exception { continue; @@ -304,7 +304,7 @@ fn get_deps(path: &Path, cargo: &Path) -> Resolve { .arg("--format-version") .arg("1") .arg("--manifest-path") - .arg(path.join("Cargo.toml")) + .arg(path.join("../Cargo.toml")) .output() .expect("Unable to run `cargo metadata`") .stdout; diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index 7f58b440a833..a78d2d4ee4e1 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -21,8 +21,8 @@ /// check for external package sources pub fn check(path: &Path, bad: &mut bool) { - // Cargo.lock of rust: src/Cargo.lock - let path = path.join("Cargo.lock"); + // Cargo.lock of rust (tidy runs inside src/) + let path = path.join("../Cargo.lock"); // open and read the whole file let mut cargo_lock = String::new(); diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index e235de9c5e13..700103d35d88 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -64,7 +64,6 @@ fn filter_dirs(path: &Path) -> bool { "src/librustc_data_structures/owning_ref", "src/compiler-rt", "src/liblibc", - "src/vendor", "src/rt/hoedown", "src/tools/cargo", "src/tools/clang", @@ -78,6 +77,7 @@ fn filter_dirs(path: &Path) -> bool { "src/target", "src/stdsimd", "target", + "vendor", ]; skip.iter().any(|p| path.ends_with(p)) } From 8e814ae608d5695d2a1c176cf82773e33ad005f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 21 Nov 2018 15:10:05 +0100 Subject: [PATCH 66/75] submodules: update clippy from f5d868c9 to 2f6881c6 ```` missed another one in the README run "util/dev update_lints" rust-lang-nursery/rust-clippy => rust-lang/rust-clippy Address 'clippy::single-match' dogfood lint Fix nit Address travis CI lint failure Update trivially_copy_pass_by_ref with Trait stderr output issue#3318 run trivially_copy_pass_by_ref for traits Update trivially_copy_pass_by_ref with Trait examples Fix awkward wording Document how to lint local Clippy changes with locally built Clippy Enable rustup clippy to refer to the correct documentation rustup https://github.com/rust-lang/rust/pull/52591 remove unused allow() attributes, NFC Add regression test Don't emit suggestion when inside of a macro ```` --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index f5d868c9edfc..2f6881c62325 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit f5d868c9edfc6c2a9310d564a2f738bec67dfd6b +Subproject commit 2f6881c62325c34115502b8901bf3ef0931b23cd From b83150e6acb2d80a5885d99cf0fca29b2f2fc513 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 22 Nov 2018 06:41:26 -0500 Subject: [PATCH 67/75] only reset non-restricted visibilities --- src/librustc/hir/lowering.rs | 33 +++++++++++++++++++++++++++------ src/librustc_lint/builtin.rs | 10 +--------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 5b38263f90f0..e53deaf87881 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2752,7 +2752,7 @@ fn lower_item_kind( id: NodeId, name: &mut Name, attrs: &hir::HirVec, - vis: &hir::Visibility, + vis: &mut hir::Visibility, i: &ItemKind, ) -> hir::ItemKind { match *i { @@ -2955,7 +2955,7 @@ fn lower_use_tree( tree: &UseTree, prefix: &Path, id: NodeId, - vis: &hir::Visibility, + vis: &mut hir::Visibility, name: &mut Name, attrs: &hir::HirVec, ) -> hir::ItemKind { @@ -3086,7 +3086,7 @@ fn lower_use_tree( hir_id: new_hir_id, } = self.lower_node_id(id); - let vis = vis.clone(); + let mut vis = vis.clone(); let mut name = name.clone(); let mut prefix = prefix.clone(); @@ -3104,7 +3104,7 @@ fn lower_use_tree( let item = this.lower_use_tree(use_tree, &prefix, new_id, - &vis, + &mut vis, &mut name, attrs); @@ -3139,6 +3139,27 @@ fn lower_use_tree( }); } + // Subtle and a bit hacky: we lower the privacy level + // of the list stem to "private" most of the time, but + // not for "restricted" paths. The key thing is that + // we don't want it to stay as `pub` (with no caveats) + // because that affects rustdoc and also the lints + // about `pub` items. But we can't *always* make it + // private -- particularly not for restricted paths -- + // because it contains node-ids that would then be + // unused, failing the check that HirIds are "densely + // assigned". + match vis.node { + hir::VisibilityKind::Public | + hir::VisibilityKind::Crate(_) | + hir::VisibilityKind::Inherited => { + *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); + } + hir::VisibilityKind::Restricted { .. } => { + // do nothing here, as described in the comment on the match + } + } + let def = self.expect_full_def_from_use(id).next().unwrap_or(Def::Err); let path = P(self.lower_path_extra(def, &prefix, ParamMode::Explicit, None)); hir::ItemKind::Use(path, hir::UseKind::ListStem) @@ -3384,7 +3405,7 @@ fn lower_item_id_use_tree(&mut self, pub fn lower_item(&mut self, i: &Item) -> Option { let mut name = i.ident.name; - let vis = self.lower_visibility(&i.vis, None); + let mut vis = self.lower_visibility(&i.vis, None); let attrs = self.lower_attrs(&i.attrs); if let ItemKind::MacroDef(ref def) = i.node { if !def.legacy || attr::contains_name(&i.attrs, "macro_export") || @@ -3403,7 +3424,7 @@ pub fn lower_item(&mut self, i: &Item) -> Option { return None; } - let node = self.lower_item_kind(i.id, &mut name, &attrs, &vis, &i.node); + let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node); let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 0348ba1f1afe..7dd1ca3493e9 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1136,15 +1136,7 @@ fn perform_lint(&self, cx: &LateContext, what: &str, id: ast::NodeId, impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnreachablePub { fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { - match item.node { - hir::ItemKind::Use(_, hir::UseKind::ListStem) => { - // Hack: ignore these `use foo::{}` remnants which are just a figment - // our IR. - } - _ => { - self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); - } - } + self.perform_lint(cx, "item", item.id, &item.vis, item.span, true); } fn check_foreign_item(&mut self, cx: &LateContext, foreign_item: &hir::ForeignItem) { From 5f2a173f75204e23737eef128edc74f88dba7f39 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 22 Nov 2018 06:48:13 -0500 Subject: [PATCH 68/75] explain how this works --- src/librustc/hir/lowering.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e53deaf87881..b3ba2968c9f5 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3070,7 +3070,29 @@ fn lower_use_tree( hir::ItemKind::Use(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { - // Nested imports are desugared into simple imports. + // Nested imports are desugared into simple + // imports. So if we start with + // + // ``` + // pub(x) use foo::{a, b}; + // ``` + // + // we will create three items: + // + // ``` + // pub(x) use foo::a; + // pub(x) use foo::b; + // pub(x) use foo::{}; // <-- this is called the `ListStem` + // ``` + // + // The first two are produced by recursively invoking + // `lower_use_tree` (and indeed there may be things + // like `use foo::{a::{b, c}}` and so forth). They + // wind up being directly added to + // `self.items`. However, the structure of this + // function also requires us to return one item, and + // for that we return the `{}` import (called the + // "`ListStem`"). let prefix = Path { segments, From abdcb868ff69a5f6a96dd188ff845a1ec67335f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 17:51:13 -0800 Subject: [PATCH 69/75] Point at every unexpected lifetime and type argument in E0107 --- src/librustc_typeck/astconv.rs | 57 ++++++++++++++------------ src/test/ui/error-codes/E0107-b.rs | 8 ++++ src/test/ui/error-codes/E0107-b.stderr | 24 +++++++++++ src/test/ui/error-codes/E0107.rs | 3 +- src/test/ui/error-codes/E0107.stderr | 6 ++- 5 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 src/test/ui/error-codes/E0107-b.rs create mode 100644 src/test/ui/error-codes/E0107-b.stderr diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d388d7564388..277f7d345462 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -338,33 +338,31 @@ fn check_generic_arg_count( (required, "") }; - let mut span = span; - let label = if required == permitted && provided > permitted { - let diff = provided - permitted; - if diff == 1 { - // In the case when the user has provided too many arguments, - // we want to point to the first unexpected argument. - let first_superfluous_arg: &GenericArg = &args.args[offset + permitted]; - span = first_superfluous_arg.span(); - } - format!( - "{}unexpected {} argument{}", - if diff != 1 { format!("{} ", diff) } else { String::new() }, - kind, - if diff != 1 { "s" } else { "" }, + let (spans, label) = if required == permitted && provided > permitted { + // In the case when the user has provided too many arguments, + // we want to point to the unexpected arguments. + ( + args.args[offset+permitted .. offset+provided] + .iter() + .map(|arg| arg.span()) + .collect(), + format!( + "unexpected {} argument", + kind, + ), ) } else { - format!( + (vec![span], format!( "expected {}{} {} argument{}", quantifier, bound, kind, if bound != 1 { "s" } else { "" }, - ) + )) }; - tcx.sess.struct_span_err_with_code( - span, + let mut err = tcx.sess.struct_span_err_with_code( + spans.clone(), &format!( "wrong number of {} arguments: expected {}{}, found {}", kind, @@ -373,7 +371,11 @@ fn check_generic_arg_count( provided, ), DiagnosticId::Error("E0107".into()) - ).span_label(span, label).emit(); + ); + for span in spans { + err.span_label(span, label.as_str()); + } + err.emit(); provided > required // `suppress_error` }; @@ -1030,13 +1032,16 @@ fn conv_object_ty_poly_trait_ref(&self, for item_def_id in associated_types { let assoc_item = tcx.associated_item(item_def_id); let trait_def_id = assoc_item.container.id(); - struct_span_err!(tcx.sess, span, E0191, "the value of the associated type `{}` \ - (from the trait `{}`) must be specified", - assoc_item.ident, - tcx.item_path_str(trait_def_id)) - .span_label(span, format!("missing associated type `{}` value", - assoc_item.ident)) - .emit(); + let mut err = struct_span_err!( + tcx.sess, + span, + E0191, + "the value of the associated type `{}` (from the trait `{}`) must be specified", + assoc_item.ident, + tcx.item_path_str(trait_def_id), + ); + err.span_label(span, format!("missing associated type `{}` value", assoc_item.ident)); + err.emit(); } // Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above. diff --git a/src/test/ui/error-codes/E0107-b.rs b/src/test/ui/error-codes/E0107-b.rs new file mode 100644 index 000000000000..58e7718ba5bb --- /dev/null +++ b/src/test/ui/error-codes/E0107-b.rs @@ -0,0 +1,8 @@ +pub trait T { + type A; + type B; + type C; +} + pub struct Foo { i: Box> } + + fn main() {} diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/error-codes/E0107-b.stderr new file mode 100644 index 000000000000..28b957dc91e7 --- /dev/null +++ b/src/test/ui/error-codes/E0107-b.stderr @@ -0,0 +1,24 @@ +error[E0107]: wrong number of type arguments: expected 2, found 4 + --> $DIR/E0107-b.rs:6:42 + | +LL | pub struct Foo { i: Box> } + | ^^^^^ ^^^^^ unexpected type argument + | | + | unexpected type argument + +error[E0191]: the value of the associated type `A` (from the trait `T`) must be specified + --> $DIR/E0107-b.rs:6:26 + | +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `A` value + +error[E0191]: the value of the associated type `C` (from the trait `T`) must be specified + --> $DIR/E0107-b.rs:6:26 + | +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `C` value + +error: aborting due to 3 previous errors + +Some errors occurred: E0107, E0191. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/error-codes/E0107.rs b/src/test/ui/error-codes/E0107.rs index 815c7fefd2a9..87ac9e37853c 100644 --- a/src/test/ui/error-codes/E0107.rs +++ b/src/test/ui/error-codes/E0107.rs @@ -26,7 +26,8 @@ struct Baz<'a, 'b, 'c> { //~| unexpected lifetime argument foo2: Foo<'a, 'b, 'c>, //~^ ERROR E0107 - //~| 2 unexpected lifetime arguments + //~| unexpected lifetime argument + //~| unexpected lifetime argument } fn main() {} diff --git a/src/test/ui/error-codes/E0107.stderr b/src/test/ui/error-codes/E0107.stderr index 497fa91bd4f3..a07c92cf26af 100644 --- a/src/test/ui/error-codes/E0107.stderr +++ b/src/test/ui/error-codes/E0107.stderr @@ -11,10 +11,12 @@ LL | bar: Bar<'a>, | ^^ unexpected lifetime argument error[E0107]: wrong number of lifetime arguments: expected 1, found 3 - --> $DIR/E0107.rs:27:11 + --> $DIR/E0107.rs:27:19 | LL | foo2: Foo<'a, 'b, 'c>, - | ^^^^^^^^^^^^^^^ 2 unexpected lifetime arguments + | ^^ ^^ unexpected lifetime argument + | | + | unexpected lifetime argument error: aborting due to 3 previous errors From 286f7ae1dde03478fc0f36b7d1f3dc97cb47b730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 18:11:37 -0800 Subject: [PATCH 70/75] Join multiple E0191 errors in the same location under a single diagnostic --- src/librustc_typeck/astconv.rs | 27 ++++++++++++++----- .../associated-types-incomplete-object.rs | 3 +-- .../associated-types-incomplete-object.stderr | 15 +++++------ src/test/ui/error-codes/E0107-b.stderr | 15 +++++------ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 277f7d345462..906b800ee447 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1029,18 +1029,31 @@ fn conv_object_ty_poly_trait_ref(&self, associated_types.remove(&projection_bound.projection_def_id()); } - for item_def_id in associated_types { - let assoc_item = tcx.associated_item(item_def_id); - let trait_def_id = assoc_item.container.id(); + if !associated_types.is_empty() { + let names = associated_types.iter().map(|item_def_id| { + let assoc_item = tcx.associated_item(*item_def_id); + let trait_def_id = assoc_item.container.id(); + format!( + "`{}` (from the trait `{}`)", + assoc_item.ident, + tcx.item_path_str(trait_def_id), + ) + }).collect::>().join(", "); let mut err = struct_span_err!( tcx.sess, span, E0191, - "the value of the associated type `{}` (from the trait `{}`) must be specified", - assoc_item.ident, - tcx.item_path_str(trait_def_id), + "the value of the associated type{} {} must be specified", + if associated_types.len() == 1 { "" } else { "s" }, + names, ); - err.span_label(span, format!("missing associated type `{}` value", assoc_item.ident)); + for item_def_id in associated_types { + let assoc_item = tcx.associated_item(item_def_id); + err.span_label( + span, + format!("missing associated type `{}` value", assoc_item.ident), + ); + } err.emit(); } diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.rs b/src/test/ui/associated-types/associated-types-incomplete-object.rs index 9f1df14605b6..e575fd695b2d 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.rs +++ b/src/test/ui/associated-types/associated-types-incomplete-object.rs @@ -37,6 +37,5 @@ pub fn main() { //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified let d = &42isize as &Foo; - //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified - //~| ERROR the value of the associated type `B` (from the trait `Foo`) must be specified + //~^ ERROR the value of the associated types `A` (from the trait `Foo`), `B` (from the trait } diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr index 95b1c6312500..5a3c243efd08 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.stderr +++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr @@ -10,18 +10,15 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must b LL | let c = &42isize as &Foo; | ^^^^^^^^^^^ missing associated type `A` value -error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified +error[E0191]: the value of the associated types `A` (from the trait `Foo`), `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:39:26 | LL | let d = &42isize as &Foo; - | ^^^ missing associated type `A` value + | ^^^ + | | + | missing associated type `A` value + | missing associated type `B` value -error[E0191]: the value of the associated type `B` (from the trait `Foo`) must be specified - --> $DIR/associated-types-incomplete-object.rs:39:26 - | -LL | let d = &42isize as &Foo; - | ^^^ missing associated type `B` value - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0191`. diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/error-codes/E0107-b.stderr index 28b957dc91e7..f779ca1e0b13 100644 --- a/src/test/ui/error-codes/E0107-b.stderr +++ b/src/test/ui/error-codes/E0107-b.stderr @@ -6,19 +6,16 @@ LL | pub struct Foo { i: Box> } | | | unexpected type argument -error[E0191]: the value of the associated type `A` (from the trait `T`) must be specified +error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified --> $DIR/E0107-b.rs:6:26 | LL | pub struct Foo { i: Box> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `A` value + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | missing associated type `A` value + | missing associated type `C` value -error[E0191]: the value of the associated type `C` (from the trait `T`) must be specified - --> $DIR/E0107-b.rs:6:26 - | -LL | pub struct Foo { i: Box> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `C` value - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors occurred: E0107, E0191. For more information about an error, try `rustc --explain E0107`. From b6f4b29c6df3fc78adbda9c915f01f8e354d9ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 18:14:41 -0800 Subject: [PATCH 71/75] Point at the associated type's def span --- src/librustc_typeck/astconv.rs | 4 ++++ ...d-type-projection-from-multiple-supertraits.stderr | 3 +++ .../associated-types-incomplete-object.stderr | 11 +++++++++++ src/test/ui/error-codes/E0107-b.stderr | 6 ++++++ src/test/ui/error-codes/E0191.stderr | 3 +++ src/test/ui/error-codes/E0220.stderr | 3 +++ src/test/ui/issues/issue-19482.stderr | 3 +++ src/test/ui/issues/issue-21950.stderr | 5 +++++ src/test/ui/issues/issue-22434.stderr | 3 +++ src/test/ui/issues/issue-22560.stderr | 5 +++++ src/test/ui/issues/issue-23024.stderr | 5 +++++ src/test/ui/issues/issue-28344.stderr | 10 ++++++++++ src/test/ui/traits/trait-alias-object.stderr | 5 +++++ 13 files changed, 66 insertions(+) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 906b800ee447..173f7ababe36 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1053,6 +1053,10 @@ fn conv_object_ty_poly_trait_ref(&self, span, format!("missing associated type `{}` value", assoc_item.ident), ); + err.span_label( + tcx.def_span(item_def_id), + format!("`{}` defined here", assoc_item.ident), + ); } err.emit(); } diff --git a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr index 7a10b6d021f5..726078f44a7e 100644 --- a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr +++ b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr @@ -25,6 +25,9 @@ LL | fn dent_object(c: BoxCar) { error[E0191]: the value of the associated type `Color` (from the trait `Vehicle`) must be specified --> $DIR/associated-type-projection-from-multiple-supertraits.rs:33:26 | +LL | type Color; + | ----------- `Color` defined here +... LL | fn dent_object(c: BoxCar) { | ^^^^^^^^^^^^^^^^^^^ missing associated type `Color` value diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr index 5a3c243efd08..933f059ebf48 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.stderr +++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr @@ -1,18 +1,29 @@ error[E0191]: the value of the associated type `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:33:26 | +LL | type B; + | ------- `B` defined here +... LL | let b = &42isize as &Foo; | ^^^^^^^^^^^^ missing associated type `B` value error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:36:26 | +LL | type A; + | ------- `A` defined here +... LL | let c = &42isize as &Foo; | ^^^^^^^^^^^ missing associated type `A` value error[E0191]: the value of the associated types `A` (from the trait `Foo`), `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:39:26 | +LL | type A; + | ------- `A` defined here +LL | type B; + | ------- `B` defined here +... LL | let d = &42isize as &Foo; | ^^^ | | diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/error-codes/E0107-b.stderr index f779ca1e0b13..1e8c683aff6a 100644 --- a/src/test/ui/error-codes/E0107-b.stderr +++ b/src/test/ui/error-codes/E0107-b.stderr @@ -9,6 +9,12 @@ LL | pub struct Foo { i: Box> } error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified --> $DIR/E0107-b.rs:6:26 | +LL | type A; + | ------- `A` defined here +LL | type B; +LL | type C; + | ------- `C` defined here +LL | } LL | pub struct Foo { i: Box> } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | diff --git a/src/test/ui/error-codes/E0191.stderr b/src/test/ui/error-codes/E0191.stderr index 08b0a845814d..a1f7c935c4a4 100644 --- a/src/test/ui/error-codes/E0191.stderr +++ b/src/test/ui/error-codes/E0191.stderr @@ -1,6 +1,9 @@ error[E0191]: the value of the associated type `Bar` (from the trait `Trait`) must be specified --> $DIR/E0191.rs:15:12 | +LL | type Bar; + | --------- `Bar` defined here +... LL | type Foo = Trait; //~ ERROR E0191 | ^^^^^ missing associated type `Bar` value diff --git a/src/test/ui/error-codes/E0220.stderr b/src/test/ui/error-codes/E0220.stderr index c8a587f2b535..7ddd912d4f2b 100644 --- a/src/test/ui/error-codes/E0220.stderr +++ b/src/test/ui/error-codes/E0220.stderr @@ -7,6 +7,9 @@ LL | type Foo = Trait; //~ ERROR E0220 error[E0191]: the value of the associated type `Bar` (from the trait `Trait`) must be specified --> $DIR/E0220.rs:15:12 | +LL | type Bar; + | --------- `Bar` defined here +... LL | type Foo = Trait; //~ ERROR E0220 | ^^^^^^^^^^^^ missing associated type `Bar` value diff --git a/src/test/ui/issues/issue-19482.stderr b/src/test/ui/issues/issue-19482.stderr index 5e2d427ab725..7e71b0bd2323 100644 --- a/src/test/ui/issues/issue-19482.stderr +++ b/src/test/ui/issues/issue-19482.stderr @@ -1,6 +1,9 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/issue-19482.rs:20:12 | +LL | type A; + | ------- `A` defined here +... LL | fn bar(x: &Foo) {} | ^^^ missing associated type `A` value diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index a2f74a29aab7..3359225ab6db 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -11,6 +11,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | &Add; | ^^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-22434.stderr b/src/test/ui/issues/issue-22434.stderr index 914da801ad4e..d951d57444d0 100644 --- a/src/test/ui/issues/issue-22434.stderr +++ b/src/test/ui/issues/issue-22434.stderr @@ -1,6 +1,9 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/issue-22434.rs:15:19 | +LL | type A; + | ------- `A` defined here +... LL | type I<'a> = &'a (Foo + 'a); | ^^^^^^^^ missing associated type `A` value diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr index b5524036fae9..8f736aa03453 100644 --- a/src/test/ui/issues/issue-22560.stderr +++ b/src/test/ui/issues/issue-22560.stderr @@ -29,6 +29,11 @@ LL | | //~^ ERROR E0393 LL | | //~| ERROR E0191 LL | | Sub; | |_______________^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 129d09453036..8a493468dbf9 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -17,6 +17,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | println!("{:?}",(vfnfer[0] as Fn)(3)); | ^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/function.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 7ef2e906422e..67588ba46f2e 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -3,6 +3,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | ^^^^^^^^^^^^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:14:17 @@ -17,6 +22,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let g = BitXor::bitor; | ^^^^^^^^^^^^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:18:13 diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr index 6b7b322a53d9..0ae9b0b88641 100644 --- a/src/test/ui/traits/trait-alias-object.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -11,6 +11,11 @@ error[E0191]: the value of the associated type `Item` (from the trait `std::iter | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value + | + ::: $SRC_DIR/libcore/iter/iterator.rs:LL:COL + | +LL | type Item; + | ---------- `Item` defined here error: aborting due to 2 previous errors From 48fa974211990ec2dd2b8d8c6949d101fb51bb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 18:54:34 -0800 Subject: [PATCH 72/75] Suggest correct syntax when writing type arg instead of assoc type When confusing an associated type with a type argument, suggest the appropriate syntax. Given `Iterator`, suggest `Iterator`. --- src/librustc_typeck/astconv.rs | 114 +++++++++++------- src/librustc_typeck/collect.rs | 11 +- src/librustc_typeck/lib.rs | 2 +- ...se-type-argument-instead-of-assoc-type.rs} | 0 ...ype-argument-instead-of-assoc-type.stderr} | 8 +- 5 files changed, 88 insertions(+), 47 deletions(-) rename src/test/ui/{error-codes/E0107-b.rs => suggestions/use-type-argument-instead-of-assoc-type.rs} (100%) rename src/test/ui/{error-codes/E0107-b.stderr => suggestions/use-type-argument-instead-of-assoc-type.stderr} (75%) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 173f7ababe36..f1192cf98ae1 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -182,7 +182,7 @@ pub fn ast_path_substs_for_ty(&self, item_segment: &hir::PathSegment) -> &'tcx Substs<'tcx> { - let (substs, assoc_bindings) = item_segment.with_generic_args(|generic_args| { + let (substs, assoc_bindings, _) = item_segment.with_generic_args(|generic_args| { self.create_substs_for_ast_path( span, def_id, @@ -256,7 +256,7 @@ pub fn check_generic_arg_count_for_call( }, def.parent.is_none() && def.has_self, // `has_self` seg.infer_types || suppress_mismatch, // `infer_types` - ) + ).0 } /// Check that the correct number of generic arguments have been provided. @@ -269,7 +269,7 @@ fn check_generic_arg_count( position: GenericArgPosition, has_self: bool, infer_types: bool, - ) -> bool { + ) -> (bool, Option>) { // At this stage we are guaranteed that the generic arguments are in the correct order, e.g. // that lifetimes will proceed types. So it suffices to check the number of each generic // arguments in order to validate them with respect to the generic parameters. @@ -303,13 +303,13 @@ fn check_generic_arg_count( let mut err = tcx.sess.struct_span_err(span, msg); err.span_note(span_late, note); err.emit(); - return true; + return (true, None); } else { let mut multispan = MultiSpan::from_span(span); multispan.push_span_label(span_late, note.to_string()); tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].id(), multispan, msg); - return false; + return (false, None); } } } @@ -323,7 +323,7 @@ fn check_generic_arg_count( // For kinds without defaults (i.e. lifetimes), `required == permitted`. // For other kinds (i.e. types), `permitted` may be greater than `required`. if required <= provided && provided <= permitted { - return false; + return (false, None); } // Unfortunately lifetime and type parameter mismatches are typically styled @@ -338,19 +338,16 @@ fn check_generic_arg_count( (required, "") }; + let mut potential_assoc_types: Option> = None; let (spans, label) = if required == permitted && provided > permitted { // In the case when the user has provided too many arguments, // we want to point to the unexpected arguments. - ( - args.args[offset+permitted .. offset+provided] + let spans: Vec = args.args[offset+permitted .. offset+provided] .iter() .map(|arg| arg.span()) - .collect(), - format!( - "unexpected {} argument", - kind, - ), - ) + .collect(); + potential_assoc_types = Some(spans.clone()); + (spans, format!( "unexpected {} argument", kind)) } else { (vec![span], format!( "expected {}{} {} argument{}", @@ -377,7 +374,8 @@ fn check_generic_arg_count( } err.emit(); - provided > required // `suppress_error` + (provided > required, // `suppress_error` + potential_assoc_types) }; if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes { @@ -399,7 +397,7 @@ fn check_generic_arg_count( arg_counts.lifetimes, ) } else { - false + (false, None) } } @@ -557,7 +555,7 @@ fn create_substs_for_ast_path(&self, generic_args: &hir::GenericArgs, infer_types: bool, self_ty: Option>) - -> (&'tcx Substs<'tcx>, Vec>) + -> (&'tcx Substs<'tcx>, Vec>, Option>) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -573,7 +571,7 @@ fn create_substs_for_ast_path(&self, assert_eq!(generic_params.has_self, self_ty.is_some()); let has_self = generic_params.has_self; - Self::check_generic_arg_count( + let (_, potential_assoc_types) = Self::check_generic_arg_count( self.tcx(), span, &generic_params, @@ -678,7 +676,7 @@ fn create_substs_for_ast_path(&self, debug!("create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}", generic_params, self_ty, substs); - (substs, assoc_bindings) + (substs, assoc_bindings, potential_assoc_types) } /// Instantiates the path for the given trait reference, assuming that it's @@ -720,7 +718,7 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self, self_ty: Ty<'tcx>, poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, speculative: bool) - -> ty::PolyTraitRef<'tcx> + -> (ty::PolyTraitRef<'tcx>, Option>) { let trait_def_id = self.trait_def_id(trait_ref); @@ -728,11 +726,12 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self, self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); - let (substs, assoc_bindings) = - self.create_substs_for_ast_trait_ref(trait_ref.path.span, - trait_def_id, - self_ty, - trait_ref.path.segments.last().unwrap()); + let (substs, assoc_bindings, potential_assoc_types) = self.create_substs_for_ast_trait_ref( + trait_ref.path.span, + trait_def_id, + self_ty, + trait_ref.path.segments.last().unwrap(), + ); let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); let mut dup_bindings = FxHashMap::default(); @@ -747,14 +746,14 @@ pub(super) fn instantiate_poly_trait_ref_inner(&self, debug!("instantiate_poly_trait_ref({:?}, projections={:?}) -> {:?}", trait_ref, poly_projections, poly_trait_ref); - poly_trait_ref + (poly_trait_ref, potential_assoc_types) } pub fn instantiate_poly_trait_ref(&self, poly_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) - -> ty::PolyTraitRef<'tcx> + -> (ty::PolyTraitRef<'tcx>, Option>) { self.instantiate_poly_trait_ref_inner(&poly_trait_ref.trait_ref, self_ty, poly_projections, false) @@ -767,7 +766,7 @@ fn ast_path_to_mono_trait_ref(&self, trait_segment: &hir::PathSegment) -> ty::TraitRef<'tcx> { - let (substs, assoc_bindings) = + let (substs, assoc_bindings, _) = self.create_substs_for_ast_trait_ref(span, trait_def_id, self_ty, @@ -776,13 +775,13 @@ fn ast_path_to_mono_trait_ref(&self, ty::TraitRef::new(trait_def_id, substs) } - fn create_substs_for_ast_trait_ref(&self, - span: Span, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - trait_segment: &hir::PathSegment) - -> (&'tcx Substs<'tcx>, Vec>) - { + fn create_substs_for_ast_trait_ref( + &self, + span: Span, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + trait_segment: &hir::PathSegment, + ) -> (&'tcx Substs<'tcx>, Vec>, Option>) { debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment); @@ -972,9 +971,11 @@ fn conv_object_ty_poly_trait_ref(&self, let mut projection_bounds = Vec::new(); let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF); - let principal = self.instantiate_poly_trait_ref(&trait_bounds[0], - dummy_self, - &mut projection_bounds); + let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref( + &trait_bounds[0], + dummy_self, + &mut projection_bounds, + ); debug!("principal: {:?}", principal); for trait_bound in trait_bounds[1..].iter() { @@ -1047,16 +1048,47 @@ fn conv_object_ty_poly_trait_ref(&self, if associated_types.len() == 1 { "" } else { "s" }, names, ); - for item_def_id in associated_types { - let assoc_item = tcx.associated_item(item_def_id); + let mut suggest = false; + let mut potential_assoc_types_spans = vec![]; + if let Some(potential_assoc_types) = potential_assoc_types { + if potential_assoc_types.len() == associated_types.len() { + // Only suggest when the amount of missing associated types is equals to the + // extra type arguments present, as that gives us a relatively high confidence + // that the user forgot to give the associtated type's name. The canonical + // example would be trying to use `Iterator` instead of + // `Iterator`. + suggest = true; + potential_assoc_types_spans = potential_assoc_types; + } + } + let mut suggestions = vec![]; + for (i, item_def_id) in associated_types.iter().enumerate() { + let assoc_item = tcx.associated_item(*item_def_id); err.span_label( span, format!("missing associated type `{}` value", assoc_item.ident), ); err.span_label( - tcx.def_span(item_def_id), + tcx.def_span(*item_def_id), format!("`{}` defined here", assoc_item.ident), ); + if suggest { + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet( + potential_assoc_types_spans[i], + ) { + suggestions.push(( + potential_assoc_types_spans[i], + format!("{} = {}", assoc_item.ident, snippet), + )); + } + } + } + if !suggestions.is_empty() { + err.multipart_suggestion_with_applicability( + "if you meant to assign the missing associated type, use the name", + suggestions, + Applicability::MaybeIncorrect, + ); } err.emit(); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f3c570e84009..a1bb0b53f1fc 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1892,7 +1892,7 @@ fn extend, Span)>>(&mut self, iter: &hir::GenericBound::Trait(ref poly_trait_ref, _) => { let mut projections = Vec::new(); - let trait_ref = AstConv::instantiate_poly_trait_ref( + let (trait_ref, _) = AstConv::instantiate_poly_trait_ref( &icx, poly_trait_ref, ty, @@ -2016,7 +2016,12 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>( let mut projection_bounds = Vec::new(); let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { - (astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span) + let (poly_trait_ref, _) = astconv.instantiate_poly_trait_ref( + bound, + param_ty, + &mut projection_bounds, + ); + (poly_trait_ref, bound.span) }).collect(); let region_bounds = region_bounds @@ -2057,7 +2062,7 @@ fn predicates_from_bound<'tcx>( match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { let mut projections = Vec::new(); - let pred = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); + let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); iter::once((pred.to_predicate(), tr.span)).chain( projections .into_iter() diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 1f5998d8ca39..0fba311d7f7d 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -389,7 +389,7 @@ pub fn hir_trait_to_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_trait: let env_def_id = tcx.hir.local_def_id(env_node_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id); let mut projections = Vec::new(); - let principal = astconv::AstConv::instantiate_poly_trait_ref_inner( + let (principal, _) = astconv::AstConv::instantiate_poly_trait_ref_inner( &item_cx, hir_trait, tcx.types.err, &mut projections, true ); diff --git a/src/test/ui/error-codes/E0107-b.rs b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs similarity index 100% rename from src/test/ui/error-codes/E0107-b.rs rename to src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr similarity index 75% rename from src/test/ui/error-codes/E0107-b.stderr rename to src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr index 1e8c683aff6a..053f70104211 100644 --- a/src/test/ui/error-codes/E0107-b.stderr +++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr @@ -1,5 +1,5 @@ error[E0107]: wrong number of type arguments: expected 2, found 4 - --> $DIR/E0107-b.rs:6:42 + --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:42 | LL | pub struct Foo { i: Box> } | ^^^^^ ^^^^^ unexpected type argument @@ -7,7 +7,7 @@ LL | pub struct Foo { i: Box> } | unexpected type argument error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified - --> $DIR/E0107-b.rs:6:26 + --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:26 | LL | type A; | ------- `A` defined here @@ -20,6 +20,10 @@ LL | pub struct Foo { i: Box> } | | | missing associated type `A` value | missing associated type `C` value +help: if you meant to assign the missing associated type, use the name + | +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^ ^^^^^^^^^ error: aborting due to 2 previous errors From a5d35631febf78027e5dd7f741bb9f07897d4eda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 21:43:08 -0800 Subject: [PATCH 73/75] Reword and fix test --- src/librustc_typeck/astconv.rs | 9 +++++++-- src/test/compile-fail/issue-23595-1.rs | 4 +--- ...ated-type-projection-from-multiple-supertraits.stderr | 2 +- .../associated-types-incomplete-object.stderr | 8 ++++---- src/test/ui/error-codes/E0191.stderr | 2 +- src/test/ui/error-codes/E0220.stderr | 2 +- src/test/ui/issues/issue-19482.stderr | 2 +- src/test/ui/issues/issue-21950.stderr | 2 +- src/test/ui/issues/issue-22434.stderr | 2 +- src/test/ui/issues/issue-22560.stderr | 2 +- src/test/ui/issues/issue-23024.stderr | 2 +- src/test/ui/issues/issue-28344.stderr | 4 ++-- .../use-type-argument-instead-of-assoc-type.stderr | 6 +++--- src/test/ui/traits/trait-alias-object.stderr | 2 +- 14 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f1192cf98ae1..b583c0554e82 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1066,7 +1066,7 @@ fn conv_object_ty_poly_trait_ref(&self, let assoc_item = tcx.associated_item(*item_def_id); err.span_label( span, - format!("missing associated type `{}` value", assoc_item.ident), + format!("associated type `{}` must be specified", assoc_item.ident), ); err.span_label( tcx.def_span(*item_def_id), @@ -1084,8 +1084,13 @@ fn conv_object_ty_poly_trait_ref(&self, } } if !suggestions.is_empty() { + let msg = if suggestions.len() == 1 { + "if you meant to specify the associated type, write" + } else { + "if you meant to specify the associated types, write" + }; err.multipart_suggestion_with_applicability( - "if you meant to assign the missing associated type, use the name", + msg, suggestions, Applicability::MaybeIncorrect, ); diff --git a/src/test/compile-fail/issue-23595-1.rs b/src/test/compile-fail/issue-23595-1.rs index a3422d859c61..1e615c4c0db8 100644 --- a/src/test/compile-fail/issue-23595-1.rs +++ b/src/test/compile-fail/issue-23595-1.rs @@ -16,9 +16,7 @@ trait Hierarchy { type Value; type ChildKey; type Children = Index; - //~^ ERROR: the value of the associated type `ChildKey` - //~^^ ERROR: the value of the associated type `Children` - //~^^^ ERROR: the value of the associated type `Value` + //~^ ERROR: the value of the associated types `Value` (from the trait `Hierarchy`), `ChildKey` fn data(&self) -> Option<(Self::Value, Self::Children)>; } diff --git a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr index 726078f44a7e..b4285c0de29d 100644 --- a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr +++ b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr @@ -29,7 +29,7 @@ LL | type Color; | ----------- `Color` defined here ... LL | fn dent_object(c: BoxCar) { - | ^^^^^^^^^^^^^^^^^^^ missing associated type `Color` value + | ^^^^^^^^^^^^^^^^^^^ associated type `Color` must be specified error[E0221]: ambiguous associated type `Color` in bounds of `C` --> $DIR/associated-type-projection-from-multiple-supertraits.rs:38:29 diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr index 933f059ebf48..eb8e6f998a53 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.stderr +++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr @@ -5,7 +5,7 @@ LL | type B; | ------- `B` defined here ... LL | let b = &42isize as &Foo; - | ^^^^^^^^^^^^ missing associated type `B` value + | ^^^^^^^^^^^^ associated type `B` must be specified error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:36:26 @@ -14,7 +14,7 @@ LL | type A; | ------- `A` defined here ... LL | let c = &42isize as &Foo; - | ^^^^^^^^^^^ missing associated type `A` value + | ^^^^^^^^^^^ associated type `A` must be specified error[E0191]: the value of the associated types `A` (from the trait `Foo`), `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:39:26 @@ -27,8 +27,8 @@ LL | type B; LL | let d = &42isize as &Foo; | ^^^ | | - | missing associated type `A` value - | missing associated type `B` value + | associated type `A` must be specified + | associated type `B` must be specified error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0191.stderr b/src/test/ui/error-codes/E0191.stderr index a1f7c935c4a4..f07529e7e9e1 100644 --- a/src/test/ui/error-codes/E0191.stderr +++ b/src/test/ui/error-codes/E0191.stderr @@ -5,7 +5,7 @@ LL | type Bar; | --------- `Bar` defined here ... LL | type Foo = Trait; //~ ERROR E0191 - | ^^^^^ missing associated type `Bar` value + | ^^^^^ associated type `Bar` must be specified error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0220.stderr b/src/test/ui/error-codes/E0220.stderr index 7ddd912d4f2b..d26e61fba8c6 100644 --- a/src/test/ui/error-codes/E0220.stderr +++ b/src/test/ui/error-codes/E0220.stderr @@ -11,7 +11,7 @@ LL | type Bar; | --------- `Bar` defined here ... LL | type Foo = Trait; //~ ERROR E0220 - | ^^^^^^^^^^^^ missing associated type `Bar` value + | ^^^^^^^^^^^^ associated type `Bar` must be specified error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-19482.stderr b/src/test/ui/issues/issue-19482.stderr index 7e71b0bd2323..d125438b8517 100644 --- a/src/test/ui/issues/issue-19482.stderr +++ b/src/test/ui/issues/issue-19482.stderr @@ -5,7 +5,7 @@ LL | type A; | ------- `A` defined here ... LL | fn bar(x: &Foo) {} - | ^^^ missing associated type `A` value + | ^^^ associated type `A` must be specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index 3359225ab6db..2cc064dad1b8 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -10,7 +10,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-21950.rs:17:14 | LL | &Add; - | ^^^ missing associated type `Output` value + | ^^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL | diff --git a/src/test/ui/issues/issue-22434.stderr b/src/test/ui/issues/issue-22434.stderr index d951d57444d0..3ba77346a1f8 100644 --- a/src/test/ui/issues/issue-22434.stderr +++ b/src/test/ui/issues/issue-22434.stderr @@ -5,7 +5,7 @@ LL | type A; | ------- `A` defined here ... LL | type I<'a> = &'a (Foo + 'a); - | ^^^^^^^^ missing associated type `A` value + | ^^^^^^^^ associated type `A` must be specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr index 8f736aa03453..bfce870196a8 100644 --- a/src/test/ui/issues/issue-22560.stderr +++ b/src/test/ui/issues/issue-22560.stderr @@ -28,7 +28,7 @@ LL | type Test = Add + LL | | //~^ ERROR E0393 LL | | //~| ERROR E0191 LL | | Sub; - | |_______________^ missing associated type `Output` value + | |_______________^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL | diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 8a493468dbf9..198469ca723d 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -16,7 +16,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-23024.rs:19:35 | LL | println!("{:?}",(vfnfer[0] as Fn)(3)); - | ^^ missing associated type `Output` value + | ^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/function.rs:LL:COL | diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 67588ba46f2e..824ba4b49cb4 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -2,7 +2,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-28344.rs:14:17 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - | ^^^^^^^^^^^^^ missing associated type `Output` value + | ^^^^^^^^^^^^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL | @@ -21,7 +21,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-28344.rs:18:13 | LL | let g = BitXor::bitor; - | ^^^^^^^^^^^^^ missing associated type `Output` value + | ^^^^^^^^^^^^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL | diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr index 053f70104211..b62b5d3b04ca 100644 --- a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr +++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr @@ -18,9 +18,9 @@ LL | } LL | pub struct Foo { i: Box> } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | missing associated type `A` value - | missing associated type `C` value -help: if you meant to assign the missing associated type, use the name + | associated type `A` must be specified + | associated type `C` must be specified +help: if you meant to specify the associated types, write | LL | pub struct Foo { i: Box> } | ^^^^^^^^^ ^^^^^^^^^ diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr index 0ae9b0b88641..c316c4a6beb7 100644 --- a/src/test/ui/traits/trait-alias-object.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -10,7 +10,7 @@ error[E0191]: the value of the associated type `Item` (from the trait `std::iter --> $DIR/trait-alias-object.rs:18:13 | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); - | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value + | ^^^^^^^^^^^^^^^^^ associated type `Item` must be specified | ::: $SRC_DIR/libcore/iter/iterator.rs:LL:COL | From 510f836d2378bc9d7ec48e3c39ca83006aadb197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 22 Nov 2018 14:30:33 -0800 Subject: [PATCH 74/75] Do not point at associated types from other crates This is a somewhat arbitrary restriction in order to be consistent in the output of the tests regardless of target platform. --- src/librustc_typeck/astconv.rs | 10 ++++++---- src/test/ui/issues/issue-21950.stderr | 5 ----- src/test/ui/issues/issue-22560.stderr | 5 ----- src/test/ui/issues/issue-23024.stderr | 5 ----- src/test/ui/issues/issue-28344.stderr | 10 ---------- src/test/ui/traits/trait-alias-object.stderr | 5 ----- 6 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b583c0554e82..a8164c85e821 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1068,10 +1068,12 @@ fn conv_object_ty_poly_trait_ref(&self, span, format!("associated type `{}` must be specified", assoc_item.ident), ); - err.span_label( - tcx.def_span(*item_def_id), - format!("`{}` defined here", assoc_item.ident), - ); + if item_def_id.is_local() { + err.span_label( + tcx.def_span(*item_def_id), + format!("`{}` defined here", assoc_item.ident), + ); + } if suggest { if let Ok(snippet) = tcx.sess.source_map().span_to_snippet( potential_assoc_types_spans[i], diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index 2cc064dad1b8..33c89dd4994b 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -11,11 +11,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | &Add; | ^^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr index bfce870196a8..715f84011f64 100644 --- a/src/test/ui/issues/issue-22560.stderr +++ b/src/test/ui/issues/issue-22560.stderr @@ -29,11 +29,6 @@ LL | | //~^ ERROR E0393 LL | | //~| ERROR E0191 LL | | Sub; | |_______________^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 198469ca723d..adee12a36d31 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -17,11 +17,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | println!("{:?}",(vfnfer[0] as Fn)(3)); | ^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/function.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 824ba4b49cb4..734c761d0b7b 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -3,11 +3,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | ^^^^^^^^^^^^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:14:17 @@ -22,11 +17,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let g = BitXor::bitor; | ^^^^^^^^^^^^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:18:13 diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr index c316c4a6beb7..fdb9427cba73 100644 --- a/src/test/ui/traits/trait-alias-object.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -11,11 +11,6 @@ error[E0191]: the value of the associated type `Item` (from the trait `std::iter | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); | ^^^^^^^^^^^^^^^^^ associated type `Item` must be specified - | - ::: $SRC_DIR/libcore/iter/iterator.rs:LL:COL - | -LL | type Item; - | ---------- `Item` defined here error: aborting due to 2 previous errors From 2598a7a56daedbb5a04a234d36fcfbfec447dc26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 23 Nov 2018 12:52:47 +0100 Subject: [PATCH 75/75] submodules: update clippy from 2f6881c6 to 754b4c07 Changes: ```` rustup https://github.com/rust-lang/rust/pull/54071/ dependencies: update pulldown-cmark from 0.1 to 0.2 s/file_map/source_map ```` --- Cargo.lock | 12 +++++++++++- src/tools/clippy | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0dd693e7217e..6a2b1bc41eff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -341,7 +341,7 @@ dependencies = [ "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pulldown-cmark 0.2.0 (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.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1641,6 +1641,15 @@ dependencies = [ "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pulldown-cmark" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quick-error" version = "1.2.2" @@ -3373,6 +3382,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09" "checksum proptest 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "926d0604475349f463fe44130aae73f2294b5309ab2ca0310b998bd334ef191f" "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" +"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "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" diff --git a/src/tools/clippy b/src/tools/clippy index 2f6881c62325..754b4c07233e 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 2f6881c62325c34115502b8901bf3ef0931b23cd +Subproject commit 754b4c07233ee18820265bd18467aa82263f9a3a