From 778d5f2074b05c013e15fabc25daf4e37a174bf7 Mon Sep 17 00:00:00 2001 From: Clar Charr <clar@charr.xyz> Date: Sat, 9 Sep 2017 16:48:40 -0400 Subject: [PATCH 01/24] Add Cow<str> -> Box<Error> impls. --- src/libstd/error.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 401552a6ec417..6d64ea0d50332 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -53,6 +53,7 @@ use alloc::allocator; use any::TypeId; +use borrow::Cow; use cell; use char; use fmt::{self, Debug, Display}; @@ -217,6 +218,20 @@ impl<'a> From<&'a str> for Box<Error> { } } +#[stable(feature = "cow_box_error", since = "1.22.0")] +impl<'a, 'b> From<Cow<'b, str>> for Box<Error + Send + Sync + 'a> { + fn from(err: Cow<'b, str>) -> Box<Error + Send + Sync + 'a> { + From::from(String::from(err)) + } +} + +#[stable(feature = "cow_box_error", since = "1.22.0")] +impl<'a> From<Cow<'a, str>> for Box<Error> { + fn from(err: Cow<'a, str>) -> Box<Error> { + From::from(String::from(err)) + } +} + #[unstable(feature = "never_type_impls", issue = "35121")] impl Error for ! { fn description(&self) -> &str { *self } From edf1622bb4f3bd2ba8c8cd13c12a22e7d776120f Mon Sep 17 00:00:00 2001 From: oyvindln <oyvindln@users.noreply.github.com> Date: Wed, 13 Sep 2017 20:11:02 +0200 Subject: [PATCH 02/24] Add proper help line for inline threshold Also remove a period on a different help line for consistency --- src/librustc/session/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 59f600f39077c..a4b13bb2f4dbc 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -905,7 +905,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options, debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED], "explicitly enable the cfg(debug_assertions) directive"), inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED], - "set the inlining threshold for"), + "set the threshold for inlining a function (default: 225)"), panic: Option<PanicStrategy> = (None, parse_panic_strategy, [TRACKED], "panic strategy to compile crate with"), } @@ -1052,7 +1052,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED], "Linker flavor"), fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], - "Set the optimization fuel quota for a crate."), + "Set the optimization fuel quota for a crate"), print_fuel: Option<String> = (None, parse_opt_string, [TRACKED], "Make Rustc print the total optimization fuel used by a crate."), remap_path_prefix_from: Vec<String> = (vec![], parse_string_push, [TRACKED], From e89748e54f059e72b4ab4b6948a992f273c64cc6 Mon Sep 17 00:00:00 2001 From: oyvindln <oyvindln@users.noreply.github.com> Date: Wed, 13 Sep 2017 22:50:47 +0200 Subject: [PATCH 03/24] Remove the other period and start with lowercase for more consistency --- src/librustc/session/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index a4b13bb2f4dbc..4cc2a087d81b5 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1052,9 +1052,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED], "Linker flavor"), fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], - "Set the optimization fuel quota for a crate"), + "set the optimization fuel quota for a crate"), print_fuel: Option<String> = (None, parse_opt_string, [TRACKED], - "Make Rustc print the total optimization fuel used by a crate."), + "make Rustc print the total optimization fuel used by a crate"), remap_path_prefix_from: Vec<String> = (vec![], parse_string_push, [TRACKED], "add a source pattern to the file path remapping config"), remap_path_prefix_to: Vec<String> = (vec![], parse_string_push, [TRACKED], From 7859c9ef442055c477e7788a74f971ac68e8bd67 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup <bluss@users.noreply.github.com> Date: Sun, 17 Sep 2017 10:19:11 +0200 Subject: [PATCH 04/24] std: Document thread builder panics for nul bytes in thread names This seems to have been undocumented. Mention this where the name is set (Builder::name) and where the panic could happen (Builder::spawn). Thread::new is private and I think the builder is the only user where this matters. A short comment was added to "document" Thread::new too. --- src/libstd/thread/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 4912ff93abdb3..a084c7fbce157 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -287,6 +287,8 @@ impl Builder { /// Names the thread-to-be. Currently the name is used for identification /// only in panic messages. /// + /// The name must not contain null bytes (`\0`). + /// /// For more information about named threads, see /// [this module-level documentation][naming-threads]. /// @@ -355,6 +357,10 @@ impl Builder { /// [`io::Result`]: ../../std/io/type.Result.html /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html /// + /// # Panics + /// + /// Panics if a thread name was set and it contained null bytes. + /// /// # Examples /// /// ``` @@ -941,6 +947,7 @@ pub struct Thread { impl Thread { // Used only internally to construct a thread object without spawning + // Panics if the name contains nuls. pub(crate) fn new(name: Option<String>) -> Thread { let cname = name.map(|n| { CString::new(n).expect("thread name may not contain interior null bytes") From 7b932d2e127b3b694e8cd2a6ae30d78cc3436547 Mon Sep 17 00:00:00 2001 From: Michal Budzynski <budziq@gmail.com> Date: Sun, 17 Sep 2017 01:42:15 +0200 Subject: [PATCH 05/24] stabilized vec_splice (fixes #32310) --- .../unstable-book/src/library-features/splice.md | 6 +++--- src/liballoc/vec.rs | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/splice.md b/src/doc/unstable-book/src/library-features/splice.md index dae4475257a02..f2d32c8803876 100644 --- a/src/doc/unstable-book/src/library-features/splice.md +++ b/src/doc/unstable-book/src/library-features/splice.md @@ -6,8 +6,8 @@ The tracking issue for this feature is: [#32310] ------------------------ -The `splice()` method on `Vec` and `String` allows you to replace a range -of values in a vector or string with another range of values, and returns +The `splice()` method on `String` allows you to replace a range +of values in a string with another range of values, and returns the replaced values. A simple example: @@ -20,4 +20,4 @@ let beta_offset = s.find('β').unwrap_or(s.len()); // Replace the range up until the β from the string s.splice(..beta_offset, "Α is capital alpha; "); assert_eq!(s, "Α is capital alpha; β is beta"); -``` \ No newline at end of file +``` diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 45574bad9ac07..75d54b8207606 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1943,7 +1943,6 @@ impl<T> Vec<T> { /// # Examples /// /// ``` - /// #![feature(splice)] /// let mut v = vec![1, 2, 3]; /// let new = [7, 8]; /// let u: Vec<_> = v.splice(..2, new.iter().cloned()).collect(); @@ -1951,7 +1950,7 @@ impl<T> Vec<T> { /// assert_eq!(u, &[1, 2]); /// ``` #[inline] - #[unstable(feature = "splice", reason = "recently added", issue = "32310")] + #[stable(feature = "vec_splice", since = "1.22.0")] pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<I::IntoIter> where R: RangeArgument<usize>, I: IntoIterator<Item=T> { @@ -2554,13 +2553,13 @@ impl<'a, T> InPlace<T> for PlaceBack<'a, T> { /// [`splice()`]: struct.Vec.html#method.splice /// [`Vec`]: struct.Vec.html #[derive(Debug)] -#[unstable(feature = "splice", reason = "recently added", issue = "32310")] +#[stable(feature = "vec_splice", since = "1.22.0")] pub struct Splice<'a, I: Iterator + 'a> { drain: Drain<'a, I::Item>, replace_with: I, } -#[unstable(feature = "splice", reason = "recently added", issue = "32310")] +#[stable(feature = "vec_splice", since = "1.22.0")] impl<'a, I: Iterator> Iterator for Splice<'a, I> { type Item = I::Item; @@ -2573,18 +2572,18 @@ impl<'a, I: Iterator> Iterator for Splice<'a, I> { } } -#[unstable(feature = "splice", reason = "recently added", issue = "32310")] +#[stable(feature = "vec_splice", since = "1.22.0")] impl<'a, I: Iterator> DoubleEndedIterator for Splice<'a, I> { fn next_back(&mut self) -> Option<Self::Item> { self.drain.next_back() } } -#[unstable(feature = "splice", reason = "recently added", issue = "32310")] +#[stable(feature = "vec_splice", since = "1.22.0")] impl<'a, I: Iterator> ExactSizeIterator for Splice<'a, I> {} -#[unstable(feature = "splice", reason = "recently added", issue = "32310")] +#[stable(feature = "vec_splice", since = "1.22.0")] impl<'a, I: Iterator> Drop for Splice<'a, I> { fn drop(&mut self) { // exhaust drain first From 6b167f98d9dcfef79519d79d03930062215158fc Mon Sep 17 00:00:00 2001 From: Michal Budzynski <budziq@gmail.com> Date: Sun, 17 Sep 2017 10:41:24 +0200 Subject: [PATCH 06/24] Updated tracking issue for String::splice and its unstable-book entry --- src/doc/unstable-book/src/library-features/splice.md | 7 +++---- src/liballoc/string.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/doc/unstable-book/src/library-features/splice.md b/src/doc/unstable-book/src/library-features/splice.md index f2d32c8803876..2e4bb1a5257c9 100644 --- a/src/doc/unstable-book/src/library-features/splice.md +++ b/src/doc/unstable-book/src/library-features/splice.md @@ -1,14 +1,13 @@ # `splice` -The tracking issue for this feature is: [#32310] +The tracking issue for this feature is: [#44643] -[#32310]: https://github.com/rust-lang/rust/issues/32310 +[#44643]: https://github.com/rust-lang/rust/issues/44643 ------------------------ The `splice()` method on `String` allows you to replace a range -of values in a string with another range of values, and returns -the replaced values. +of values in a string with another range of values. A simple example: diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 46b96df1eabd7..6d0bb264df186 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -1451,7 +1451,7 @@ impl String { /// s.splice(..beta_offset, "Α is capital alpha; "); /// assert_eq!(s, "Α is capital alpha; β is beta"); /// ``` - #[unstable(feature = "splice", reason = "recently added", issue = "32310")] + #[unstable(feature = "splice", reason = "recently added", issue = "44643")] pub fn splice<R>(&mut self, range: R, replace_with: &str) where R: RangeArgument<usize> { From 2633b85ab2c89822d2c227fc9e81c6ec1c0ed9b6 Mon Sep 17 00:00:00 2001 From: Ixrec <ericrhitchcock@gmail.com> Date: Sun, 17 Sep 2017 17:03:56 +0100 Subject: [PATCH 07/24] Replace str's transmute() calls with pointer casts After the following conversation in #rust-lang: ``` [14:43:50] <Ixrec> TIL the implementation of from_utf_unchecked is literally just "mem::transmute(x)" [14:43:59] <Ixrec> no wonder people keep saying transmute is overpowered [15:15:30] <eddyb> Ixrec: it should be a pointer cast lol [15:15:46] <eddyb> unless it doesn't let you [16:50:34] <Ixrec> https://play.rust-lang.org/?gist=d1e6b629ad9ec1baf64ce261c63845e6&version=stable seems like it does let me [16:52:35] <eddyb> Ixrec: yeah that's the preferred impl [16:52:46] <eddyb> Ixrec: it just wasn't in 1.0 [16:52:50] <eddyb> IIRC [16:53:00] <eddyb> (something something fat pointers) ``` Since I already wrote half of the preferred impls in the playground, might as well make an actual PR. --- src/libcore/str/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index d4fef45ae4e8f..60f3640446cab 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -404,7 +404,7 @@ unsafe fn from_raw_parts_mut<'a>(p: *mut u8, len: usize) -> &'a mut str { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { - mem::transmute(v) + &*(v as *const [u8] as *const str) } /// Converts a slice of bytes to a string slice without checking @@ -429,7 +429,7 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { #[inline] #[stable(feature = "str_mut_extras", since = "1.20.0")] pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { - mem::transmute(v) + &*(v as *mut [u8] as *mut str) } #[stable(feature = "rust1", since = "1.0.0")] @@ -2447,12 +2447,12 @@ impl StrExt for str { #[inline] fn as_bytes(&self) -> &[u8] { - unsafe { mem::transmute(self) } + unsafe { &*(self as *const str as *const [u8]) } } #[inline] unsafe fn as_bytes_mut(&mut self) -> &mut [u8] { - mem::transmute(self) + &mut *(self as *mut str as *mut [u8]) } fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> { From 38fa340ba263612a6f7351d4800d6d4f57ac1cdf Mon Sep 17 00:00:00 2001 From: Ixrec <ericrhitchcock@gmail.com> Date: Sun, 17 Sep 2017 17:11:42 +0100 Subject: [PATCH 08/24] missed a 'mut' --- src/libcore/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 60f3640446cab..862085c7228af 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -429,7 +429,7 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str { #[inline] #[stable(feature = "str_mut_extras", since = "1.20.0")] pub unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str { - &*(v as *mut [u8] as *mut str) + &mut *(v as *mut [u8] as *mut str) } #[stable(feature = "rust1", since = "1.0.0")] From 2787a285bd211ecbf75fd95d990226242005d848 Mon Sep 17 00:00:00 2001 From: Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> Date: Wed, 13 Sep 2017 12:20:39 +0200 Subject: [PATCH 09/24] Add `<*const T>::align_offset` and use it in `memchr` --- src/libcore/intrinsics.rs | 33 +-------------- src/libcore/ptr.rs | 75 ++++++++++++++++++++++++++++++++- src/libcore/str/mod.rs | 3 +- src/libstd/lib.rs | 1 + src/libstd/sys_common/memchr.rs | 9 ++-- 5 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index f7f1dd12d28b1..bc82f0230e5b4 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1381,38 +1381,7 @@ extern "rust-intrinsic" { } #[cfg(stage0)] -/// Computes the byte offset that needs to be applied to `ptr` in order to -/// make it aligned to `align`. -/// If it is not possible to align `ptr`, the implementation returns -/// `usize::max_value()`. -/// -/// There are no guarantees whatsover that offsetting the pointer will not -/// overflow or go beyond the allocation that `ptr` points into. -/// It is up to the caller to ensure that the returned offset is correct -/// in all terms other than alignment. -/// -/// # Examples -/// -/// Accessing adjacent `u8` as `u16` -/// -/// ``` -/// # #![feature(core_intrinsics)] -/// # fn foo(n: usize) { -/// # use std::intrinsics::align_offset; -/// # use std::mem::align_of; -/// # unsafe { -/// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; -/// let ptr = &x[n] as *const u8; -/// let offset = align_offset(ptr as *const (), align_of::<u16>()); -/// if offset < x.len() - n - 1 { -/// let u16_ptr = ptr.offset(offset as isize) as *const u16; -/// assert_ne!(*u16_ptr, 500); -/// } else { -/// // while the pointer can be aligned via `offset`, it would point -/// // outside the allocation -/// } -/// # } } -/// ``` +/// remove me after the next release pub unsafe fn align_offset(ptr: *const (), align: usize) -> usize { let offset = ptr as usize % align; if offset == 0 { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index dd01534ec02d9..4041a3760e5ca 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1064,7 +1064,43 @@ impl<T: ?Sized> *const T { copy_nonoverlapping(self, dest, count) } - + /// Computes the byte offset that needs to be applied in order to + /// make the pointer aligned to `align`. + /// If it is not possible to align the pointer, the implementation returns + /// `usize::max_value()`. + /// + /// There are no guarantees whatsover that offsetting the pointer will not + /// overflow or go beyond the allocation that the pointer points into. + /// It is up to the caller to ensure that the returned offset is correct + /// in all terms other than alignment. + /// + /// # Examples + /// + /// Accessing adjacent `u8` as `u16` + /// + /// ``` + /// # #![feature(align_offset)] + /// # fn foo(n: usize) { + /// # use std::mem::align_of; + /// # unsafe { + /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; + /// let ptr = &x[n] as *const u8; + /// let offset = ptr.align_offset(align_of::<u16>()); + /// if offset < x.len() - n - 1 { + /// let u16_ptr = ptr.offset(offset as isize) as *const u16; + /// assert_ne!(*u16_ptr, 500); + /// } else { + /// // while the pointer can be aligned via `offset`, it would point + /// // outside the allocation + /// } + /// # } } + /// ``` + #[unstable(feature = "align_offset", issue = "44488")] + pub fn align_offset(self, align: usize) -> usize { + unsafe { + intrinsics::align_offset(self as *const _, align) + } + } } #[lang = "mut_ptr"] @@ -1284,6 +1320,43 @@ impl<T: ?Sized> *mut T { } } + /// Computes the byte offset that needs to be applied in order to + /// make the pointer aligned to `align`. + /// If it is not possible to align the pointer, the implementation returns + /// `usize::max_value()`. + /// + /// There are no guarantees whatsover that offsetting the pointer will not + /// overflow or go beyond the allocation that the pointer points into. + /// It is up to the caller to ensure that the returned offset is correct + /// in all terms other than alignment. + /// + /// # Examples + /// + /// Accessing adjacent `u8` as `u16` + /// + /// ``` + /// # #![feature(align_offset)] + /// # fn foo(n: usize) { + /// # use std::mem::align_of; + /// # unsafe { + /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; + /// let ptr = &x[n] as *const u8; + /// let offset = ptr.align_offset(align_of::<u16>()); + /// if offset < x.len() - n - 1 { + /// let u16_ptr = ptr.offset(offset as isize) as *const u16; + /// assert_ne!(*u16_ptr, 500); + /// } else { + /// // while the pointer can be aligned via `offset`, it would point + /// // outside the allocation + /// } + /// # } } + /// ``` + #[unstable(feature = "align_offset", issue = "44488")] + pub fn align_offset(self, align: usize) -> usize { + unsafe { + intrinsics::align_offset(self as *const _, align) + } + } /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`). /// diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index d4fef45ae4e8f..0d907d11cfba1 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -23,7 +23,6 @@ use fmt; use iter::{Map, Cloned, FusedIterator}; use slice::{self, SliceIndex}; use mem; -use intrinsics::align_offset; pub mod pattern; @@ -1515,7 +1514,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let ptr = v.as_ptr(); let align = unsafe { // the offset is safe, because `index` is guaranteed inbounds - align_offset(ptr.offset(index as isize) as *const (), usize_bytes) + ptr.offset(index as isize).align_offset(usize_bytes) }; if align == 0 { while index < blocks_end { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 1a0f8b8d2177e..a3eecd46e9051 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -242,6 +242,7 @@ #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] +#![feature(align_offset)] #![feature(asm)] #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] diff --git a/src/libstd/sys_common/memchr.rs b/src/libstd/sys_common/memchr.rs index 3824a5fb5284c..50f998eb4867d 100644 --- a/src/libstd/sys_common/memchr.rs +++ b/src/libstd/sys_common/memchr.rs @@ -65,15 +65,12 @@ pub mod fallback { let usize_bytes = mem::size_of::<usize>(); // search up to an aligned boundary - let align = (ptr as usize) & (usize_bytes- 1); - let mut offset; - if align > 0 { - offset = cmp::min(usize_bytes - align, len); + let mut offset = ptr.align_offset(usize_bytes); + if offset > 0 { + offset = cmp::min(offset, len); if let Some(index) = text[..offset].iter().position(|elt| *elt == x) { return Some(index); } - } else { - offset = 0; } // search the body of the text From e47279f51212a749d7cfe1d38a27f10a842d97a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume1.gomez@gmail.com> Date: Sun, 17 Sep 2017 22:11:37 +0200 Subject: [PATCH 10/24] Add more links and put the link character to the left --- src/librustdoc/html/render.rs | 8 +++++--- src/librustdoc/html/static/rustdoc.css | 12 ++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c09ce4c4bd31a..bf0fe5f6e9d98 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2671,8 +2671,9 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, let ns_id = derive_id(format!("{}.{}", field.name.as_ref().unwrap(), ItemType::StructField.name_space())); - write!(w, "<span id='{id}' class=\"{item_type}\"> - <span id='{ns_id}' class='invisible'> + write!(w, "<span id=\"{id}\" class=\"{item_type} small-section-header\"> + <a href=\"#{id}\" class=\"anchor field\"></a> + <span id=\"{ns_id}\" class='invisible'> <code>{name}: {ty}</code> </span></span>", item_type = ItemType::StructField, @@ -2793,7 +2794,8 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, let ns_id = derive_id(format!("{}.{}", variant.name.as_ref().unwrap(), ItemType::Variant.name_space())); - write!(w, "<span id='{id}' class='variant'>\ + write!(w, "<span id=\"{id}\" class=\"variant small-section-header\">\ + <a href=\"#{id}\" class=\"anchor field\"></a>\ <span id='{ns_id}' class='invisible'><code>{name}", id = id, ns_id = ns_id, diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index c15051376bf27..50c0424aa5fcc 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -288,6 +288,7 @@ nav.sub { .docblock { margin-left: 24px; + position: relative; } .content .out-of-band { @@ -456,8 +457,13 @@ a { } .anchor { display: none; + position: absolute; + left: -25px; } -.anchor:after { +.anchor.field { + left: -20px; +} +.anchor:before { content: '\2002\00a7\2002'; } @@ -625,7 +631,9 @@ a.test-arrow:hover{ text-decoration: none; } -.section-header:hover a:after { +.section-header:hover a:before { + position: absolute; + left: -25px; content: '\2002\00a7\2002'; } From ebd0e4f1996053c1d63709b169682ee8586ae65f Mon Sep 17 00:00:00 2001 From: Will Speak <lithiumflame@gmail.com> Date: Mon, 18 Sep 2017 07:38:32 +0100 Subject: [PATCH 11/24] Add Example of `IntoIterator` as Trait Bound to Docs Part of #44600. --- src/libcore/iter/traits.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 2af129a67bddf..7ef50396c82bf 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -196,6 +196,23 @@ pub trait FromIterator<A>: Sized { /// assert_eq!(i as i32, n); /// } /// ``` +/// +/// It is common to use `IntoIterator` as a trait bound. This allows +/// the input collection type to change, so long as it is still an +/// iterator. Additional bounds can be specified by restricting on +/// `Item`: +/// +/// ```rust +/// fn collect_as_strings<T>(collection: T) -> Vec<String> +/// where T: IntoIterator, +/// T::Item : std::fmt::Debug, +/// { +/// collection +/// .into_iter() +/// .map(|item| format!("{:?}", item)) +/// .collect() +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait IntoIterator { /// The type of the elements being iterated over. From 3cf28f3002470f61a471c69b869e4f55ae1766f7 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Tue, 15 Aug 2017 17:05:25 +0200 Subject: [PATCH 12/24] Use DefId instead of NodeId as identifier in resolve_lifetime::Region. These Region values end up in crate metadata so they should not use NodeId. --- .../error_reporting/different_lifetimes.rs | 12 ++--- src/librustc/middle/resolve_lifetime.rs | 50 ++++++++++++------- src/librustc_typeck/astconv.rs | 16 +++--- src/librustdoc/clean/mod.rs | 3 +- src/librustdoc/core.rs | 6 +-- 5 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index 536715ffadb15..ef28b5b42b0dd 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -245,10 +245,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { // region at the right depth with the same index (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound self.infcx.tcx.hir.local_def_id(id)={:?} \ - def_id={:?}", - self.infcx.tcx.hir.local_def_id(id), - def_id); - if self.infcx.tcx.hir.local_def_id(id) == def_id { + def_id={:?}", id, def_id); + if id == def_id { self.found_type = Some(arg); return; // we can stop visiting now } @@ -260,11 +258,9 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindNestedTypeVisitor<'a, 'gcx, 'tcx> { (Some(rl::Region::LateBound(debruijn_index, id)), ty::BrNamed(def_id, _)) => { debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index.depth); - debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", - self.infcx.tcx.hir.local_def_id(id)); + debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", id); debug!("def_id={:?}", def_id); - if debruijn_index.depth == self.depth && - self.infcx.tcx.hir.local_def_id(id) == def_id { + if debruijn_index.depth == self.depth && id == def_id { self.found_type = Some(arg); return; // we can stop visiting now } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 657c30289ebb5..2d201e5935ec7 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -39,22 +39,24 @@ use hir::intravisit::{self, Visitor, NestedVisitorMap}; #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub enum Region { Static, - EarlyBound(/* index */ u32, /* lifetime decl */ ast::NodeId), - LateBound(ty::DebruijnIndex, /* lifetime decl */ ast::NodeId), + EarlyBound(/* index */ u32, /* lifetime decl */ DefId), + LateBound(ty::DebruijnIndex, /* lifetime decl */ DefId), LateBoundAnon(ty::DebruijnIndex, /* anon index */ u32), - Free(DefId, /* lifetime decl */ ast::NodeId), + Free(DefId, /* lifetime decl */ DefId), } impl Region { - fn early(index: &mut u32, def: &hir::LifetimeDef) -> (ast::Name, Region) { + fn early(hir_map: &Map, index: &mut u32, def: &hir::LifetimeDef) -> (ast::Name, Region) { let i = *index; *index += 1; - (def.lifetime.name, Region::EarlyBound(i, def.lifetime.id)) + let def_id = hir_map.local_def_id(def.lifetime.id); + (def.lifetime.name, Region::EarlyBound(i, def_id)) } - fn late(def: &hir::LifetimeDef) -> (ast::Name, Region) { + fn late(hir_map: &Map, def: &hir::LifetimeDef) -> (ast::Name, Region) { let depth = ty::DebruijnIndex::new(1); - (def.lifetime.name, Region::LateBound(depth, def.lifetime.id)) + let def_id = hir_map.local_def_id(def.lifetime.id); + (def.lifetime.name, Region::LateBound(depth, def_id)) } fn late_anon(index: &Cell<u32>) -> Region { @@ -64,7 +66,7 @@ impl Region { Region::LateBoundAnon(depth, i) } - fn id(&self) -> Option<ast::NodeId> { + fn id(&self) -> Option<DefId> { match *self { Region::Static | Region::LateBoundAnon(..) => None, @@ -337,7 +339,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { 0 }; let lifetimes = generics.lifetimes.iter().map(|def| { - Region::early(&mut index, def) + Region::early(self.hir_map, &mut index, def) }).collect(); let scope = Scope::Binder { lifetimes, @@ -368,7 +370,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { match ty.node { hir::TyBareFn(ref c) => { let scope = Scope::Binder { - lifetimes: c.lifetimes.iter().map(Region::late).collect(), + lifetimes: c.lifetimes.iter().map(|def| { + Region::late(self.hir_map, def) + }).collect(), s: self.scope }; self.with(scope, |old_scope, this| { @@ -467,7 +471,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { if !bound_lifetimes.is_empty() { self.trait_ref_hack = true; let scope = Scope::Binder { - lifetimes: bound_lifetimes.iter().map(Region::late).collect(), + lifetimes: bound_lifetimes.iter().map(|def| { + Region::late(self.hir_map, def) + }).collect(), s: self.scope }; let result = self.with(scope, |old_scope, this| { @@ -512,7 +518,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { "nested quantification of lifetimes"); } let scope = Scope::Binder { - lifetimes: trait_ref.bound_lifetimes.iter().map(Region::late).collect(), + lifetimes: trait_ref.bound_lifetimes.iter().map(|def| { + Region::late(self.hir_map, def) + }).collect(), s: self.scope }; self.with(scope, |old_scope, this| { @@ -647,10 +655,13 @@ fn extract_labels(ctxt: &mut LifetimeContext, body: &hir::Body) { Scope::Binder { ref lifetimes, s } => { // FIXME (#24278): non-hygienic comparison if let Some(def) = lifetimes.get(&label) { + let node_id = hir_map.as_local_node_id(def.id().unwrap()) + .unwrap(); + signal_shadowing_problem( sess, label, - original_lifetime(hir_map.span(def.id().unwrap())), + original_lifetime(hir_map.span(node_id)), shadower_label(label_span)); return; } @@ -749,7 +760,8 @@ fn object_lifetime_defaults_for_item(hir_map: &Map, generics: &hir::Generics) generics.lifetimes.iter().enumerate().find(|&(_, def)| { def.lifetime.name == name }).map_or(Set1::Many, |(i, def)| { - Set1::One(Region::EarlyBound(i as u32, def.lifetime.id)) + let def_id = hir_map.local_def_id(def.lifetime.id); + Set1::One(Region::EarlyBound(i as u32, def_id)) }) } } @@ -835,9 +847,9 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let lifetimes = generics.lifetimes.iter().map(|def| { if self.map.late_bound.contains(&def.lifetime.id) { - Region::late(def) + Region::late(self.hir_map, def) } else { - Region::early(&mut index, def) + Region::early(self.hir_map, &mut index, def) } }).collect(); @@ -1483,10 +1495,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Binder { ref lifetimes, s } => { if let Some(&def) = lifetimes.get(&lifetime.name) { + let node_id = self.hir_map + .as_local_node_id(def.id().unwrap()) + .unwrap(); + signal_shadowing_problem( self.sess, lifetime.name, - original_lifetime(self.hir_map.span(def.id().unwrap())), + original_lifetime(self.hir_map.span(node_id)), shadower_lifetime(&lifetime)); return; } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 8f8663385b020..5256bb2278117 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -96,6 +96,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { -> ty::Region<'tcx> { let tcx = self.tcx(); + let lifetime_name = |def_id| { + tcx.hir.name(tcx.hir.as_local_node_id(def_id).unwrap()) + }; + let hir_id = tcx.hir.node_to_hir_id(lifetime.id); let r = match tcx.named_region(hir_id) { Some(rl::Region::Static) => { @@ -103,9 +107,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } Some(rl::Region::LateBound(debruijn, id)) => { - let name = tcx.hir.name(id); + let name = lifetime_name(id); tcx.mk_region(ty::ReLateBound(debruijn, - ty::BrNamed(tcx.hir.local_def_id(id), name))) + ty::BrNamed(id, name))) } Some(rl::Region::LateBoundAnon(debruijn, index)) => { @@ -113,19 +117,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { } Some(rl::Region::EarlyBound(index, id)) => { - let name = tcx.hir.name(id); + let name = lifetime_name(id); tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { - def_id: tcx.hir.local_def_id(id), + def_id: id, index, name, })) } Some(rl::Region::Free(scope, id)) => { - let name = tcx.hir.name(id); + let name = lifetime_name(id); tcx.mk_region(ty::ReFree(ty::FreeRegion { scope, - bound_region: ty::BrNamed(tcx.hir.local_def_id(id), name) + bound_region: ty::BrNamed(id, name) })) // (*) -- not late-bound, won't change diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3be0937340899..73ab286f185aa 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1835,7 +1835,8 @@ impl Clean<Type> for hir::Ty { for (i, lt_param) in generics.lifetimes.iter().enumerate() { if let Some(lt) = provided_params.lifetimes.get(i).cloned() { if !lt.is_elided() { - lt_substs.insert(lt_param.lifetime.id, lt.clean(cx)); + let lt_def_id = cx.tcx.hir.local_def_id(lt_param.lifetime.id); + lt_substs.insert(lt_def_id, lt.clean(cx)); } } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 0c0748cf673c1..277e2909ba9ed 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -24,7 +24,7 @@ use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; -use syntax::{ast, codemap}; +use syntax::codemap; use syntax::feature_gate::UnstableFeatures; use syntax::fold::Folder; use errors; @@ -65,7 +65,7 @@ pub struct DocContext<'a, 'tcx: 'a> { /// Table type parameter definition -> substituted type pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>, /// Table node id of lifetime parameter definition -> substituted lifetime - pub lt_substs: RefCell<FxHashMap<ast::NodeId, clean::Lifetime>>, + pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>, } impl<'a, 'tcx> DocContext<'a, 'tcx> { @@ -77,7 +77,7 @@ impl<'a, 'tcx> DocContext<'a, 'tcx> { /// the substitutions for a type alias' RHS. pub fn enter_alias<F, R>(&self, ty_substs: FxHashMap<Def, clean::Type>, - lt_substs: FxHashMap<ast::NodeId, clean::Lifetime>, + lt_substs: FxHashMap<DefId, clean::Lifetime>, f: F) -> R where F: FnOnce() -> R { let (old_tys, old_lts) = From e6c9a53d1a148fe4cd2cf9e0e1329289163d2284 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Mon, 14 Aug 2017 18:19:42 +0200 Subject: [PATCH 13/24] incr.comp.: Compute hashes of all query results. --- src/librustc/ich/hcx.rs | 82 +++++- src/librustc/ich/impls_cstore.rs | 7 + src/librustc/ich/impls_hir.rs | 54 +++- src/librustc/ich/impls_ty.rs | 255 +++++++++++++++--- src/librustc/ich/mod.rs | 5 +- src/librustc/lint/levels.rs | 61 +++++ src/librustc/lint/mod.rs | 17 ++ src/librustc/middle/reachable.rs | 10 +- src/librustc/middle/region.rs | 43 +++ .../traits/specialize/specialization_graph.rs | 34 +++ src/librustc/ty/fast_reject.rs | 94 ++++++- src/librustc/ty/layout.rs | 130 +++++++++ src/librustc/ty/maps.rs | 24 +- src/librustc/ty/trait_def.rs | 17 +- src/librustc_data_structures/stable_hasher.rs | 28 +- src/librustc_mir/transform/erase_regions.rs | 42 ++- src/libsyntax/ast.rs | 9 +- 17 files changed, 828 insertions(+), 84 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 5c011042deeee..767868ffda318 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -13,9 +13,10 @@ use hir::def_id::DefId; use hir::map::DefPathHash; use ich::{self, CachingCodemapView}; use session::config::DebugInfoLevel::NoDebugInfo; -use ty::TyCtxt; -use util::nodemap::{NodeMap, ItemLocalMap}; +use ty::{self, TyCtxt, fast_reject}; +use util::nodemap::{NodeMap, NodeSet, ItemLocalMap}; +use std::cmp::Ord; use std::hash as std_hash; use std::collections::{HashMap, HashSet, BTreeMap}; @@ -47,6 +48,7 @@ pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { #[derive(PartialEq, Eq, Clone, Copy)] pub enum NodeIdHashingMode { Ignore, + CheckedIgnore, HashDefPath, HashTraitsInScope, } @@ -148,7 +150,7 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { self.overflow_checks_enabled = true; } let prev_hash_node_ids = self.node_id_hashing_mode; - self.node_id_hashing_mode = NodeIdHashingMode::Ignore; + self.node_id_hashing_mode = NodeIdHashingMode::CheckedIgnore; f(self); @@ -202,6 +204,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::N let hir_id = hcx.tcx.hir.node_to_hir_id(*self); match hcx.node_id_hashing_mode { NodeIdHashingMode::Ignore => { + // Don't do anything. + } + NodeIdHashingMode::CheckedIgnore => { // Most NodeIds in the HIR can be ignored, but if there is a // corresponding entry in the `trait_map` we need to hash that. // Make sure we don't ignore too much by checking that there is @@ -321,7 +326,7 @@ pub fn hash_stable_hashmap<'a, 'gcx, 'tcx, K, V, R, SK, F, W>( let mut keys: Vec<_> = map.keys() .map(|k| (extract_stable_key(hcx, k), k)) .collect(); - keys.sort_unstable_by_key(|&(ref stable_key, _)| stable_key.clone()); + keys.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); keys.len().hash_stable(hcx, hasher); for (stable_key, key) in keys { stable_key.hash_stable(hcx, hasher); @@ -354,8 +359,25 @@ pub fn hash_stable_nodemap<'a, 'tcx, 'gcx, V, W>( where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, W: StableHasherResult, { - hash_stable_hashmap(hcx, hasher, map, |hcx, node_id| { - hcx.tcx.hir.definitions().node_to_hir_id(*node_id).local_id + let definitions = hcx.tcx.hir.definitions(); + hash_stable_hashmap(hcx, hasher, map, |_, node_id| { + let hir_id = definitions.node_to_hir_id(*node_id); + let owner_def_path_hash = definitions.def_path_hash(hir_id.owner); + (owner_def_path_hash, hir_id.local_id) + }); +} + +pub fn hash_stable_nodeset<'a, 'tcx, 'gcx, W>( + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>, + map: &NodeSet) + where W: StableHasherResult, +{ + let definitions = hcx.tcx.hir.definitions(); + hash_stable_hashset(hcx, hasher, map, |_, node_id| { + let hir_id = definitions.node_to_hir_id(*node_id); + let owner_def_path_hash = definitions.def_path_hash(hir_id.owner); + (owner_def_path_hash, hir_id.local_id) }); } @@ -386,10 +408,56 @@ pub fn hash_stable_btreemap<'a, 'tcx, 'gcx, K, V, SK, F, W>( let mut keys: Vec<_> = map.keys() .map(|k| (extract_stable_key(hcx, k), k)) .collect(); - keys.sort_unstable_by_key(|&(ref stable_key, _)| stable_key.clone()); + keys.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); keys.len().hash_stable(hcx, hasher); for (stable_key, key) in keys { stable_key.hash_stable(hcx, hasher); map[key].hash_stable(hcx, hasher); } } + +pub fn hash_stable_trait_impls<'a, 'tcx, 'gcx, W, R>( + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>, + blanket_impls: &Vec<DefId>, + non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>) + where W: StableHasherResult, + R: std_hash::BuildHasher, +{ + { + let mut blanket_impls: AccumulateVec<[_; 8]> = blanket_impls + .iter() + .map(|&def_id| hcx.def_path_hash(def_id)) + .collect(); + + if blanket_impls.len() > 1 { + blanket_impls.sort_unstable(); + } + + blanket_impls.hash_stable(hcx, hasher); + } + + { + let tcx = hcx.tcx(); + let mut keys: AccumulateVec<[_; 8]> = + non_blanket_impls.keys() + .map(|k| (k, k.map_def(|d| tcx.def_path_hash(d)))) + .collect(); + keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2)); + keys.len().hash_stable(hcx, hasher); + for (key, ref stable_key) in keys { + stable_key.hash_stable(hcx, hasher); + let mut impls : AccumulateVec<[_; 8]> = non_blanket_impls[key] + .iter() + .map(|&impl_id| hcx.def_path_hash(impl_id)) + .collect(); + + if impls.len() > 1 { + impls.sort_unstable(); + } + + impls.hash_stable(hcx, hasher); + } + } +} + diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs index e95dbdd15c5f0..dad5c35c1e814 100644 --- a/src/librustc/ich/impls_cstore.rs +++ b/src/librustc/ich/impls_cstore.rs @@ -38,3 +38,10 @@ impl_stable_hash_for!(enum middle::cstore::LinkagePreference { RequireDynamic, RequireStatic }); + +impl_stable_hash_for!(struct middle::cstore::ExternCrate { + def_id, + span, + direct, + path_len +}); diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 411f5e26e4d05..a4cbcf0411199 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -13,13 +13,12 @@ use hir; use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; -use ich::{StableHashingContext, NodeIdHashingMode}; -use std::mem; - -use syntax::ast; - +use ich::{self, StableHashingContext, NodeIdHashingMode}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; +use std::mem; +use syntax::ast; +use util::nodemap::DefIdSet; impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefId { #[inline] @@ -30,6 +29,16 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefId } } +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefIdSet +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + ich::hash_stable_hashset(hcx, hasher, self, |hcx, def_id| { + hcx.def_path_hash(*def_id) + }); + } +} impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { #[inline] @@ -235,7 +244,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::T hir::TyTypeof(..) | hir::TyErr | hir::TyInfer => { - NodeIdHashingMode::Ignore + NodeIdHashingMode::CheckedIgnore } hir::TyPath(..) => { NodeIdHashingMode::HashTraitsInScope @@ -403,7 +412,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::P hir::PatKind::Lit(..) | hir::PatKind::Range(..) | hir::PatKind::Slice(..) => { - NodeIdHashingMode::Ignore + NodeIdHashingMode::CheckedIgnore } hir::PatKind::Path(..) | hir::PatKind::Struct(..) | @@ -574,21 +583,21 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E hir::ExprRepeat(..) | hir::ExprTup(..) => { // For these we only hash the span when debuginfo is on. - (false, NodeIdHashingMode::Ignore) + (false, NodeIdHashingMode::CheckedIgnore) } // For the following, spans might be significant because of // panic messages indicating the source location. hir::ExprBinary(op, ..) => { - (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::Ignore) + (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::CheckedIgnore) } hir::ExprUnary(op, _) => { - (hcx.unop_can_panic_at_runtime(op), NodeIdHashingMode::Ignore) + (hcx.unop_can_panic_at_runtime(op), NodeIdHashingMode::CheckedIgnore) } hir::ExprAssignOp(op, ..) => { - (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::Ignore) + (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::CheckedIgnore) } hir::ExprIndex(..) => { - (true, NodeIdHashingMode::Ignore) + (true, NodeIdHashingMode::CheckedIgnore) } // For these we don't care about the span, but want to hash the // trait in scope @@ -899,7 +908,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => { - (NodeIdHashingMode::Ignore, hcx.hash_spans()) + (NodeIdHashingMode::CheckedIgnore, hcx.hash_spans()) } hir::ItemUse(..) => { (NodeIdHashingMode::HashTraitsInScope, false) @@ -916,7 +925,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) => { - (NodeIdHashingMode::Ignore, false) + (NodeIdHashingMode::CheckedIgnore, false) } }; @@ -1160,3 +1169,20 @@ for ::middle::lang_items::LangItem { ::std::hash::Hash::hash(self, hasher); } } + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +for hir::TraitCandidate { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + let hir::TraitCandidate { + def_id, + import_id, + } = *self; + + def_id.hash_stable(hcx, hasher); + import_id.hash_stable(hcx, hasher); + }); + } +} diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index e933ca4c2b551..53a071fe48030 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -11,12 +11,13 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::ty in no particular order. -use ich::StableHashingContext; +use ich::{self, StableHashingContext, NodeIdHashingMode}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; use std::hash as std_hash; use std::mem; use middle::region; +use traits; use ty; impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> @@ -304,7 +305,9 @@ for ::middle::const_val::ConstVal<'gcx> { } Function(def_id, substs) => { def_id.hash_stable(hcx, hasher); - substs.hash_stable(hcx, hasher); + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + substs.hash_stable(hcx, hasher); + }); } Aggregate(Struct(ref name_values)) => { let mut values = name_values.to_vec(); @@ -338,6 +341,54 @@ impl_stable_hash_for!(struct ty::Const<'tcx> { val }); +impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> { + span, + kind +}); + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +for ::middle::const_val::ErrKind<'gcx> { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + use middle::const_val::ErrKind::*; + + mem::discriminant(self).hash_stable(hcx, hasher); + + match *self { + CannotCast | + MissingStructField | + NonConstPath | + ExpectedConstTuple | + ExpectedConstStruct | + IndexedNonVec | + IndexNotUsize | + MiscBinaryOp | + MiscCatchAll | + IndexOpFeatureGated | + TypeckError => { + // nothing to do + } + UnimplementedConstVal(s) => { + s.hash_stable(hcx, hasher); + } + IndexOutOfBounds { len, index } => { + len.hash_stable(hcx, hasher); + index.hash_stable(hcx, hasher); + } + Math(ref const_math_err) => { + const_math_err.hash_stable(hcx, hasher); + } + LayoutError(ref layout_error) => { + layout_error.hash_stable(hcx, hasher); + } + ErroneousReferencedConstant(ref const_val) => { + const_val.hash_stable(hcx, hasher); + } + } + } +} + impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs }); impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness }); @@ -414,7 +465,6 @@ impl_stable_hash_for!(struct ty::TypeParameterDef { pure_wrt_drop }); - impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ::middle::resolve_lifetime::Set1<T> where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> @@ -470,19 +520,21 @@ for region::Scope hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); - match *self { - region::Scope::Node(node_id) | - region::Scope::Destruction(node_id) => { - node_id.hash_stable(hcx, hasher); - } - region::Scope::CallSite(body_id) | - region::Scope::Arguments(body_id) => { - body_id.hash_stable(hcx, hasher); - } - region::Scope::Remainder(block_remainder) => { - block_remainder.hash_stable(hcx, hasher); - } - } + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + match *self { + region::Scope::Node(node_id) | + region::Scope::Destruction(node_id) => { + node_id.hash_stable(hcx, hasher); + } + region::Scope::CallSite(body_id) | + region::Scope::Arguments(body_id) => { + body_id.hash_stable(hcx, hasher); + } + region::Scope::Remainder(block_remainder) => { + block_remainder.hash_stable(hcx, hasher); + } + } + }) } } @@ -520,6 +572,7 @@ for ty::TypeVariants<'gcx> TyBool | TyChar | TyStr | + TyError | TyNever => { // Nothing more to hash. } @@ -585,10 +638,8 @@ for ty::TypeVariants<'gcx> TyParam(param_ty) => { param_ty.hash_stable(hcx, hasher); } - - TyError | TyInfer(..) => { - bug!("ty::TypeVariants::hash_stable() - Unexpected variant.") + bug!("ty::TypeVariants::hash_stable() - Unexpected variant {:?}.", *self) } } } @@ -636,26 +687,6 @@ impl_stable_hash_for!(struct ty::ExistentialProjection<'tcx> { ty }); -impl_stable_hash_for!(enum ty::fast_reject::SimplifiedType { - BoolSimplifiedType, - CharSimplifiedType, - IntSimplifiedType(int_ty), - UintSimplifiedType(int_ty), - FloatSimplifiedType(float_ty), - AdtSimplifiedType(def_id), - StrSimplifiedType, - ArraySimplifiedType, - PtrSimplifiedType, - NeverSimplifiedType, - TupleSimplifiedType(size), - TraitSimplifiedType(def_id), - ClosureSimplifiedType(def_id), - GeneratorSimplifiedType(def_id), - AnonSimplifiedType(def_id), - FunctionSimplifiedType(params), - ParameterSimplifiedType -}); - impl_stable_hash_for!(struct ty::Instance<'tcx> { def, substs @@ -697,3 +728,149 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::In } } +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::TraitDef { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let ty::TraitDef { + // We already have the def_path_hash below, no need to hash it twice + def_id: _, + unsafety, + paren_sugar, + has_default_impl, + def_path_hash, + } = *self; + + unsafety.hash_stable(hcx, hasher); + paren_sugar.hash_stable(hcx, hasher); + has_default_impl.hash_stable(hcx, hasher); + def_path_hash.hash_stable(hcx, hasher); + } +} + +impl_stable_hash_for!(struct ty::Destructor { + did +}); + +impl_stable_hash_for!(struct ty::DtorckConstraint<'tcx> { + outlives, + dtorck_types +}); + + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::CrateVariancesMap { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let ty::CrateVariancesMap { + ref dependencies, + ref variances, + // This is just an irrelevant helper value. + empty_variance: _, + } = *self; + + dependencies.hash_stable(hcx, hasher); + + ich::hash_stable_hashmap(hcx, hasher, variances, |hcx, def_id| { + hcx.def_path_hash(*def_id) + }); + } +} + +impl_stable_hash_for!(struct ty::AssociatedItem { + def_id, + name, + kind, + vis, + defaultness, + container, + method_has_self_argument +}); + +impl_stable_hash_for!(enum ty::AssociatedKind { + Const, + Method, + Type +}); + +impl_stable_hash_for!(enum ty::AssociatedItemContainer { + TraitContainer(def_id), + ImplContainer(def_id) +}); + + +impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +for ty::steal::Steal<T> + where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + self.borrow().hash_stable(hcx, hasher); + } +} + +impl_stable_hash_for!(struct ty::ParamEnv<'tcx> { + caller_bounds, + reveal +}); + +impl_stable_hash_for!(enum traits::Reveal { + UserFacing, + All +}); + +impl_stable_hash_for!(enum ::middle::privacy::AccessLevel { + Reachable, + Exported, + Public +}); + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +for ::middle::privacy::AccessLevels { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + let ::middle::privacy::AccessLevels { + ref map + } = *self; + + ich::hash_stable_nodemap(hcx, hasher, map); + }); + } +} + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +for ty::CrateInherentImpls { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let ty::CrateInherentImpls { + ref inherent_impls, + } = *self; + + ich::hash_stable_hashmap(hcx, hasher, inherent_impls, |hcx, def_id| { + hcx.def_path_hash(*def_id) + }); + } +} + +impl_stable_hash_for!(enum ::session::CompileIncomplete { + Stopped, + Errored(error_reported) +}); + +impl_stable_hash_for!(struct ::util::common::ErrorReported {}); + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +for ::middle::reachable::ReachableSet { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let ::middle::reachable::ReachableSet(ref reachable_set) = *self; + + ich::hash_stable_nodeset(hcx, hasher, reachable_set); + } +} + diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index dcf84be0eeb3a..c24064eb27c58 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -13,8 +13,9 @@ pub use self::fingerprint::Fingerprint; pub use self::caching_codemap_view::CachingCodemapView; pub use self::hcx::{StableHashingContext, NodeIdHashingMode, hash_stable_hashmap, - hash_stable_hashset, hash_stable_nodemap, - hash_stable_btreemap, hash_stable_itemlocalmap}; + hash_stable_hashset, hash_stable_nodemap, hash_stable_nodeset, + hash_stable_btreemap, hash_stable_itemlocalmap, + hash_stable_trait_impls}; mod fingerprint; mod caching_codemap_view; mod hcx; diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index c5863b5618feb..e953afd799dbf 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -12,9 +12,12 @@ use std::cmp; use errors::DiagnosticBuilder; use hir::HirId; +use ich::{self, StableHashingContext}; use lint::builtin; use lint::context::CheckLintNameResult; use lint::{self, Lint, LintId, Level, LintSource}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHasherResult}; use session::Session; use syntax::ast; use syntax::attr; @@ -382,3 +385,61 @@ impl LintLevelMap { }) } } + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LintLevelMap { + #[inline] + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let LintLevelMap { + ref sets, + ref id_to_set, + } = *self; + + let definitions = hcx.tcx().hir.definitions(); + ich::hash_stable_hashmap(hcx, hasher, id_to_set, |_, hir_id| { + (definitions.def_path_hash(hir_id.owner), hir_id.local_id) + }); + + let LintLevelSets { + ref list, + lint_cap, + } = *sets; + + lint_cap.hash_stable(hcx, hasher); + + hcx.while_hashing_spans(true, |hcx| { + list.len().hash_stable(hcx, hasher); + + // We are working under the assumption here that the list of + // lint-sets is built in a deterministic order. + for lint_set in list { + ::std::mem::discriminant(lint_set).hash_stable(hcx, hasher); + + match *lint_set { + LintSet::CommandLine { ref specs } => { + ich::hash_stable_hashmap(hcx, hasher, specs, |_, lint_id| { + lint_id.lint_name_raw() + }); + } + LintSet::Node { ref specs, parent } => { + ich::hash_stable_hashmap(hcx, hasher, specs, |_, lint_id| { + lint_id.lint_name_raw() + }); + parent.hash_stable(hcx, hasher); + } + } + } + }) + } +} + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LintId { + #[inline] + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + self.lint_name_raw().hash_stable(hcx, hasher); + } +} + diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index c64e1c08082a5..42b5e2dd83de5 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -305,6 +305,10 @@ impl LintId { } } + pub fn lint_name_raw(&self) -> &'static str { + self.lint.name + } + /// Get the name of the lint. pub fn to_string(&self) -> String { self.lint.name_lower() @@ -317,6 +321,13 @@ pub enum Level { Allow, Warn, Deny, Forbid } +impl_stable_hash_for!(enum self::Level { + Allow, + Warn, + Deny, + Forbid +}); + impl Level { /// Convert a level to a lower-case string. pub fn as_str(self) -> &'static str { @@ -354,6 +365,12 @@ pub enum LintSource { CommandLine(Symbol), } +impl_stable_hash_for!(enum self::LintSource { + Default, + Node(name, span), + CommandLine(text) +}); + pub type LevelSource = (Level, LintSource); pub mod builtin; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 7c44245090197..fa29dda86ddd0 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -369,7 +369,13 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, } } -fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> Rc<NodeSet> { +// We introduce a new-type here, so we can have a specialized HashStable +// implementation for it. +#[derive(Clone)] +pub struct ReachableSet(pub Rc<NodeSet>); + + +fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> ReachableSet { debug_assert!(crate_num == LOCAL_CRATE); let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE); @@ -414,7 +420,7 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> reachable_context.propagate(); // Return the set of reachable symbols. - Rc::new(reachable_context.reachable_symbols) + ReachableSet(Rc::new(reachable_context.reachable_symbols)) } pub fn provide(providers: &mut Providers) { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index ae9866edc53b2..562536ced3ce9 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -14,6 +14,7 @@ //! Most of the documentation on regions can be found in //! `middle/infer/region_inference/README.md` +use ich::{self, StableHashingContext, NodeIdHashingMode}; use util::nodemap::{FxHashMap, FxHashSet}; use ty; @@ -31,6 +32,8 @@ use hir::def_id::DefId; use hir::intravisit::{self, Visitor, NestedVisitorMap}; use hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local}; use mir::transform::MirSource; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHasherResult}; /// Scope represents a statically-describable scope that can be /// used to bound the lifetime/region for values. @@ -1235,3 +1238,43 @@ pub fn provide(providers: &mut Providers) { ..*providers }; } + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ScopeTree { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let ScopeTree { + root_body, + root_parent, + ref parent_map, + ref var_map, + ref destruction_scopes, + ref rvalue_scopes, + ref closure_tree, + ref yield_in_scope, + } = *self; + + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + root_body.hash_stable(hcx, hasher); + root_parent.hash_stable(hcx, hasher); + }); + + ich::hash_stable_hashmap(hcx, hasher, parent_map, |hcx, scope| { + let mut hasher = StableHasher::new(); + scope.hash_stable(hcx, &mut hasher); + let stable: u64 = hasher.finish(); + stable + }); + + ich::hash_stable_itemlocalmap(hcx, hasher, var_map); + ich::hash_stable_itemlocalmap(hcx, hasher, destruction_scopes); + ich::hash_stable_itemlocalmap(hcx, hasher, rvalue_scopes); + ich::hash_stable_itemlocalmap(hcx, hasher, closure_tree); + ich::hash_stable_hashmap(hcx, hasher, yield_in_scope, |hcx, scope| { + let mut hasher = StableHasher::new(); + scope.hash_stable(hcx, &mut hasher); + let stable: u64 = hasher.finish(); + stable + }); + } +} diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 2640542ad1059..ecaf14659ae6b 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -11,6 +11,9 @@ use super::OverlapError; use hir::def_id::DefId; +use ich::{self, StableHashingContext}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHasherResult}; use traits; use ty::{self, TyCtxt, TypeFoldable}; use ty::fast_reject::{self, SimplifiedType}; @@ -365,3 +368,34 @@ pub fn ancestors(tcx: TyCtxt, current_source: Some(Node::Impl(start_from_impl)), } } + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Children { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let Children { + ref nonblanket_impls, + ref blanket_impls, + } = *self; + + ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls); + } +} + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Graph { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let Graph { + ref parent, + ref children, + } = *self; + + ich::hash_stable_hashmap(hcx, hasher, parent, |hcx, def_id| { + hcx.def_path_hash(*def_id) + }); + ich::hash_stable_hashmap(hcx, hasher, children, |hcx, def_id| { + hcx.def_path_hash(*def_id) + }); + } +} diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 353a1cd5355b9..86ae4bb92df07 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -9,29 +9,44 @@ // except according to those terms. use hir::def_id::DefId; -use ty::{self, Ty, TyCtxt}; +use ich::StableHashingContext; +use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult, + HashStable}; +use std::fmt::Debug; +use std::hash::Hash; +use std::mem; use syntax::ast; +use ty::{self, Ty, TyCtxt}; -use self::SimplifiedType::*; +use self::SimplifiedTypeGen::*; -/// See `simplify_type -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum SimplifiedType { +pub type SimplifiedType = SimplifiedTypeGen<DefId>; + +/// See `simplify_type` +/// +/// Note that we keep this type generic over the type of identifier it uses +/// because we sometimes need to use SimplifiedTypeGen values as stable sorting +/// keys (in which case we use a DefPathHash as id-type) but in the general case +/// the non-stable but fast to construct DefId-version is the better choice. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum SimplifiedTypeGen<D> + where D: Copy + Debug + Ord + Eq + Hash +{ BoolSimplifiedType, CharSimplifiedType, IntSimplifiedType(ast::IntTy), UintSimplifiedType(ast::UintTy), FloatSimplifiedType(ast::FloatTy), - AdtSimplifiedType(DefId), + AdtSimplifiedType(D), StrSimplifiedType, ArraySimplifiedType, PtrSimplifiedType, NeverSimplifiedType, TupleSimplifiedType(usize), - TraitSimplifiedType(DefId), - ClosureSimplifiedType(DefId), - GeneratorSimplifiedType(DefId), - AnonSimplifiedType(DefId), + TraitSimplifiedType(D), + ClosureSimplifiedType(D), + GeneratorSimplifiedType(D), + AnonSimplifiedType(D), FunctionSimplifiedType(usize), ParameterSimplifiedType, } @@ -101,3 +116,62 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, ty::TyInfer(_) | ty::TyError => None, } } + +impl<D: Copy + Debug + Ord + Eq + Hash> SimplifiedTypeGen<D> { + pub fn map_def<U, F>(self, map: F) -> SimplifiedTypeGen<U> + where F: Fn(D) -> U, + U: Copy + Debug + Ord + Eq + Hash, + { + match self { + BoolSimplifiedType => BoolSimplifiedType, + CharSimplifiedType => CharSimplifiedType, + IntSimplifiedType(t) => IntSimplifiedType(t), + UintSimplifiedType(t) => UintSimplifiedType(t), + FloatSimplifiedType(t) => FloatSimplifiedType(t), + AdtSimplifiedType(d) => AdtSimplifiedType(map(d)), + StrSimplifiedType => StrSimplifiedType, + ArraySimplifiedType => ArraySimplifiedType, + PtrSimplifiedType => PtrSimplifiedType, + NeverSimplifiedType => NeverSimplifiedType, + TupleSimplifiedType(n) => TupleSimplifiedType(n), + TraitSimplifiedType(d) => TraitSimplifiedType(map(d)), + ClosureSimplifiedType(d) => ClosureSimplifiedType(map(d)), + GeneratorSimplifiedType(d) => GeneratorSimplifiedType(map(d)), + AnonSimplifiedType(d) => AnonSimplifiedType(map(d)), + FunctionSimplifiedType(n) => FunctionSimplifiedType(n), + ParameterSimplifiedType => ParameterSimplifiedType, + } + } +} + +impl<'a, 'gcx, 'tcx, D> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for SimplifiedTypeGen<D> + where D: Copy + Debug + Ord + Eq + Hash + + HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + mem::discriminant(self).hash_stable(hcx, hasher); + match *self { + BoolSimplifiedType | + CharSimplifiedType | + StrSimplifiedType | + ArraySimplifiedType | + PtrSimplifiedType | + NeverSimplifiedType | + ParameterSimplifiedType => { + // nothing to do + } + IntSimplifiedType(t) => t.hash_stable(hcx, hasher), + UintSimplifiedType(t) => t.hash_stable(hcx, hasher), + FloatSimplifiedType(t) => t.hash_stable(hcx, hasher), + AdtSimplifiedType(d) => d.hash_stable(hcx, hasher), + TupleSimplifiedType(n) => n.hash_stable(hcx, hasher), + TraitSimplifiedType(d) => d.hash_stable(hcx, hasher), + ClosureSimplifiedType(d) => d.hash_stable(hcx, hasher), + GeneratorSimplifiedType(d) => d.hash_stable(hcx, hasher), + AnonSimplifiedType(d) => d.hash_stable(hcx, hasher), + FunctionSimplifiedType(n) => n.hash_stable(hcx, hasher), + } + } +} diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 84d7745a64f0a..1ae1e7007ac5e 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -23,8 +23,13 @@ use std::cmp; use std::fmt; use std::i64; use std::iter; +use std::mem; use std::ops::Deref; +use ich::StableHashingContext; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHasherResult}; + /// Parsed [Data layout](http://llvm.org/docs/LangRef.html#data-layout) /// for a target, which contains everything needed to compute layouts. pub struct TargetDataLayout { @@ -2300,3 +2305,128 @@ impl<'a, 'tcx> TyLayout<'tcx> { cx.layout_of(cx.normalize_projections(self.field_type(cx, i))) } } + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Layout +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + use ty::layout::Layout::*; + mem::discriminant(self).hash_stable(hcx, hasher); + + match *self { + Scalar { value, non_zero } => { + value.hash_stable(hcx, hasher); + non_zero.hash_stable(hcx, hasher); + } + Vector { element, count } => { + element.hash_stable(hcx, hasher); + count.hash_stable(hcx, hasher); + } + Array { sized, align, primitive_align, element_size, count } => { + sized.hash_stable(hcx, hasher); + align.hash_stable(hcx, hasher); + primitive_align.hash_stable(hcx, hasher); + element_size.hash_stable(hcx, hasher); + count.hash_stable(hcx, hasher); + } + FatPointer { ref metadata, non_zero } => { + metadata.hash_stable(hcx, hasher); + non_zero.hash_stable(hcx, hasher); + } + CEnum { discr, signed, non_zero, min, max } => { + discr.hash_stable(hcx, hasher); + signed.hash_stable(hcx, hasher); + non_zero.hash_stable(hcx, hasher); + min.hash_stable(hcx, hasher); + max.hash_stable(hcx, hasher); + } + Univariant { ref variant, non_zero } => { + variant.hash_stable(hcx, hasher); + non_zero.hash_stable(hcx, hasher); + } + UntaggedUnion { ref variants } => { + variants.hash_stable(hcx, hasher); + } + General { discr, ref variants, size, align, primitive_align } => { + discr.hash_stable(hcx, hasher); + variants.hash_stable(hcx, hasher); + size.hash_stable(hcx, hasher); + align.hash_stable(hcx, hasher); + primitive_align.hash_stable(hcx, hasher); + } + RawNullablePointer { nndiscr, ref value } => { + nndiscr.hash_stable(hcx, hasher); + value.hash_stable(hcx, hasher); + } + StructWrappedNullablePointer { + nndiscr, + ref nonnull, + ref discrfield, + ref discrfield_source + } => { + nndiscr.hash_stable(hcx, hasher); + nonnull.hash_stable(hcx, hasher); + discrfield.hash_stable(hcx, hasher); + discrfield_source.hash_stable(hcx, hasher); + } + } + } +} + +impl_stable_hash_for!(enum ::ty::layout::Integer { + I1, + I8, + I16, + I32, + I64, + I128 +}); + +impl_stable_hash_for!(enum ::ty::layout::Primitive { + Int(integer), + F32, + F64, + Pointer +}); + +impl_stable_hash_for!(struct ::ty::layout::Align { + abi, + pref +}); + +impl_stable_hash_for!(struct ::ty::layout::Size { + raw +}); + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LayoutError<'gcx> +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + use ty::layout::LayoutError::*; + mem::discriminant(self).hash_stable(hcx, hasher); + + match *self { + Unknown(t) | + SizeOverflow(t) => t.hash_stable(hcx, hasher) + } + } +} + +impl_stable_hash_for!(struct ::ty::layout::Struct { + align, + primitive_align, + packed, + sized, + offsets, + memory_index, + min_size +}); + +impl_stable_hash_for!(struct ::ty::layout::Union { + align, + primitive_align, + min_size, + packed +}); diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index bf17b82535cc1..48502dc2e8c84 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -14,11 +14,13 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; use hir::def::{Def, Export}; use hir::{self, TraitCandidate, ItemLocalId}; use hir::svh::Svh; +use ich::{Fingerprint, StableHashingContext}; use lint; use middle::const_val; use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary}; use middle::cstore::{NativeLibraryKind, DepKind, CrateSource}; use middle::privacy::AccessLevels; +use middle::reachable::ReachableSet; use middle::region; use middle::resolve_lifetime::{Region, ObjectLifetimeDefault}; use middle::stability::{self, DeprecationEntry}; @@ -36,7 +38,7 @@ use ty::item_path; use ty::steal::Steal; use ty::subst::Substs; use ty::fast_reject::SimplifiedType; -use util::nodemap::{DefIdSet, NodeSet, DefIdMap}; +use util::nodemap::{DefIdSet, DefIdMap}; use util::common::{profq_msg, ProfileQueriesMsg}; use rustc_data_structures::indexed_set::IdxSetBuf; @@ -44,6 +46,7 @@ use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::cell::{RefCell, RefMut, Cell}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -925,9 +928,8 @@ macro_rules! define_maps { span = key.default_span(tcx) } + let dep_node = Self::to_dep_node(tcx, &key); let res = tcx.cycle_check(span, Query::$name(key), || { - let dep_node = Self::to_dep_node(tcx, &key); - tcx.sess.diagnostic().track_diagnostics(|| { if dep_node.kind.is_anon() { tcx.dep_graph.with_anon_task(dep_node.kind, || { @@ -951,6 +953,20 @@ macro_rules! define_maps { tcx.dep_graph.read_index(dep_node_index); + // In incremental mode, hash the result of the query. We don't + // do anything with the hash yet, but we are computing it + // anyway so that + // - we make sure that the infrastructure works and + // - we can get an idea of the runtime cost. + if !dep_node.kind.is_anon() && tcx.sess.opts.incremental.is_some() { + let mut hcx = StableHashingContext::new(tcx); + let mut hasher = StableHasher::new(); + + result.hash_stable(&mut hcx, &mut hasher); + + let _: Fingerprint = hasher.finish(); + } + let value = QueryValue { value: result, index: dep_node_index, @@ -1300,7 +1316,7 @@ define_maps! { <'tcx> /// Performs the privacy check and computes "access levels". [] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>, - [] fn reachable_set: reachability_dep_node(CrateNum) -> Rc<NodeSet>, + [] fn reachable_set: reachability_dep_node(CrateNum) -> ReachableSet, /// Per-body `region::ScopeTree`. The `DefId` should be the owner-def-id for the body; /// in the case of closures, this will be redirected to the enclosing function. diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 3aadacfe826fd..9ae6c3516a5cf 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -11,13 +11,15 @@ use hir; use hir::def_id::DefId; use hir::map::DefPathHash; +use ich::{self, StableHashingContext}; use traits::specialization_graph; use ty::fast_reject; use ty::fold::TypeFoldable; use ty::{Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; - +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHasherResult}; use std::rc::Rc; /// A trait's definition with type information. @@ -183,3 +185,16 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, non_blanket_impls: non_blanket_impls, }) } + +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for TraitImpls { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let TraitImpls { + ref blanket_impls, + ref non_blanket_impls, + } = *self; + + ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, non_blanket_impls); + } +} diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 33c4a041cff88..0d0cf67248944 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -365,8 +365,24 @@ impl<T, CTX> HashStable<CTX> for Option<T> } } +impl<T1, T2, CTX> HashStable<CTX> for Result<T1, T2> + where T1: HashStable<CTX>, + T2: HashStable<CTX>, +{ + #[inline] + fn hash_stable<W: StableHasherResult>(&self, + ctx: &mut CTX, + hasher: &mut StableHasher<W>) { + mem::discriminant(self).hash_stable(ctx, hasher); + match *self { + Ok(ref x) => x.hash_stable(ctx, hasher), + Err(ref x) => x.hash_stable(ctx, hasher), + } + } +} + impl<'a, T, CTX> HashStable<CTX> for &'a T - where T: HashStable<CTX> + where T: HashStable<CTX> + ?Sized { #[inline] fn hash_stable<W: StableHasherResult>(&self, @@ -425,3 +441,13 @@ impl<I: ::indexed_vec::Idx, T, CTX> HashStable<CTX> for ::indexed_vec::IndexVec< } } } + + +impl<I: ::indexed_vec::Idx, CTX> HashStable<CTX> for ::indexed_set::IdxSetBuf<I> +{ + fn hash_stable<W: StableHasherResult>(&self, + ctx: &mut CTX, + hasher: &mut StableHasher<W>) { + self.words().hash_stable(ctx, hasher); + } +} diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index dc18cdd8f0dd6..6ed928ca09deb 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -15,7 +15,8 @@ //! "types-as-contracts"-validation, namely, AcquireValid, ReleaseValid, and EndRegion. use rustc::ty::subst::Substs; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts}; +use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::visit::{MutVisitor, Lookup}; use rustc::mir::transform::{MirPass, MirSource}; @@ -79,6 +80,45 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> { self.super_statement(block, statement, location); self.in_validation_statement = false; } + + fn visit_const_val(&mut self, + const_val: &mut ConstVal<'tcx>, + _: Location) { + erase_const_val(self.tcx, const_val); + self.super_const_val(const_val); + + fn erase_const_val<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + const_val: &mut ConstVal<'tcx>) { + match *const_val { + ConstVal::Float(_) | + ConstVal::Integral(_) | + ConstVal::Str(_) | + ConstVal::ByteStr(_) | + ConstVal::Bool(_) | + ConstVal::Char(_) | + ConstVal::Variant(_) => { + // nothing to do + } + ConstVal::Function(_, ref mut substs) => { + *substs = tcx.erase_regions(&{*substs}); + } + ConstVal::Struct(ref mut field_map) => { + for (_, field_val) in field_map { + erase_const_val(tcx, field_val); + } + } + ConstVal::Tuple(ref mut fields) | + ConstVal::Array(ref mut fields) => { + for field_val in fields { + erase_const_val(tcx, field_val); + } + } + ConstVal::Repeat(ref mut expr, _) => { + erase_const_val(tcx, &mut **expr); + } + } + } + } } pub struct EraseRegions; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 5248f874a6e97..496be8b3eb23e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1221,7 +1221,8 @@ pub enum ImplItemKind { Macro(Mac), } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, + PartialOrd, Ord)] pub enum IntTy { Is, I8, @@ -1274,7 +1275,8 @@ impl IntTy { } } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, + PartialOrd, Ord)] pub enum UintTy { Us, U8, @@ -1324,7 +1326,8 @@ impl fmt::Display for UintTy { } } -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy, + PartialOrd, Ord)] pub enum FloatTy { F32, F64, From 3cc3ae22bddc4fb24c790b58700a699c764ebd0e Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Thu, 7 Sep 2017 16:11:58 +0200 Subject: [PATCH 14/24] incr.comp.: Move result fingerprinting to DepGraph::with_task(). This makes sure that we don't introduce strange cases where we have nodes outside the query system that could break red/green tracking and it will allow to keep red/green neatly encapsulated within the DepGraph implementation. --- src/librustc/dep_graph/graph.rs | 36 +++++++++++++------ src/librustc/dep_graph/safe.rs | 7 ++++ src/librustc/ich/hcx.rs | 10 ++++-- src/librustc/ty/maps.rs | 17 +-------- src/librustc/ty/mod.rs | 4 +++ src/librustc_data_structures/stable_hasher.rs | 28 +++++++++++++-- src/librustc_trans/base.rs | 31 +++++++++++++++- src/librustc_trans/context.rs | 14 ++++++++ src/librustc_typeck/variance/constraints.rs | 20 ++++++++--- 9 files changed, 130 insertions(+), 37 deletions(-) diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index 34cb1d2a6d795..7679b7e7971eb 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -9,11 +9,15 @@ // except according to those terms. use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, + StableHashingContextProvider}; use session::config::OutputType; use std::cell::{Ref, RefCell}; use std::rc::Rc; use util::common::{ProfileQueriesMsg, profq_msg}; +use ich::Fingerprint; + use super::dep_node::{DepNode, DepKind, WorkProductId}; use super::query::DepGraphQuery; use super::raii; @@ -71,10 +75,6 @@ impl DepGraph { self.data.as_ref().map(|data| raii::IgnoreTask::new(&data.edges)) } - pub fn in_task<'graph>(&'graph self, key: DepNode) -> Option<raii::DepTask<'graph>> { - self.data.as_ref().map(|data| raii::DepTask::new(&data.edges, key)) - } - pub fn with_ignore<OP,R>(&self, op: OP) -> R where OP: FnOnce() -> R { @@ -109,24 +109,38 @@ impl DepGraph { /// `arg` parameter. /// /// [README]: README.md - pub fn with_task<C, A, R>(&self, - key: DepNode, - cx: C, - arg: A, - task: fn(C, A) -> R) - -> (R, DepNodeIndex) - where C: DepGraphSafe + pub fn with_task<C, A, R, HCX>(&self, + key: DepNode, + cx: C, + arg: A, + task: fn(C, A) -> R) + -> (R, DepNodeIndex) + where C: DepGraphSafe + StableHashingContextProvider<ContextType=HCX>, + R: HashStable<HCX>, { if let Some(ref data) = self.data { data.edges.borrow_mut().push_task(key); if cfg!(debug_assertions) { profq_msg(ProfileQueriesMsg::TaskBegin(key.clone())) }; + + // In incremental mode, hash the result of the task. We don't + // do anything with the hash yet, but we are computing it + // anyway so that + // - we make sure that the infrastructure works and + // - we can get an idea of the runtime cost. + let mut hcx = cx.create_stable_hashing_context(); + let result = task(cx, arg); if cfg!(debug_assertions) { profq_msg(ProfileQueriesMsg::TaskEnd) }; let dep_node_index = data.edges.borrow_mut().pop_task(key); + + let mut stable_hasher = StableHasher::new(); + result.hash_stable(&mut hcx, &mut stable_hasher); + let _: Fingerprint = stable_hasher.finish(); + (result, dep_node_index) } else { (task(cx, arg), DepNodeIndex::INVALID) diff --git a/src/librustc/dep_graph/safe.rs b/src/librustc/dep_graph/safe.rs index bf224f89f0ddb..f82bf9be03390 100644 --- a/src/librustc/dep_graph/safe.rs +++ b/src/librustc/dep_graph/safe.rs @@ -58,6 +58,13 @@ impl<'a, A> DepGraphSafe for &'a A { } +/// Mut ref to dep-graph-safe stuff should still be dep-graph-safe. +impl<'a, A> DepGraphSafe for &'a mut A + where A: DepGraphSafe, +{ +} + + /// No data here! :) impl DepGraphSafe for () { } diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 767868ffda318..f4fa376347ae9 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -26,8 +26,8 @@ use syntax::ext::hygiene::SyntaxContext; use syntax::symbol::Symbol; use syntax_pos::Span; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvider, + StableHasher, StableHasherResult}; use rustc_data_structures::accumulate_vec::AccumulateVec; /// This is the context state available during incr. comp. hashing. It contains @@ -196,6 +196,12 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { } } +impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx> { + type ContextType = StableHashingContext<'a, 'gcx, 'lcx>; + fn create_stable_hashing_context(&self) -> Self::ContextType { + StableHashingContext::new(*self) + } +} impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId { fn hash_stable<W: StableHasherResult>(&self, diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 48502dc2e8c84..c96ae862265df 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -14,7 +14,6 @@ use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex}; use hir::def::{Def, Export}; use hir::{self, TraitCandidate, ItemLocalId}; use hir::svh::Svh; -use ich::{Fingerprint, StableHashingContext}; use lint; use middle::const_val; use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary}; @@ -46,7 +45,7 @@ use rustc_back::PanicStrategy; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::cell::{RefCell, RefMut, Cell}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; + use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; @@ -953,20 +952,6 @@ macro_rules! define_maps { tcx.dep_graph.read_index(dep_node_index); - // In incremental mode, hash the result of the query. We don't - // do anything with the hash yet, but we are computing it - // anyway so that - // - we make sure that the infrastructure works and - // - we can get an idea of the runtime cost. - if !dep_node.kind.is_anon() && tcx.sess.opts.incremental.is_some() { - let mut hcx = StableHashingContext::new(tcx); - let mut hasher = StableHasher::new(); - - result.hash_stable(&mut hcx, &mut hasher); - - let _: Fingerprint = hasher.finish(); - } - let value = QueryValue { value: result, index: dep_node_index, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e2df963f80fad..da00f12edacb0 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2575,6 +2575,10 @@ pub struct SymbolName { pub name: InternedString } +impl_stable_hash_for!(struct self::SymbolName { + name +}); + impl Deref for SymbolName { type Target = str; diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 0d0cf67248944..f80cbfadf2e7f 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -192,6 +192,28 @@ impl<W> Hasher for StableHasher<W> { } +/// Something that can provide a stable hashing context. +pub trait StableHashingContextProvider { + type ContextType; + fn create_stable_hashing_context(&self) -> Self::ContextType; +} + +impl<'a, T: StableHashingContextProvider> StableHashingContextProvider for &'a T { + type ContextType = T::ContextType; + + fn create_stable_hashing_context(&self) -> Self::ContextType { + (**self).create_stable_hashing_context() + } +} + +impl<'a, T: StableHashingContextProvider> StableHashingContextProvider for &'a mut T { + type ContextType = T::ContextType; + + fn create_stable_hashing_context(&self) -> Self::ContextType { + (**self).create_stable_hashing_context() + } +} + /// Something that implements `HashStable<CTX>` can be hashed in a way that is /// stable across multiple compilation sessions. pub trait HashStable<CTX> { @@ -292,7 +314,7 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> { } } -impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Box<T> { +impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for Box<T> { #[inline] fn hash_stable<W: StableHasherResult>(&self, ctx: &mut CTX, @@ -301,7 +323,7 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Box<T> { } } -impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> { +impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> { #[inline] fn hash_stable<W: StableHasherResult>(&self, ctx: &mut CTX, @@ -310,7 +332,7 @@ impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ::std::rc::Rc<T> { } } -impl<T: HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> { +impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> { #[inline] fn hash_stable<W: StableHasherResult>(&self, ctx: &mut CTX, diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index d86f88d4c7da0..1e1b9929f0e37 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1070,7 +1070,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let start_time = Instant::now(); all_stats.extend(tcx.compile_codegen_unit(*cgu.name())); total_trans_time += start_time.elapsed(); - ongoing_translation.check_for_errors(tcx.sess); } @@ -1565,5 +1564,35 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { Visibility::Default => llvm::Visibility::Default, Visibility::Hidden => llvm::Visibility::Hidden, Visibility::Protected => llvm::Visibility::Protected, +} + +// FIXME(mw): Anything that is produced via DepGraph::with_task() must implement +// the HashStable trait. Normally DepGraph::with_task() calls are +// hidden behind queries, but CGU creation is a special case in two +// ways: (1) it's not a query and (2) CGU are output nodes, so their +// Fingerprints are not actually needed. It remains to be clarified +// how exactly this case will be handled in the red/green system but +// for now we content ourselves with providing a no-op HashStable +// implementation for CGUs. +mod temp_stable_hash_impls { + use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, + HashStable}; + use context::Stats; + use ModuleTranslation; + + impl<HCX> HashStable<HCX> for Stats { + fn hash_stable<W: StableHasherResult>(&self, + _: &mut HCX, + _: &mut StableHasher<W>) { + // do nothing + } + } + + impl<HCX> HashStable<HCX> for ModuleTranslation { + fn hash_stable<W: StableHasherResult>(&self, + _: &mut HCX, + _: &mut StableHasher<W>) { + // do nothing + } } } diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 8b18bf2e1ff1f..40fc07cfd4f62 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -14,6 +14,7 @@ use llvm::{ContextRef, ModuleRef, ValueRef}; use rustc::dep_graph::{DepGraph, DepGraphSafe}; use rustc::hir; use rustc::hir::def_id::DefId; +use rustc::ich::StableHashingContext; use rustc::traits; use debuginfo; use callee; @@ -25,6 +26,8 @@ use partitioning::CodegenUnit; use type_::Type; use rustc_data_structures::base_n; use rustc::middle::trans::Stats; +use rustc_data_structures::stable_hasher::StableHashingContextProvider; +use rustc::session::config::{self, NoDebugInfo, OutputFilenames}; use rustc::session::Session; use rustc::session::config::{self, NoDebugInfo}; use rustc::ty::layout::{LayoutCx, LayoutError, LayoutTyper, TyLayout}; @@ -134,6 +137,17 @@ impl<'a, 'tcx> CrateContext<'a, 'tcx> { impl<'a, 'tcx> DepGraphSafe for CrateContext<'a, 'tcx> { } +impl<'a, 'tcx> DepGraphSafe for SharedCrateContext<'a, 'tcx> { +} + +impl<'a, 'tcx> StableHashingContextProvider for SharedCrateContext<'a, 'tcx> { + type ContextType = StableHashingContext<'a, 'tcx, 'tcx>; + + fn create_stable_hashing_context(&self) -> Self::ContextType { + StableHashingContext::new(self.tcx) + } +} + pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode { let reloc_model_arg = match sess.opts.cg.relocation_model { Some(ref s) => &s[..], diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 70b989b6ab21c..4918dd78b3793 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -14,7 +14,8 @@ //! We walk the set of items and, for each member, generate new constraints. use hir::def_id::DefId; -use rustc::dep_graph::{AssertDepGraphSafe, DepKind}; +use rustc::dep_graph::{DepGraphSafe, DepKind}; +use rustc::ich::StableHashingContext; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use syntax::ast; @@ -22,6 +23,7 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc_data_structures::transitive_relation::TransitiveRelation; +use rustc_data_structures::stable_hasher::StableHashingContextProvider; use super::terms::*; use super::terms::VarianceTerm::*; @@ -138,6 +140,16 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> { } } +impl<'a, 'tcx> StableHashingContextProvider for ConstraintContext<'a, 'tcx> { + type ContextType = StableHashingContext<'a, 'tcx, 'tcx>; + + fn create_stable_hashing_context(&self) -> Self::ContextType { + StableHashingContext::new(self.terms_cx.tcx) + } +} + +impl<'a, 'tcx> DepGraphSafe for ConstraintContext<'a, 'tcx> {} + impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn visit_node_helper(&mut self, id: ast::NodeId) { let tcx = self.terms_cx.tcx; @@ -151,14 +163,14 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { // on dep-graph management. let dep_node = def_id.to_dep_node(tcx, DepKind::ItemVarianceConstraints); tcx.dep_graph.with_task(dep_node, - AssertDepGraphSafe(self), + self, def_id, visit_item_task); - fn visit_item_task<'a, 'tcx>(ccx: AssertDepGraphSafe<&mut ConstraintContext<'a, 'tcx>>, + fn visit_item_task<'a, 'tcx>(ccx: &mut ConstraintContext<'a, 'tcx>, def_id: DefId) { - ccx.0.build_constraints_for_item(def_id); + ccx.build_constraints_for_item(def_id); } } From e3f913167c0f232478b945aa236aab8340be62a9 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Tue, 12 Sep 2017 17:07:09 +0200 Subject: [PATCH 15/24] Fix issues uncovered by rebasing: - Don't hash traits in scope as part of HIR hashing any more. - Some queries returned DefIndexes from other crates. - Provide a generic way of stably hashing maps (not used everywhere yet). --- src/librustc/dep_graph/dep_node.rs | 12 ++ src/librustc/ich/hcx.rs | 44 ++-- src/librustc/ich/impls_cstore.rs | 6 + src/librustc/ich/impls_hir.rs | 200 +++++++++--------- src/librustc/ich/impls_misc.rs | 26 +++ src/librustc/ich/impls_syntax.rs | 30 ++- src/librustc/ich/mod.rs | 1 + src/librustc/middle/cstore.rs | 2 +- src/librustc/middle/lang_items.rs | 3 +- src/librustc/middle/stability.rs | 12 ++ src/librustc/ty/context.rs | 25 +-- src/librustc/ty/maps.rs | 2 +- src/librustc_data_structures/stable_hasher.rs | 87 ++++++-- src/librustc_incremental/calculate_svh/mod.rs | 53 +++-- src/librustc_incremental/persist/hash.rs | 2 + src/librustc_incremental/persist/load.rs | 1 + src/librustc_metadata/creader.rs | 5 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/decoder.rs | 3 +- src/librustc_metadata/native_libs.rs | 2 +- src/librustc_mir/transform/erase_regions.rs | 42 +--- .../ich_method_call_trait_scope.rs | 5 +- 22 files changed, 328 insertions(+), 237 deletions(-) create mode 100644 src/librustc/ich/impls_misc.rs diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 06469c16bc22e..1dcc9272d4e02 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -633,6 +633,18 @@ impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId,) { } } +impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefIndex,) { + const CAN_RECONSTRUCT_QUERY_KEY: bool = true; + + fn to_fingerprint(&self, tcx: TyCtxt) -> Fingerprint { + tcx.hir.definitions().def_path_hash(self.0).0 + } + + fn to_debug_str(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> String { + tcx.item_path_str(DefId::local(self.0)) + } +} + impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> DepNodeParams<'a, 'gcx, 'tcx> for (DefId, DefId) { const CAN_RECONSTRUCT_QUERY_KEY: bool = false; diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index f4fa376347ae9..daf1ff8ad2b95 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -27,7 +27,8 @@ use syntax::symbol::Symbol; use syntax_pos::Span; use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvider, - StableHasher, StableHasherResult}; + StableHasher, StableHasherResult, + ToStableHashKey}; use rustc_data_structures::accumulate_vec::AccumulateVec; /// This is the context state available during incr. comp. hashing. It contains @@ -48,9 +49,7 @@ pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { #[derive(PartialEq, Eq, Clone, Copy)] pub enum NodeIdHashingMode { Ignore, - CheckedIgnore, HashDefPath, - HashTraitsInScope, } impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { @@ -150,7 +149,7 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { self.overflow_checks_enabled = true; } let prev_hash_node_ids = self.node_id_hashing_mode; - self.node_id_hashing_mode = NodeIdHashingMode::CheckedIgnore; + self.node_id_hashing_mode = NodeIdHashingMode::Ignore; f(self); @@ -207,41 +206,28 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::N fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { - let hir_id = hcx.tcx.hir.node_to_hir_id(*self); match hcx.node_id_hashing_mode { NodeIdHashingMode::Ignore => { // Don't do anything. } - NodeIdHashingMode::CheckedIgnore => { - // Most NodeIds in the HIR can be ignored, but if there is a - // corresponding entry in the `trait_map` we need to hash that. - // Make sure we don't ignore too much by checking that there is - // no entry in a debug_assert!(). - debug_assert!(hcx.tcx.in_scope_traits(hir_id).is_none()); - } NodeIdHashingMode::HashDefPath => { - hir_id.hash_stable(hcx, hasher); - } - NodeIdHashingMode::HashTraitsInScope => { - if let Some(traits) = hcx.tcx.in_scope_traits(hir_id) { - // The ordering of the candidates is not fixed. So we hash - // the def-ids and then sort them and hash the collection. - let mut candidates: AccumulateVec<[_; 8]> = - traits.iter() - .map(|&hir::TraitCandidate { def_id, import_id: _ }| { - hcx.def_path_hash(def_id) - }) - .collect(); - if traits.len() > 1 { - candidates.sort(); - } - candidates.hash_stable(hcx, hasher); - } + hcx.tcx.hir.node_to_hir_id(*self).hash_stable(hcx, hasher); } } } } +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId { + type KeyType = (DefPathHash, hir::ItemLocalId); + + #[inline] + fn to_stable_hash_key(&self, + hcx: &StableHashingContext<'a, 'gcx, 'tcx>) + -> (DefPathHash, hir::ItemLocalId) { + hcx.tcx.hir.node_to_hir_id(*self).to_stable_hash_key(hcx) + } +} + impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Span { // Hash a span in a stable way. We can't directly hash the span's BytePos diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs index dad5c35c1e814..057a83ebbe352 100644 --- a/src/librustc/ich/impls_cstore.rs +++ b/src/librustc/ich/impls_cstore.rs @@ -45,3 +45,9 @@ impl_stable_hash_for!(struct middle::cstore::ExternCrate { direct, path_len }); + +impl_stable_hash_for!(struct middle::cstore::CrateSource { + dylib, + rlib, + rmeta +}); diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index a4cbcf0411199..9da147472ce4e 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -12,13 +12,13 @@ //! types in no particular order. use hir; +use hir::map::DefPathHash; use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; -use ich::{self, StableHashingContext, NodeIdHashingMode}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use ich::{StableHashingContext, NodeIdHashingMode}; +use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, + StableHasher, StableHasherResult}; use std::mem; use syntax::ast; -use util::nodemap::DefIdSet; impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefId { #[inline] @@ -29,14 +29,12 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefId } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefIdSet -{ - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>) { - ich::hash_stable_hashset(hcx, hasher, self, |hcx, def_id| { - hcx.def_path_hash(*def_id) - }); +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for DefId { + type KeyType = DefPathHash; + + #[inline] + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { + hcx.tcx().def_path_hash(*self) } } @@ -50,11 +48,22 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::H local_id, } = *self; - hcx.def_path_hash(DefId::local(owner)).hash_stable(hcx, hasher); + hcx.tcx().hir.definitions().def_path_hash(owner).hash_stable(hcx, hasher); local_id.hash_stable(hcx, hasher); } } +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { + type KeyType = (DefPathHash, hir::ItemLocalId); + + #[inline] + fn to_stable_hash_key(&self, + hcx: &StableHashingContext<'a, 'gcx, 'tcx>) + -> (DefPathHash, hir::ItemLocalId) { + let def_path_hash = hcx.tcx().hir.definitions().def_path_hash(self.owner); + (def_path_hash, self.local_id) + } +} impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum { #[inline] @@ -68,8 +77,30 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateN } } +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum { + type KeyType = DefPathHash; + + #[inline] + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { + let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX }; + def_id.to_stable_hash_key(hcx) + } +} + impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index }); +impl<'a, 'gcx, 'lcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'lcx>> +for hir::ItemLocalId { + type KeyType = hir::ItemLocalId; + + #[inline] + fn to_stable_hash_key(&self, + _: &StableHashingContext<'a, 'gcx, 'lcx>) + -> hir::ItemLocalId { + *self + } +} + // The following implementations of HashStable for ItemId, TraitItemId, and // ImplItemId deserve special attention. Normally we do not hash NodeIds within // the HIR, since they just signify a HIR nodes own path. But ItemId et al @@ -231,36 +262,13 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::T fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { - let node_id_hashing_mode = match self.node { - hir::TySlice(..) | - hir::TyArray(..) | - hir::TyPtr(..) | - hir::TyRptr(..) | - hir::TyBareFn(..) | - hir::TyNever | - hir::TyTup(..) | - hir::TyTraitObject(..) | - hir::TyImplTrait(..) | - hir::TyTypeof(..) | - hir::TyErr | - hir::TyInfer => { - NodeIdHashingMode::CheckedIgnore - } - hir::TyPath(..) => { - NodeIdHashingMode::HashTraitsInScope - } - }; - hcx.while_hashing_hir_bodies(true, |hcx| { let hir::Ty { - id, + id: _, ref node, ref span, } = *self; - hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| { - id.hash_stable(hcx, hasher); - }); node.hash_stable(hcx, hasher); span.hash_stable(hcx, hasher); }) @@ -317,13 +325,11 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::T hasher: &mut StableHasher<W>) { let hir::TraitRef { ref path, - ref_id, + // Don't hash the ref_id. It is tracked via the thing it is used to access + ref_id: _, } = *self; path.hash_stable(hcx, hasher); - hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| { - ref_id.hash_stable(hcx, hasher); - }); } } @@ -357,7 +363,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B let hir::Block { ref stmts, ref expr, - id, + id: _, hir_id: _, rules, span, @@ -392,7 +398,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B } expr.hash_stable(hcx, hasher); - id.hash_stable(hcx, hasher); rules.hash_stable(hcx, hasher); span.hash_stable(hcx, hasher); targeted_by_break.hash_stable(hcx, hasher); @@ -403,34 +408,13 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::P fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { - let node_id_hashing_mode = match self.node { - hir::PatKind::Wild | - hir::PatKind::Binding(..) | - hir::PatKind::Tuple(..) | - hir::PatKind::Box(..) | - hir::PatKind::Ref(..) | - hir::PatKind::Lit(..) | - hir::PatKind::Range(..) | - hir::PatKind::Slice(..) => { - NodeIdHashingMode::CheckedIgnore - } - hir::PatKind::Path(..) | - hir::PatKind::Struct(..) | - hir::PatKind::TupleStruct(..) => { - NodeIdHashingMode::HashTraitsInScope - } - }; - let hir::Pat { - id, + id: _, hir_id: _, ref node, ref span } = *self; - hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| { - id.hash_stable(hcx, hasher); - }); node.hash_stable(hcx, hasher); span.hash_stable(hcx, hasher); } @@ -552,14 +536,14 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E hasher: &mut StableHasher<W>) { hcx.while_hashing_hir_bodies(true, |hcx| { let hir::Expr { - id, + id: _, hir_id: _, ref span, ref node, ref attrs } = *self; - let (spans_always_on, node_id_hashing_mode) = match *node { + let spans_always_on = match *node { hir::ExprBox(..) | hir::ExprArray(..) | hir::ExprCall(..) | @@ -578,41 +562,33 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E hir::ExprBreak(..) | hir::ExprAgain(..) | hir::ExprRet(..) | - hir::ExprYield(..) | + hir::ExprYield(..) | hir::ExprInlineAsm(..) | hir::ExprRepeat(..) | - hir::ExprTup(..) => { + hir::ExprTup(..) | + hir::ExprMethodCall(..) | + hir::ExprPath(..) | + hir::ExprStruct(..) | + hir::ExprField(..) => { // For these we only hash the span when debuginfo is on. - (false, NodeIdHashingMode::CheckedIgnore) + false } // For the following, spans might be significant because of // panic messages indicating the source location. hir::ExprBinary(op, ..) => { - (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::CheckedIgnore) + hcx.binop_can_panic_at_runtime(op.node) } hir::ExprUnary(op, _) => { - (hcx.unop_can_panic_at_runtime(op), NodeIdHashingMode::CheckedIgnore) + hcx.unop_can_panic_at_runtime(op) } hir::ExprAssignOp(op, ..) => { - (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::CheckedIgnore) + hcx.binop_can_panic_at_runtime(op.node) } hir::ExprIndex(..) => { - (true, NodeIdHashingMode::CheckedIgnore) - } - // For these we don't care about the span, but want to hash the - // trait in scope - hir::ExprMethodCall(..) | - hir::ExprPath(..) | - hir::ExprStruct(..) | - hir::ExprField(..) => { - (false, NodeIdHashingMode::HashTraitsInScope) + true } }; - hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| { - id.hash_stable(hcx, hasher); - }); - if spans_always_on { hcx.while_hashing_spans(true, |hcx| { span.hash_stable(hcx, hasher); @@ -815,7 +791,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::V // No fields to hash. } hir::Visibility::Restricted { ref path, id } => { - hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| { + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { id.hash_stable(hcx, hasher); }); path.hash_stable(hcx, hasher); @@ -904,16 +880,13 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { - let (node_id_hashing_mode, hash_spans) = match self.node { + let hash_spans = match self.node { hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => { - (NodeIdHashingMode::CheckedIgnore, hcx.hash_spans()) + hcx.hash_spans() } - hir::ItemUse(..) => { - (NodeIdHashingMode::HashTraitsInScope, false) - } - + hir::ItemUse(..) | hir::ItemExternCrate(..) | hir::ItemForeignMod(..) | hir::ItemGlobalAsm(..) | @@ -925,14 +898,14 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) => { - (NodeIdHashingMode::CheckedIgnore, false) + false } }; let hir::Item { name, ref attrs, - id, + id: _, hir_id: _, ref node, ref vis, @@ -941,9 +914,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I hcx.hash_hir_item_like(attrs, |hcx| { hcx.while_hashing_spans(hash_spans, |hcx| { - hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| { - id.hash_stable(hcx, hasher); - }); name.hash_stable(hcx, hasher); attrs.hash_stable(hcx, hasher); node.hash_stable(hcx, hasher); @@ -1049,6 +1019,18 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B } } +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId { + type KeyType = (DefPathHash, hir::ItemLocalId); + + #[inline] + fn to_stable_hash_key(&self, + hcx: &StableHashingContext<'a, 'gcx, 'tcx>) + -> (DefPathHash, hir::ItemLocalId) { + let hir::BodyId { node_id } = *self; + node_id.to_stable_hash_key(hcx) + } +} + impl_stable_hash_for!(struct hir::InlineAsmOutput { constraint, is_rw, @@ -1151,7 +1133,17 @@ for hir::def_id::DefIndex { fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { - DefId::local(*self).hash_stable(hcx, hasher); + hcx.tcx().hir.definitions().def_path_hash(*self).hash_stable(hcx, hasher); + } +} + +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> +for hir::def_id::DefIndex { + type KeyType = DefPathHash; + + #[inline] + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { + hcx.tcx().hir.definitions().def_path_hash(*self) } } @@ -1170,6 +1162,11 @@ for ::middle::lang_items::LangItem { } } +impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems { + items, + missing +}); + impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::TraitCandidate { fn hash_stable<W: StableHasherResult>(&self, @@ -1186,3 +1183,8 @@ for hir::TraitCandidate { }); } } + +impl_stable_hash_for!(struct hir::Freevar { + def, + span +}); diff --git a/src/librustc/ich/impls_misc.rs b/src/librustc/ich/impls_misc.rs new file mode 100644 index 0000000000000..951315fb4a849 --- /dev/null +++ b/src/librustc/ich/impls_misc.rs @@ -0,0 +1,26 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This module contains `HashStable` implementations for various data types +//! that don't fit into any of the other impls_xxx modules. + +impl_stable_hash_for!(enum ::session::search_paths::PathKind { + Native, + Crate, + Dependency, + Framework, + ExternFlag, + All +}); + +impl_stable_hash_for!(enum ::rustc_back::PanicStrategy { + Abort, + Unwind +}); diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index e52be70190c81..a75527c14bd69 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -18,17 +18,17 @@ use std::mem; use syntax::ast; use syntax::parse::token; +use syntax::symbol::InternedString; use syntax::tokenstream; use syntax_pos::{Span, FileMap}; use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, + StableHasher, StableHasherResult}; use rustc_data_structures::accumulate_vec::AccumulateVec; -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> -for ::syntax::symbol::InternedString { +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for InternedString { #[inline] fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, @@ -38,6 +38,17 @@ for ::syntax::symbol::InternedString { } } +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for InternedString { + type KeyType = InternedString; + + #[inline] + fn to_stable_hash_key(&self, + _: &StableHashingContext<'a, 'gcx, 'tcx>) + -> InternedString { + self.clone() + } +} + impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Name { #[inline] fn hash_stable<W: StableHasherResult>(&self, @@ -47,6 +58,17 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::N } } +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Name { + type KeyType = InternedString; + + #[inline] + fn to_stable_hash_key(&self, + _: &StableHashingContext<'a, 'gcx, 'tcx>) + -> InternedString { + self.as_str() + } +} + impl_stable_hash_for!(enum ::syntax::ast::AsmDialect { Att, Intel diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index c24064eb27c58..5558534b71d2e 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -24,6 +24,7 @@ mod impls_const_math; mod impls_cstore; mod impls_hir; mod impls_mir; +mod impls_misc; mod impls_ty; mod impls_syntax; diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index bea6ef4dc11ce..7c60c6d6430e1 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -132,7 +132,7 @@ pub struct NativeLibrary { pub kind: NativeLibraryKind, pub name: Symbol, pub cfg: Option<ast::MetaItem>, - pub foreign_items: Vec<DefIndex>, + pub foreign_items: Vec<DefId>, } pub enum LoadedMacro { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 7a6f4fdbb03ac..0c0b9697338e9 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -192,8 +192,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> { pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LanguageItems { let mut collector = LanguageItemCollector::new(tcx); for &cnum in tcx.crates().iter() { - for &(index, item_index) in tcx.defined_lang_items(cnum).iter() { - let def_id = DefId { krate: cnum, index: index }; + for &(def_id, item_index) in tcx.defined_lang_items(cnum).iter() { collector.collect_item(item_index, def_id); } } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 977102ec1adca..89049958309a1 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -65,6 +65,11 @@ pub struct DeprecationEntry { origin: Option<HirId>, } +impl_stable_hash_for!(struct self::DeprecationEntry { + attr, + origin +}); + impl DeprecationEntry { fn local(attr: Deprecation, id: HirId) -> DeprecationEntry { DeprecationEntry { @@ -102,6 +107,13 @@ pub struct Index<'tcx> { active_features: FxHashSet<Symbol>, } +impl_stable_hash_for!(struct self::Index<'tcx> { + stab_map, + depr_map, + staged_api, + active_features +}); + // A private tree-walker for producing an Index. struct Annotator<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 945a081442750..7edc55e8a9fe4 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1083,6 +1083,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { None }; + // FIXME(mw): Each of the Vecs in the trait_map should be brought into + // a deterministic order here. Otherwise we might end up with + // unnecessarily unstable incr. comp. hashes. let mut trait_map = FxHashMap(); for (k, v) in resolutions.trait_map { let hir_id = hir.node_to_hir_id(k); @@ -1171,17 +1174,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn lang_items(self) -> Rc<middle::lang_items::LanguageItems> { - // FIXME(#42293) Right now we insert a `with_ignore` node in the dep - // graph here to ignore the fact that `get_lang_items` below depends on - // the entire crate. For now this'll prevent false positives of - // recompiling too much when anything changes. - // - // Once red/green incremental compilation lands we should be able to - // remove this because while the crate changes often the lint level map - // will change rarely. - self.dep_graph.with_ignore(|| { - self.get_lang_items(LOCAL_CRATE) - }) + self.get_lang_items(LOCAL_CRATE) } pub fn stability(self) -> Rc<stability::Index<'tcx>> { @@ -2198,7 +2191,15 @@ pub fn provide(providers: &mut ty::maps::Providers) { }; providers.get_lang_items = |tcx, id| { assert_eq!(id, LOCAL_CRATE); - Rc::new(middle::lang_items::collect(tcx)) + // FIXME(#42293) Right now we insert a `with_ignore` node in the dep + // graph here to ignore the fact that `get_lang_items` below depends on + // the entire crate. For now this'll prevent false positives of + // recompiling too much when anything changes. + // + // Once red/green incremental compilation lands we should be able to + // remove this because while the crate changes often the lint level map + // will change rarely. + tcx.dep_graph.with_ignore(|| Rc::new(middle::lang_items::collect(tcx))) }; providers.freevars = |tcx, id| tcx.gcx.freevars.get(&id).cloned(); providers.maybe_unused_trait_import = |tcx, id| { diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index c96ae862265df..fc803d1c849b5 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -1400,7 +1400,7 @@ define_maps! { <'tcx> [] fn extern_mod_stmt_cnum: ExternModStmtCnum(DefId) -> Option<CrateNum>, [] fn get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>, - [] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefIndex, usize)>>, + [] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefId, usize)>>, [] fn missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>, [] fn extern_const_body: ExternConstBody(DefId) -> &'tcx hir::Body, [] fn visible_parent_map: visible_parent_map_node(CrateNum) diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index f80cbfadf2e7f..1b2d09bef934c 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::hash::{Hash, Hasher}; +use std::hash::{Hash, Hasher, BuildHasher}; use std::marker::PhantomData; use std::mem; use blake2b::Blake2bHasher; @@ -222,6 +222,14 @@ pub trait HashStable<CTX> { hasher: &mut StableHasher<W>); } +/// Implement this for types that can be turned into stable keys like, for +/// example, for DefId that can be converted to a DefPathHash. This is used for +/// bringing maps into a predictable order before hashing them. +pub trait ToStableHashKey<HCX> { + type KeyType: Ord + Clone + Sized + HashStable<HCX>; + fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType; +} + // Implement HashStable by just calling `Hash::hash()`. This works fine for // self-contained values that don't depend on the hashing context `CTX`. macro_rules! impl_stable_hash_via_hash { @@ -423,53 +431,88 @@ impl<T, CTX> HashStable<CTX> for ::std::mem::Discriminant<T> { } } -impl<K, V, CTX> HashStable<CTX> for ::std::collections::BTreeMap<K, V> - where K: Ord + HashStable<CTX>, - V: HashStable<CTX>, +impl<I: ::indexed_vec::Idx, T, CTX> HashStable<CTX> for ::indexed_vec::IndexVec<I, T> + where T: HashStable<CTX>, { fn hash_stable<W: StableHasherResult>(&self, ctx: &mut CTX, hasher: &mut StableHasher<W>) { self.len().hash_stable(ctx, hasher); - for (k, v) in self { - k.hash_stable(ctx, hasher); + for v in &self.raw { v.hash_stable(ctx, hasher); } } } -impl<T, CTX> HashStable<CTX> for ::std::collections::BTreeSet<T> - where T: Ord + HashStable<CTX>, + +impl<I: ::indexed_vec::Idx, CTX> HashStable<CTX> for ::indexed_set::IdxSetBuf<I> { fn hash_stable<W: StableHasherResult>(&self, ctx: &mut CTX, hasher: &mut StableHasher<W>) { - self.len().hash_stable(ctx, hasher); - for v in self { - v.hash_stable(ctx, hasher); - } + self.words().hash_stable(ctx, hasher); } } -impl<I: ::indexed_vec::Idx, T, CTX> HashStable<CTX> for ::indexed_vec::IndexVec<I, T> - where T: HashStable<CTX>, +impl_stable_hash_via_hash!(::std::path::Path); +impl_stable_hash_via_hash!(::std::path::PathBuf); + +impl<K, V, R, HCX> HashStable<HCX> for ::std::collections::HashMap<K, V, R> + where K: ToStableHashKey<HCX> + Eq + Hash, + V: HashStable<HCX>, + R: BuildHasher, { fn hash_stable<W: StableHasherResult>(&self, - ctx: &mut CTX, + hcx: &mut HCX, hasher: &mut StableHasher<W>) { - self.len().hash_stable(ctx, hasher); - for v in &self.raw { - v.hash_stable(ctx, hasher); - } + let mut entries: Vec<_> = self.iter() + .map(|(k, v)| (k.to_stable_hash_key(hcx), v)) + .collect(); + entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); + entries.hash_stable(hcx, hasher); } } +impl<K, R, HCX> HashStable<HCX> for ::std::collections::HashSet<K, R> + where K: ToStableHashKey<HCX> + Eq + Hash, + R: BuildHasher, +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut HCX, + hasher: &mut StableHasher<W>) { + let mut keys: Vec<_> = self.iter() + .map(|k| k.to_stable_hash_key(hcx)) + .collect(); + keys.sort_unstable(); + keys.hash_stable(hcx, hasher); + } +} -impl<I: ::indexed_vec::Idx, CTX> HashStable<CTX> for ::indexed_set::IdxSetBuf<I> +impl<K, V, HCX> HashStable<HCX> for ::std::collections::BTreeMap<K, V> + where K: ToStableHashKey<HCX>, + V: HashStable<HCX>, { fn hash_stable<W: StableHasherResult>(&self, - ctx: &mut CTX, + hcx: &mut HCX, hasher: &mut StableHasher<W>) { - self.words().hash_stable(ctx, hasher); + let mut entries: Vec<_> = self.iter() + .map(|(k, v)| (k.to_stable_hash_key(hcx), v)) + .collect(); + entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); + entries.hash_stable(hcx, hasher); + } +} + +impl<K, HCX> HashStable<HCX> for ::std::collections::BTreeSet<K> + where K: ToStableHashKey<HCX>, +{ + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut HCX, + hasher: &mut StableHasher<W>) { + let mut keys: Vec<_> = self.iter() + .map(|k| k.to_stable_hash_key(hcx)) + .collect(); + keys.sort_unstable(); + keys.hash_stable(hcx, hasher); } } diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 94400890c5641..d8e201d3acdcf 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -31,7 +31,7 @@ use std::cell::RefCell; use std::hash::Hash; use rustc::dep_graph::{DepNode, DepKind}; use rustc::hir; -use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; use rustc::hir::map::DefPathHash; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ich::{Fingerprint, StableHashingContext}; @@ -96,7 +96,7 @@ struct ComputeItemHashesVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { fn compute_and_store_ich_for_item_like<T>(&mut self, - dep_node: DepNode, + def_index: DefIndex, hash_bodies: bool, item_like: T) where T: HashStable<StableHashingContext<'a, 'tcx, 'tcx>> @@ -108,6 +108,8 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { return } + let def_path_hash = self.hcx.tcx().hir.definitions().def_path_hash(def_index); + let mut hasher = IchHasher::new(); self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| { item_like.hash_stable(hcx, &mut hasher); @@ -115,6 +117,11 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { let bytes_hashed = hasher.bytes_hashed(); let item_hash = hasher.finish(); + let dep_node = if hash_bodies { + def_path_hash.to_dep_node(DepKind::HirBody) + } else { + def_path_hash.to_dep_node(DepKind::Hir) + }; debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash); self.hashes.insert(dep_node, item_hash); @@ -123,6 +130,14 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { tcx.sess.perf_stats.incr_comp_bytes_hashed.get() + bytes_hashed; tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed); + + if hash_bodies { + let in_scope_traits_map = tcx.in_scope_traits_map(def_index); + let mut hasher = IchHasher::new(); + in_scope_traits_map.hash_stable(&mut self.hcx, &mut hasher); + let dep_node = def_path_hash.to_dep_node(DepKind::InScopeTraits); + self.hashes.insert(dep_node, hasher.finish()); + } } fn compute_crate_hash(&mut self) { @@ -145,6 +160,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { // This `match` determines what kinds of nodes // go into the SVH: match item_dep_node.kind { + DepKind::InScopeTraits | DepKind::Hir | DepKind::HirBody => { // We want to incoporate these into the @@ -195,11 +211,10 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { body_ids: _, } = *krate; - let def_path_hash = self.hcx.tcx().hir.definitions().def_path_hash(CRATE_DEF_INDEX); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir), + self.compute_and_store_ich_for_item_like(CRATE_DEF_INDEX, false, (module, (span, attrs))); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody), + self.compute_and_store_ich_for_item_like(CRATE_DEF_INDEX, true, (module, (span, attrs))); } @@ -251,34 +266,31 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { - let def_id = self.hcx.tcx().hir.local_def_id(item.id); - let def_path_hash = self.hcx.tcx().def_path_hash(def_id); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir), + let def_index = self.hcx.tcx().hir.local_def_id(item.id).index; + self.compute_and_store_ich_for_item_like(def_index, false, item); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody), + self.compute_and_store_ich_for_item_like(def_index, true, item); } fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) { - let def_id = self.hcx.tcx().hir.local_def_id(item.id); - let def_path_hash = self.hcx.tcx().def_path_hash(def_id); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir), + let def_index = self.hcx.tcx().hir.local_def_id(item.id).index; + self.compute_and_store_ich_for_item_like(def_index, false, item); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody), + self.compute_and_store_ich_for_item_like(def_index, true, item); } fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) { - let def_id = self.hcx.tcx().hir.local_def_id(item.id); - let def_path_hash = self.hcx.tcx().def_path_hash(def_id); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir), + let def_index = self.hcx.tcx().hir.local_def_id(item.id).index; + self.compute_and_store_ich_for_item_like(def_index, false, item); - self.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody), + self.compute_and_store_ich_for_item_like(def_index, true, item); } @@ -301,12 +313,11 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) krate.visit_all_item_likes(&mut visitor); for macro_def in krate.exported_macros.iter() { - let def_id = tcx.hir.local_def_id(macro_def.id); - let def_path_hash = tcx.def_path_hash(def_id); - visitor.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::Hir), + let def_index = tcx.hir.local_def_id(macro_def.id).index; + visitor.compute_and_store_ich_for_item_like(def_index, false, macro_def); - visitor.compute_and_store_ich_for_item_like(def_path_hash.to_dep_node(DepKind::HirBody), + visitor.compute_and_store_ich_for_item_like(def_index, true, macro_def); } diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs index 44d6788c77365..8355f31913938 100644 --- a/src/librustc_incremental/persist/hash.rs +++ b/src/librustc_incremental/persist/hash.rs @@ -49,6 +49,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { match dep_node.kind { DepKind::Krate | DepKind::Hir | + DepKind::InScopeTraits | DepKind::HirBody => true, DepKind::MetaData => { @@ -66,6 +67,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { } // HIR nodes (which always come from our crate) are an input: + DepKind::InScopeTraits | DepKind::Hir | DepKind::HirBody => { Some(self.incremental_hashes_map[dep_node]) diff --git a/src/librustc_incremental/persist/load.rs b/src/librustc_incremental/persist/load.rs index ba638289fdf03..9865ea8c2856a 100644 --- a/src/librustc_incremental/persist/load.rs +++ b/src/librustc_incremental/persist/load.rs @@ -104,6 +104,7 @@ fn does_still_exist(tcx: TyCtxt, dep_node: &DepNode) -> bool { match dep_node.kind { DepKind::Hir | DepKind::HirBody | + DepKind::InScopeTraits | DepKind::MetaData => { dep_node.extract_def_id(tcx).is_some() } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index dc6c260ec7174..39bdf88925e44 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -301,7 +301,10 @@ impl<'a> CrateLoader<'a> { .decode(&cmeta) .filter(|lib| relevant_lib(self.sess, lib) && lib.kind == cstore::NativeLibraryKind::NativeUnknown) - .flat_map(|lib| lib.foreign_items.into_iter()) + .flat_map(|lib| { + assert!(lib.foreign_items.iter().all(|def_id| def_id.krate == cnum)); + lib.foreign_items.into_iter().map(|def_id| def_id.index) + }) .collect(); cmeta.dllimport_foreign_items = dllimports; diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 3a116160bcab2..e4de27ee15e52 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -264,7 +264,7 @@ pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) { tcx.native_libraries(id.krate) .iter() .filter(|lib| native_libs::relevant_lib(&tcx.sess, lib)) - .find(|l| l.foreign_items.contains(&id.index)) + .find(|l| l.foreign_items.contains(&id)) .map(|l| l.kind) }, native_libraries: |tcx, cnum| { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 1c4f1c6348689..4696759817fcb 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -659,10 +659,11 @@ impl<'a, 'tcx> CrateMetadata { } /// Iterates over the language items in the given crate. - pub fn get_lang_items(&self) -> Vec<(DefIndex, usize)> { + pub fn get_lang_items(&self) -> Vec<(DefId, usize)> { self.root .lang_items .decode(self) + .map(|(def_index, index)| (self.local_def_id(def_index), index)) .collect() } diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 669681d2aadde..cc332acb5b08e 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -96,7 +96,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for Collector<'a, 'tcx> { list[0].meta_item().unwrap().clone() }); let foreign_items = fm.items.iter() - .map(|it| self.tcx.hir.local_def_id(it.id).index) + .map(|it| self.tcx.hir.local_def_id(it.id)) .collect(); let lib = NativeLibrary { name: n, diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 6ed928ca09deb..dc18cdd8f0dd6 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -15,8 +15,7 @@ //! "types-as-contracts"-validation, namely, AcquireValid, ReleaseValid, and EndRegion. use rustc::ty::subst::Substs; -use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts}; -use rustc::middle::const_val::ConstVal; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::mir::*; use rustc::mir::visit::{MutVisitor, Lookup}; use rustc::mir::transform::{MirPass, MirSource}; @@ -80,45 +79,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> { self.super_statement(block, statement, location); self.in_validation_statement = false; } - - fn visit_const_val(&mut self, - const_val: &mut ConstVal<'tcx>, - _: Location) { - erase_const_val(self.tcx, const_val); - self.super_const_val(const_val); - - fn erase_const_val<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - const_val: &mut ConstVal<'tcx>) { - match *const_val { - ConstVal::Float(_) | - ConstVal::Integral(_) | - ConstVal::Str(_) | - ConstVal::ByteStr(_) | - ConstVal::Bool(_) | - ConstVal::Char(_) | - ConstVal::Variant(_) => { - // nothing to do - } - ConstVal::Function(_, ref mut substs) => { - *substs = tcx.erase_regions(&{*substs}); - } - ConstVal::Struct(ref mut field_map) => { - for (_, field_val) in field_map { - erase_const_val(tcx, field_val); - } - } - ConstVal::Tuple(ref mut fields) | - ConstVal::Array(ref mut fields) => { - for field_val in fields { - erase_const_val(tcx, field_val); - } - } - ConstVal::Repeat(ref mut expr, _) => { - erase_const_val(tcx, &mut **expr); - } - } - } - } } pub struct EraseRegions; diff --git a/src/test/incremental/ich_method_call_trait_scope.rs b/src/test/incremental/ich_method_call_trait_scope.rs index 0a36e3c693edb..7f4e2b0f17652 100644 --- a/src/test/incremental/ich_method_call_trait_scope.rs +++ b/src/test/incremental/ich_method_call_trait_scope.rs @@ -12,6 +12,7 @@ // scope. // revisions: rpass1 rpass2 +// compile-flags: -Z query-dep-graph #![feature(rustc_attrs)] @@ -47,13 +48,15 @@ mod mod3 { use Trait2; #[rustc_clean(label="Hir", cfg="rpass2")] - #[rustc_dirty(label="HirBody", cfg="rpass2")] + #[rustc_clean(label="HirBody", cfg="rpass2")] + #[rustc_dirty(label="TypeckTables", cfg="rpass2")] fn bar() { ().method(); } #[rustc_clean(label="Hir", cfg="rpass2")] #[rustc_clean(label="HirBody", cfg="rpass2")] + #[rustc_clean(label="TypeckTables", cfg="rpass2")] fn baz() { 22; // no method call, traits in scope don't matter } From b9816c5fab6bfde01f83d83a0b53e78bb00d3900 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Wed, 13 Sep 2017 14:59:10 +0200 Subject: [PATCH 16/24] incr.comp.: Already hash HIR bodies during metadata export so they don't have to be hashed in downstream crates. --- src/librustc/ich/hcx.rs | 34 +++++++++++++++++++ src/librustc/ich/impls_cstore.rs | 28 ++++++++++++++++ src/librustc/ich/impls_hir.rs | 50 ++++++++++------------------ src/librustc/middle/cstore.rs | 22 ++++++++++++ src/librustc/ty/maps.rs | 11 +++--- src/librustc_const_eval/eval.rs | 5 ++- src/librustc_const_eval/pattern.rs | 2 +- src/librustc_metadata/astencode.rs | 25 ++++++++++++-- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/decoder.rs | 35 ++++++++++++++----- src/librustdoc/clean/inline.rs | 4 +-- 11 files changed, 163 insertions(+), 55 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index daf1ff8ad2b95..bd3a35836762b 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -202,6 +202,40 @@ impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx> } } +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { + #[inline] + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + match hcx.node_id_hashing_mode { + NodeIdHashingMode::Ignore => { + // Don't do anything. + } + NodeIdHashingMode::HashDefPath => { + let hir::HirId { + owner, + local_id, + } = *self; + + hcx.tcx.hir.definitions().def_path_hash(owner).hash_stable(hcx, hasher); + local_id.hash_stable(hcx, hasher); + } + } + } +} + +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { + type KeyType = (DefPathHash, hir::ItemLocalId); + + #[inline] + fn to_stable_hash_key(&self, + hcx: &StableHashingContext<'a, 'gcx, 'tcx>) + -> (DefPathHash, hir::ItemLocalId) { + let def_path_hash = hcx.tcx().hir.definitions().def_path_hash(self.owner); + (def_path_hash, self.local_id) + } +} + impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId { fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, diff --git a/src/librustc/ich/impls_cstore.rs b/src/librustc/ich/impls_cstore.rs index 057a83ebbe352..18a02ff5c5882 100644 --- a/src/librustc/ich/impls_cstore.rs +++ b/src/librustc/ich/impls_cstore.rs @@ -11,6 +11,8 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::middle::cstore in no particular order. +use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; + use middle; impl_stable_hash_for!(enum middle::cstore::DepKind { @@ -51,3 +53,29 @@ impl_stable_hash_for!(struct middle::cstore::CrateSource { rlib, rmeta }); + +impl<HCX> HashStable<HCX> for middle::cstore::ExternBodyNestedBodies { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut HCX, + hasher: &mut StableHasher<W>) { + let middle::cstore::ExternBodyNestedBodies { + nested_bodies: _, + fingerprint, + } = *self; + + fingerprint.hash_stable(hcx, hasher); + } +} + +impl<'a, HCX> HashStable<HCX> for middle::cstore::ExternConstBody<'a> { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut HCX, + hasher: &mut StableHasher<W>) { + let middle::cstore::ExternConstBody { + body: _, + fingerprint, + } = *self; + + fingerprint.hash_stable(hcx, hasher); + } +} diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 9da147472ce4e..3c89e10a0d2d9 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -38,33 +38,6 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for D } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { - #[inline] - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>) { - let hir::HirId { - owner, - local_id, - } = *self; - - hcx.tcx().hir.definitions().def_path_hash(owner).hash_stable(hcx, hasher); - local_id.hash_stable(hcx, hasher); - } -} - -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { - type KeyType = (DefPathHash, hir::ItemLocalId); - - #[inline] - fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a, 'gcx, 'tcx>) - -> (DefPathHash, hir::ItemLocalId) { - let def_path_hash = hcx.tcx().hir.definitions().def_path_hash(self.owner); - (def_path_hash, self.local_id) - } -} - impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum { #[inline] fn hash_stable<W: StableHasherResult>(&self, @@ -415,6 +388,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::P ref span } = *self; + node.hash_stable(hcx, hasher); span.hash_stable(hcx, hasher); } @@ -1003,11 +977,23 @@ impl_stable_hash_for!(struct hir::Arg { hir_id }); -impl_stable_hash_for!(struct hir::Body { - arguments, - value, - is_generator -}); +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Body { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + let hir::Body { + ref arguments, + ref value, + is_generator, + } = *self; + + hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| { + arguments.hash_stable(hcx, hasher); + value.hash_stable(hcx, hasher); + is_generator.hash_stable(hcx, hasher); + }); + } +} impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId { fn hash_stable<W: StableHasherResult>(&self, diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 7c60c6d6430e1..de647913f0f3b 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -22,6 +22,7 @@ //! are *mostly* used as a part of that interface, but these should //! probably get a better home if someone can find one. +use hir; use hir::def; use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use hir::map as hir_map; @@ -34,6 +35,7 @@ use session::search_paths::PathKind; use util::nodemap::NodeSet; use std::any::Any; +use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use std::rc::Rc; use owning_ref::ErasedBoxRef; @@ -218,6 +220,26 @@ pub trait MetadataLoader { -> Result<ErasedBoxRef<[u8]>, String>; } +#[derive(Clone)] +pub struct ExternConstBody<'tcx> { + pub body: &'tcx hir::Body, + + // It would require a lot of infrastructure to enable stable-hashing Bodies + // from other crates, so we hash on export and just store the fingerprint + // with them. + pub fingerprint: ich::Fingerprint, +} + +#[derive(Clone)] +pub struct ExternBodyNestedBodies { + pub nested_bodies: Rc<BTreeMap<hir::BodyId, hir::Body>>, + + // It would require a lot of infrastructure to enable stable-hashing Bodies + // from other crates, so we hash on export and just store the fingerprint + // with them. + pub fingerprint: ich::Fingerprint, +} + /// A store of Rust crates, through with their metadata /// can be accessed. /// diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index fc803d1c849b5..5207aaa0c5b2f 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -16,8 +16,9 @@ use hir::{self, TraitCandidate, ItemLocalId}; use hir::svh::Svh; use lint; use middle::const_val; -use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary}; -use middle::cstore::{NativeLibraryKind, DepKind, CrateSource}; +use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary, + ExternBodyNestedBodies}; +use middle::cstore::{NativeLibraryKind, DepKind, CrateSource, ExternConstBody}; use middle::privacy::AccessLevels; use middle::reachable::ReachableSet; use middle::region; @@ -50,7 +51,6 @@ use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; use std::mem; -use std::collections::BTreeMap; use std::ops::Deref; use std::rc::Rc; use std::sync::Arc; @@ -1321,8 +1321,7 @@ define_maps! { <'tcx> [] fn impl_parent: ImplParent(DefId) -> Option<DefId>, [] fn trait_of_item: TraitOfItem(DefId) -> Option<DefId>, [] fn is_exported_symbol: IsExportedSymbol(DefId) -> bool, - [] fn item_body_nested_bodies: ItemBodyNestedBodies(DefId) - -> Rc<BTreeMap<hir::BodyId, hir::Body>>, + [] fn item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> ExternBodyNestedBodies, [] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool, [] fn is_mir_available: IsMirAvailable(DefId) -> bool, @@ -1402,7 +1401,7 @@ define_maps! { <'tcx> [] fn get_lang_items: get_lang_items_node(CrateNum) -> Rc<LanguageItems>, [] fn defined_lang_items: DefinedLangItems(CrateNum) -> Rc<Vec<(DefId, usize)>>, [] fn missing_lang_items: MissingLangItems(CrateNum) -> Rc<Vec<LangItem>>, - [] fn extern_const_body: ExternConstBody(DefId) -> &'tcx hir::Body, + [] fn extern_const_body: ExternConstBody(DefId) -> ExternConstBody<'tcx>, [] fn visible_parent_map: visible_parent_map_node(CrateNum) -> Rc<DefIdMap<DefId>>, [] fn missing_extern_crate_item: MissingExternCrateItem(CrateNum) -> bool, diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 61eb5dfd18b9c..7520c6ac652ba 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -34,7 +34,6 @@ use syntax_pos::Span; use std::cmp::Ordering; use rustc_const_math::*; - macro_rules! signal { ($e:expr, $exn:expr) => { return Err(ConstEvalErr { span: $e.span, kind: $exn }) @@ -366,7 +365,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>, } } else { if tcx.is_const_fn(def_id) { - tcx.extern_const_body(def_id) + tcx.extern_const_body(def_id).body } else { signal!(e, TypeckError) } @@ -790,7 +789,7 @@ fn const_eval<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.mir_const_qualif(def_id); tcx.hir.body(tcx.hir.body_owned_by(id)) } else { - tcx.extern_const_body(def_id) + tcx.extern_const_body(def_id).body }; ConstContext::new(tcx, key.param_env.and(substs), tables).eval(&body.value) } diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index a87fa0c2746a3..7586ad5a75f81 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -607,7 +607,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { let body = if let Some(id) = self.tcx.hir.as_local_node_id(def_id) { self.tcx.hir.body(self.tcx.hir.body_owned_by(id)) } else { - self.tcx.extern_const_body(def_id) + self.tcx.extern_const_body(def_id).body }; let pat = self.lower_const_expr(&body.value, pat_id, span); self.tables = old_tables; diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index ade2612855e02..3bc281e5486a8 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -16,26 +16,46 @@ use schema::*; use rustc::hir; use rustc::ty::{self, TyCtxt}; +use rustc::ich::{StableHashingContext, Fingerprint}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; + #[derive(RustcEncodable, RustcDecodable)] pub struct Ast<'tcx> { pub body: Lazy<hir::Body>, pub tables: Lazy<ty::TypeckTables<'tcx>>, pub nested_bodies: LazySeq<hir::Body>, pub rvalue_promotable_to_static: bool, + pub stable_bodies_hash: Fingerprint, } impl_stable_hash_for!(struct Ast<'tcx> { body, tables, nested_bodies, - rvalue_promotable_to_static + rvalue_promotable_to_static, + stable_bodies_hash }); impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> { pub fn encode_body(&mut self, body_id: hir::BodyId) -> Lazy<Ast<'tcx>> { let body = self.tcx.hir.body(body_id); - let lazy_body = self.lazy(body); + // In order to avoid having to hash hir::Bodies from extern crates, we + // hash them here, during export, and store the hash with metadata. + let stable_bodies_hash = { + let mut hcx = StableHashingContext::new(self.tcx); + let mut hasher = StableHasher::new(); + + hcx.while_hashing_hir_bodies(true, |hcx| { + hcx.while_hashing_spans(false, |hcx| { + body.hash_stable(hcx, &mut hasher); + }); + }); + + hasher.finish() + }; + + let lazy_body = self.lazy(body); let tables = self.tcx.body_tables(body_id); let lazy_tables = self.lazy(tables); @@ -54,6 +74,7 @@ impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> { tables: lazy_tables, nested_bodies: lazy_nested_bodies, rvalue_promotable_to_static, + stable_bodies_hash, }) } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index e4de27ee15e52..78c44c7e45cdf 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -159,7 +159,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, is_exported_symbol => { cdata.exported_symbols.contains(&def_id.index) } - item_body_nested_bodies => { Rc::new(cdata.item_body_nested_bodies(def_id.index)) } + item_body_nested_bodies => { cdata.item_body_nested_bodies(def_id.index) } const_is_rvalue_promotable_to_static => { cdata.const_is_rvalue_promotable_to_static(def_id.index) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 4696759817fcb..65cf15e5a0ec7 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -17,9 +17,11 @@ use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir; use rustc::middle::const_val::ByteArray; -use rustc::middle::cstore::LinkagePreference; +use rustc::middle::cstore::{LinkagePreference, ExternConstBody, + ExternBodyNestedBodies}; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc::ich::Fingerprint; use rustc::middle::lang_items; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; @@ -775,12 +777,16 @@ impl<'a, 'tcx> CrateMetadata { pub fn extern_const_body(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex) - -> &'tcx hir::Body { + -> ExternConstBody<'tcx> { assert!(!self.is_proc_macro(id)); let ast = self.entry(id).ast.unwrap(); let def_id = self.local_def_id(id); - let body = ast.decode((self, tcx)).body.decode((self, tcx)); - tcx.hir.intern_inlined_body(def_id, body) + let ast = ast.decode((self, tcx)); + let body = ast.body.decode((self, tcx)); + ExternConstBody { + body: tcx.hir.intern_inlined_body(def_id, body), + fingerprint: ast.stable_bodies_hash, + } } pub fn item_body_tables(&self, @@ -791,10 +797,23 @@ impl<'a, 'tcx> CrateMetadata { tcx.alloc_tables(ast.tables.decode((self, tcx))) } - pub fn item_body_nested_bodies(&self, id: DefIndex) -> BTreeMap<hir::BodyId, hir::Body> { - self.entry(id).ast.into_iter().flat_map(|ast| { - ast.decode(self).nested_bodies.decode(self).map(|body| (body.id(), body)) - }).collect() + pub fn item_body_nested_bodies(&self, id: DefIndex) -> ExternBodyNestedBodies { + if let Some(ref ast) = self.entry(id).ast { + let ast = ast.decode(self); + let nested_bodies: BTreeMap<_, _> = ast.nested_bodies + .decode(self) + .map(|body| (body.id(), body)) + .collect(); + ExternBodyNestedBodies { + nested_bodies: Rc::new(nested_bodies), + fingerprint: ast.stable_bodies_hash, + } + } else { + ExternBodyNestedBodies { + nested_bodies: Rc::new(BTreeMap::new()), + fingerprint: Fingerprint::zero(), + } + } } pub fn const_is_rvalue_promotable_to_static(&self, id: DefIndex) -> bool { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 7f5d11ba5de28..3a4dcc3217388 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -474,9 +474,9 @@ impl hir::print::PpAnn for InlinedConst { } pub fn print_inlined_const(cx: &DocContext, did: DefId) -> String { - let body = cx.tcx.extern_const_body(did); + let body = cx.tcx.extern_const_body(did).body; let inlined = InlinedConst { - nested_bodies: cx.tcx.item_body_nested_bodies(did) + nested_bodies: cx.tcx.item_body_nested_bodies(did).nested_bodies }; hir::print::to_string(&inlined, |s| s.print_expr(&body.value)) } From 67c84e05e72931587e5f81a297dee95bc149bcd8 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Wed, 13 Sep 2017 18:20:27 +0200 Subject: [PATCH 17/24] incr.comp.: Use StableHash impls instead of functions for hashing most maps. --- src/librustc/ich/hcx.rs | 108 +----------------- src/librustc/ich/impls_ty.rs | 83 +++++--------- src/librustc/ich/mod.rs | 4 +- src/librustc/lint/levels.rs | 31 ++--- src/librustc/middle/region.rs | 25 ++-- .../traits/specialize/specialization_graph.rs | 21 +--- src/librustc/ty/context.rs | 43 ++++--- src/librustc_data_structures/stable_hasher.rs | 50 ++++++-- 8 files changed, 118 insertions(+), 247 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index bd3a35836762b..0932c5ce8fb80 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -14,11 +14,10 @@ use hir::map::DefPathHash; use ich::{self, CachingCodemapView}; use session::config::DebugInfoLevel::NoDebugInfo; use ty::{self, TyCtxt, fast_reject}; -use util::nodemap::{NodeMap, NodeSet, ItemLocalMap}; use std::cmp::Ord; use std::hash as std_hash; -use std::collections::{HashMap, HashSet, BTreeMap}; +use std::collections::HashMap; use syntax::ast; use syntax::attr; @@ -337,111 +336,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Span { } } -pub fn hash_stable_hashmap<'a, 'gcx, 'tcx, K, V, R, SK, F, W>( - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>, - map: &HashMap<K, V, R>, - extract_stable_key: F) - where K: Eq + std_hash::Hash, - V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - R: std_hash::BuildHasher, - SK: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + Ord + Clone, - F: Fn(&mut StableHashingContext<'a, 'gcx, 'tcx>, &K) -> SK, - W: StableHasherResult, -{ - let mut keys: Vec<_> = map.keys() - .map(|k| (extract_stable_key(hcx, k), k)) - .collect(); - keys.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); - keys.len().hash_stable(hcx, hasher); - for (stable_key, key) in keys { - stable_key.hash_stable(hcx, hasher); - map[key].hash_stable(hcx, hasher); - } -} - -pub fn hash_stable_hashset<'a, 'tcx, 'gcx, K, R, SK, F, W>( - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>, - set: &HashSet<K, R>, - extract_stable_key: F) - where K: Eq + std_hash::Hash, - R: std_hash::BuildHasher, - SK: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + Ord + Clone, - F: Fn(&mut StableHashingContext<'a, 'gcx, 'tcx>, &K) -> SK, - W: StableHasherResult, -{ - let mut keys: Vec<_> = set.iter() - .map(|k| extract_stable_key(hcx, k)) - .collect(); - keys.sort_unstable(); - keys.hash_stable(hcx, hasher); -} - -pub fn hash_stable_nodemap<'a, 'tcx, 'gcx, V, W>( - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>, - map: &NodeMap<V>) - where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - W: StableHasherResult, -{ - let definitions = hcx.tcx.hir.definitions(); - hash_stable_hashmap(hcx, hasher, map, |_, node_id| { - let hir_id = definitions.node_to_hir_id(*node_id); - let owner_def_path_hash = definitions.def_path_hash(hir_id.owner); - (owner_def_path_hash, hir_id.local_id) - }); -} - -pub fn hash_stable_nodeset<'a, 'tcx, 'gcx, W>( - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>, - map: &NodeSet) - where W: StableHasherResult, -{ - let definitions = hcx.tcx.hir.definitions(); - hash_stable_hashset(hcx, hasher, map, |_, node_id| { - let hir_id = definitions.node_to_hir_id(*node_id); - let owner_def_path_hash = definitions.def_path_hash(hir_id.owner); - (owner_def_path_hash, hir_id.local_id) - }); -} - -pub fn hash_stable_itemlocalmap<'a, 'tcx, 'gcx, V, W>( - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>, - map: &ItemLocalMap<V>) - where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - W: StableHasherResult, -{ - hash_stable_hashmap(hcx, hasher, map, |_, local_id| { - *local_id - }); -} - - -pub fn hash_stable_btreemap<'a, 'tcx, 'gcx, K, V, SK, F, W>( - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>, - map: &BTreeMap<K, V>, - extract_stable_key: F) - where K: Eq + Ord, - V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - SK: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + Ord + Clone, - F: Fn(&mut StableHashingContext<'a, 'gcx, 'tcx>, &K) -> SK, - W: StableHasherResult, -{ - let mut keys: Vec<_> = map.keys() - .map(|k| (extract_stable_key(hcx, k), k)) - .collect(); - keys.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); - keys.len().hash_stable(hcx, hasher); - for (stable_key, key) in keys { - stable_key.hash_stable(hcx, hasher); - map[key].hash_stable(hcx, hasher); - } -} - pub fn hash_stable_trait_impls<'a, 'tcx, 'gcx, W, R>( hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 53a071fe48030..371a9c966440a 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -11,9 +11,9 @@ //! This module contains `HashStable` implementations for various data types //! from rustc::ty in no particular order. -use ich::{self, StableHashingContext, NodeIdHashingMode}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use ich::{StableHashingContext, NodeIdHashingMode}; +use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, + StableHasher, StableHasherResult}; use std::hash as std_hash; use std::mem; use middle::region; @@ -124,9 +124,10 @@ for ty::adjustment::Adjust<'gcx> { impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target }); impl_stable_hash_for!(struct ty::adjustment::OverloadedDeref<'tcx> { region, mutbl }); -impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id }); impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region }); +impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id }); + impl_stable_hash_for!(enum ty::BorrowKind { ImmBorrow, UniqueImmBorrow, @@ -513,28 +514,20 @@ impl_stable_hash_for!(enum ty::cast::CastKind { FnPtrAddrCast }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> -for region::Scope -{ - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>) { - mem::discriminant(self).hash_stable(hcx, hasher); - hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - match *self { - region::Scope::Node(node_id) | - region::Scope::Destruction(node_id) => { - node_id.hash_stable(hcx, hasher); - } - region::Scope::CallSite(body_id) | - region::Scope::Arguments(body_id) => { - body_id.hash_stable(hcx, hasher); - } - region::Scope::Remainder(block_remainder) => { - block_remainder.hash_stable(hcx, hasher); - } - } - }) +impl_stable_hash_for!(enum ::middle::region::Scope { + Node(local_id), + Destruction(local_id), + CallSite(local_id), + Arguments(local_id), + Remainder(block_remainder) +}); + +impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for region::Scope { + type KeyType = region::Scope; + + #[inline] + fn to_stable_hash_key(&self, _: &StableHashingContext<'a, 'gcx, 'tcx>) -> region::Scope { + *self } } @@ -770,10 +763,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Cr } = *self; dependencies.hash_stable(hcx, hasher); - - ich::hash_stable_hashmap(hcx, hasher, variances, |hcx, def_id| { - hcx.def_path_hash(*def_id) - }); + variances.hash_stable(hcx, hasher); } } @@ -836,25 +826,14 @@ for ::middle::privacy::AccessLevels { ref map } = *self; - ich::hash_stable_nodemap(hcx, hasher, map); + map.hash_stable(hcx, hasher); }); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> -for ty::CrateInherentImpls { - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>) { - let ty::CrateInherentImpls { - ref inherent_impls, - } = *self; - - ich::hash_stable_hashmap(hcx, hasher, inherent_impls, |hcx, def_id| { - hcx.def_path_hash(*def_id) - }); - } -} +impl_stable_hash_for!(struct ty::CrateInherentImpls { + inherent_impls +}); impl_stable_hash_for!(enum ::session::CompileIncomplete { Stopped, @@ -863,14 +842,6 @@ impl_stable_hash_for!(enum ::session::CompileIncomplete { impl_stable_hash_for!(struct ::util::common::ErrorReported {}); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> -for ::middle::reachable::ReachableSet { - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>) { - let ::middle::reachable::ReachableSet(ref reachable_set) = *self; - - ich::hash_stable_nodeset(hcx, hasher, reachable_set); - } -} - +impl_stable_hash_for!(tuple_struct ::middle::reachable::ReachableSet { + reachable_set +}); diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index 5558534b71d2e..cd0749a686511 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -12,9 +12,7 @@ pub use self::fingerprint::Fingerprint; pub use self::caching_codemap_view::CachingCodemapView; -pub use self::hcx::{StableHashingContext, NodeIdHashingMode, hash_stable_hashmap, - hash_stable_hashset, hash_stable_nodemap, hash_stable_nodeset, - hash_stable_btreemap, hash_stable_itemlocalmap, +pub use self::hcx::{StableHashingContext, NodeIdHashingMode, hash_stable_trait_impls}; mod fingerprint; mod caching_codemap_view; diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index e953afd799dbf..eb2b136e417d3 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -12,12 +12,12 @@ use std::cmp; use errors::DiagnosticBuilder; use hir::HirId; -use ich::{self, StableHashingContext}; +use ich::StableHashingContext; use lint::builtin; use lint::context::CheckLintNameResult; use lint::{self, Lint, LintId, Level, LintSource}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, + StableHasher, StableHasherResult}; use session::Session; use syntax::ast; use syntax::attr; @@ -396,10 +396,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LintLe ref id_to_set, } = *self; - let definitions = hcx.tcx().hir.definitions(); - ich::hash_stable_hashmap(hcx, hasher, id_to_set, |_, hir_id| { - (definitions.def_path_hash(hir_id.owner), hir_id.local_id) - }); + id_to_set.hash_stable(hcx, hasher); let LintLevelSets { ref list, @@ -418,14 +415,10 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LintLe match *lint_set { LintSet::CommandLine { ref specs } => { - ich::hash_stable_hashmap(hcx, hasher, specs, |_, lint_id| { - lint_id.lint_name_raw() - }); + specs.hash_stable(hcx, hasher); } LintSet::Node { ref specs, parent } => { - ich::hash_stable_hashmap(hcx, hasher, specs, |_, lint_id| { - lint_id.lint_name_raw() - }); + specs.hash_stable(hcx, hasher); parent.hash_stable(hcx, hasher); } } @@ -434,12 +427,20 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LintLe } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LintId { +impl<HCX> HashStable<HCX> for LintId { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut HCX, hasher: &mut StableHasher<W>) { self.lint_name_raw().hash_stable(hcx, hasher); } } +impl<HCX> ToStableHashKey<HCX> for LintId { + type KeyType = &'static str; + + #[inline] + fn to_stable_hash_key(&self, _: &HCX) -> &'static str { + self.lint_name_raw() + } +} diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 562536ced3ce9..5c6feddb1fdf2 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -14,7 +14,7 @@ //! Most of the documentation on regions can be found in //! `middle/infer/region_inference/README.md` -use ich::{self, StableHashingContext, NodeIdHashingMode}; +use ich::{StableHashingContext, NodeIdHashingMode}; use util::nodemap::{FxHashMap, FxHashSet}; use ty; @@ -1259,22 +1259,11 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ScopeT root_parent.hash_stable(hcx, hasher); }); - ich::hash_stable_hashmap(hcx, hasher, parent_map, |hcx, scope| { - let mut hasher = StableHasher::new(); - scope.hash_stable(hcx, &mut hasher); - let stable: u64 = hasher.finish(); - stable - }); - - ich::hash_stable_itemlocalmap(hcx, hasher, var_map); - ich::hash_stable_itemlocalmap(hcx, hasher, destruction_scopes); - ich::hash_stable_itemlocalmap(hcx, hasher, rvalue_scopes); - ich::hash_stable_itemlocalmap(hcx, hasher, closure_tree); - ich::hash_stable_hashmap(hcx, hasher, yield_in_scope, |hcx, scope| { - let mut hasher = StableHasher::new(); - scope.hash_stable(hcx, &mut hasher); - let stable: u64 = hasher.finish(); - stable - }); + parent_map.hash_stable(hcx, hasher); + var_map.hash_stable(hcx, hasher); + destruction_scopes.hash_stable(hcx, hasher); + rvalue_scopes.hash_stable(hcx, hasher); + closure_tree.hash_stable(hcx, hasher); + yield_in_scope.hash_stable(hcx, hasher); } } diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index ecaf14659ae6b..6895e0e8a3456 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -382,20 +382,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Childr } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Graph { - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>) { - let Graph { - ref parent, - ref children, - } = *self; - - ich::hash_stable_hashmap(hcx, hasher, parent, |hcx, def_id| { - hcx.def_path_hash(*def_id) - }); - ich::hash_stable_hashmap(hcx, hasher, children, |hcx, def_id| { - hcx.def_path_hash(*def_id) - }); - } -} +impl_stable_hash_for!(struct self::Graph { + parent, + children +}); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 7edc55e8a9fe4..0ea466a1bbcc3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use hir::map as hir_map; use hir::map::DefPathHash; use lint::{self, Lint}; -use ich::{self, StableHashingContext, NodeIdHashingMode}; +use ich::{StableHashingContext, NodeIdHashingMode}; use middle::const_val::ConstVal; use middle::cstore::{CrateStore, LinkMeta, EncodedMetadataHashes}; use middle::cstore::EncodedMetadata; @@ -49,8 +49,8 @@ use ty::BindingMode; use util::nodemap::{NodeMap, NodeSet, DefIdSet, ItemLocalMap}; use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::accumulate_vec::AccumulateVec; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, - StableHasherResult}; +use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, + StableHasher, StableHasherResult}; use arena::{TypedArena, DroplessArena}; use rustc_const_math::{ConstInt, ConstUsize}; @@ -714,12 +714,12 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Typeck } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { - ich::hash_stable_itemlocalmap(hcx, hasher, type_dependent_defs); - ich::hash_stable_itemlocalmap(hcx, hasher, node_types); - ich::hash_stable_itemlocalmap(hcx, hasher, node_substs); - ich::hash_stable_itemlocalmap(hcx, hasher, adjustments); - ich::hash_stable_itemlocalmap(hcx, hasher, pat_binding_modes); - ich::hash_stable_hashmap(hcx, hasher, upvar_capture_map, |hcx, up_var_id| { + type_dependent_defs.hash_stable(hcx, hasher); + node_types.hash_stable(hcx, hasher); + node_substs.hash_stable(hcx, hasher); + adjustments.hash_stable(hcx, hasher); + pat_binding_modes.hash_stable(hcx, hasher); + hash_stable_hashmap(hcx, hasher, upvar_capture_map, |up_var_id, hcx| { let ty::UpvarId { var_id, closure_expr_id @@ -736,22 +736,19 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Typeck krate: local_id_root.krate, index: closure_expr_id, }; - ((hcx.def_path_hash(var_owner_def_id), var_id.local_id), - hcx.def_path_hash(closure_def_id)) - }); - - ich::hash_stable_itemlocalmap(hcx, hasher, closure_tys); - ich::hash_stable_itemlocalmap(hcx, hasher, closure_kinds); - ich::hash_stable_itemlocalmap(hcx, hasher, liberated_fn_sigs); - ich::hash_stable_itemlocalmap(hcx, hasher, fru_field_types); - ich::hash_stable_itemlocalmap(hcx, hasher, cast_kinds); - ich::hash_stable_itemlocalmap(hcx, hasher, generator_sigs); - ich::hash_stable_itemlocalmap(hcx, hasher, generator_interiors); - - ich::hash_stable_hashset(hcx, hasher, used_trait_imports, |hcx, def_id| { - hcx.def_path_hash(*def_id) + (hcx.tcx().def_path_hash(var_owner_def_id), + var_id.local_id, + hcx.tcx().def_path_hash(closure_def_id)) }); + closure_tys.hash_stable(hcx, hasher); + closure_kinds.hash_stable(hcx, hasher); + liberated_fn_sigs.hash_stable(hcx, hasher); + fru_field_types.hash_stable(hcx, hasher); + cast_kinds.hash_stable(hcx, hasher); + generator_sigs.hash_stable(hcx, hasher); + generator_interiors.hash_stable(hcx, hasher); + used_trait_imports.hash_stable(hcx, hasher); tainted_by_errors.hash_stable(hcx, hasher); free_region_map.hash_stable(hcx, hasher); }) diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 1b2d09bef934c..e18c1969a91cc 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -289,7 +289,8 @@ impl<T1: HashStable<CTX>, CTX> HashStable<CTX> for (T1,) { fn hash_stable<W: StableHasherResult>(&self, ctx: &mut CTX, hasher: &mut StableHasher<W>) { - self.0.hash_stable(ctx, hasher); + let (ref _0,) = *self; + _0.hash_stable(ctx, hasher); } } @@ -297,8 +298,24 @@ impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2) fn hash_stable<W: StableHasherResult>(&self, ctx: &mut CTX, hasher: &mut StableHasher<W>) { - self.0.hash_stable(ctx, hasher); - self.1.hash_stable(ctx, hasher); + let (ref _0, ref _1) = *self; + _0.hash_stable(ctx, hasher); + _1.hash_stable(ctx, hasher); + } +} + +impl<T1, T2, T3, CTX> HashStable<CTX> for (T1, T2, T3) + where T1: HashStable<CTX>, + T2: HashStable<CTX>, + T3: HashStable<CTX>, +{ + fn hash_stable<W: StableHasherResult>(&self, + ctx: &mut CTX, + hasher: &mut StableHasher<W>) { + let (ref _0, ref _1, ref _2) = *self; + _0.hash_stable(ctx, hasher); + _1.hash_stable(ctx, hasher); + _2.hash_stable(ctx, hasher); } } @@ -462,14 +479,11 @@ impl<K, V, R, HCX> HashStable<HCX> for ::std::collections::HashMap<K, V, R> V: HashStable<HCX>, R: BuildHasher, { + #[inline] fn hash_stable<W: StableHasherResult>(&self, hcx: &mut HCX, hasher: &mut StableHasher<W>) { - let mut entries: Vec<_> = self.iter() - .map(|(k, v)| (k.to_stable_hash_key(hcx), v)) - .collect(); - entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); - entries.hash_stable(hcx, hasher); + hash_stable_hashmap(hcx, hasher, self, ToStableHashKey::to_stable_hash_key); } } @@ -516,3 +530,23 @@ impl<K, HCX> HashStable<HCX> for ::std::collections::BTreeSet<K> keys.hash_stable(hcx, hasher); } } + +pub fn hash_stable_hashmap<HCX, K, V, R, SK, F, W>( + hcx: &mut HCX, + hasher: &mut StableHasher<W>, + map: &::std::collections::HashMap<K, V, R>, + to_stable_hash_key: F) + where K: Eq + Hash, + V: HashStable<HCX>, + R: BuildHasher, + SK: HashStable<HCX> + Ord + Clone, + F: Fn(&K, &HCX) -> SK, + W: StableHasherResult, +{ + let mut entries: Vec<_> = map.iter() + .map(|(k, v)| (to_stable_hash_key(k, hcx), v)) + .collect(); + entries.sort_unstable_by(|&(ref sk1, _), &(ref sk2, _)| sk1.cmp(sk2)); + entries.hash_stable(hcx, hasher); +} + From dd501735ac8eb38756f8a4f4da91b0b7a4fbca1b Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Thu, 14 Sep 2017 12:08:03 +0200 Subject: [PATCH 18/24] incr.comp.: Initialize the CachingCodemapView in StableHashingContext lazily. --- src/librustc/ich/caching_codemap_view.rs | 10 ++++------ src/librustc/ich/hcx.rs | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/librustc/ich/caching_codemap_view.rs b/src/librustc/ich/caching_codemap_view.rs index 49e18f100cf26..71e442b3bb213 100644 --- a/src/librustc/ich/caching_codemap_view.rs +++ b/src/librustc/ich/caching_codemap_view.rs @@ -11,7 +11,6 @@ use std::rc::Rc; use syntax::codemap::CodeMap; use syntax_pos::{BytePos, FileMap}; -use ty::TyCtxt; #[derive(Clone)] struct CacheEntry { @@ -23,15 +22,14 @@ struct CacheEntry { file_index: usize, } -pub struct CachingCodemapView<'tcx> { - codemap: &'tcx CodeMap, +pub struct CachingCodemapView<'cm> { + codemap: &'cm CodeMap, line_cache: [CacheEntry; 3], time_stamp: usize, } -impl<'gcx> CachingCodemapView<'gcx> { - pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> CachingCodemapView<'gcx> { - let codemap = tcx.sess.codemap(); +impl<'cm> CachingCodemapView<'cm> { + pub fn new(codemap: &'cm CodeMap) -> CachingCodemapView<'cm> { let files = codemap.files(); let first_file = files[0].clone(); let entry = CacheEntry { diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 0932c5ce8fb80..3f9590a45c68c 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -21,6 +21,7 @@ use std::collections::HashMap; use syntax::ast; use syntax::attr; +use syntax::codemap::CodeMap; use syntax::ext::hygiene::SyntaxContext; use syntax::symbol::Symbol; use syntax_pos::Span; @@ -36,13 +37,17 @@ use rustc_data_structures::accumulate_vec::AccumulateVec; /// things (e.g. each DefId/DefPath is only hashed once). pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, - codemap: CachingCodemapView<'gcx>, hash_spans: bool, hash_bodies: bool, overflow_checks_enabled: bool, node_id_hashing_mode: NodeIdHashingMode, // A sorted array of symbol keys for fast lookup. ignored_attr_names: Vec<Symbol>, + + // Very often, we are hashing something that does not need the + // CachingCodemapView, so we initialize it lazily. + raw_codemap: &'gcx CodeMap, + caching_codemap: Option<CachingCodemapView<'gcx>>, } #[derive(PartialEq, Eq, Clone, Copy)] @@ -66,7 +71,8 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { StableHashingContext { tcx, - codemap: CachingCodemapView::new(tcx), + caching_codemap: None, + raw_codemap: tcx.sess.codemap(), hash_spans: hash_spans_initial, hash_bodies: true, overflow_checks_enabled: check_overflow_initial, @@ -132,7 +138,15 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { #[inline] pub fn codemap(&mut self) -> &mut CachingCodemapView<'gcx> { - &mut self.codemap + match self.caching_codemap { + Some(ref mut cm) => { + cm + } + ref mut none => { + *none = Some(CachingCodemapView::new(self.raw_codemap)); + none.as_mut().unwrap() + } + } } #[inline] From e567afbc584e32df6492d1ea29a65b583ca24e57 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Thu, 14 Sep 2017 12:29:16 +0200 Subject: [PATCH 19/24] incr.comp.: Initialize IGNORED_ATTRS in StableHashingContext lazily. --- src/librustc/ich/hcx.rs | 26 ++++++++++++++++---------- src/librustc/ich/impls_syntax.rs | 5 +++++ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 3f9590a45c68c..616b966cb5058 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -17,6 +17,7 @@ use ty::{self, TyCtxt, fast_reject}; use std::cmp::Ord; use std::hash as std_hash; +use std::cell::RefCell; use std::collections::HashMap; use syntax::ast; @@ -30,6 +31,10 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHashingContextProvi StableHasher, StableHasherResult, ToStableHashKey}; use rustc_data_structures::accumulate_vec::AccumulateVec; +use rustc_data_structures::fx::FxHashSet; + +thread_local!(static IGNORED_ATTR_NAMES: RefCell<FxHashSet<Symbol>> = + RefCell::new(FxHashSet())); /// This is the context state available during incr. comp. hashing. It contains /// enough information to transform DefIds and HirIds into stable DefPaths (i.e. @@ -41,8 +46,6 @@ pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { hash_bodies: bool, overflow_checks_enabled: bool, node_id_hashing_mode: NodeIdHashingMode, - // A sorted array of symbol keys for fast lookup. - ignored_attr_names: Vec<Symbol>, // Very often, we are hashing something that does not need the // CachingCodemapView, so we initialize it lazily. @@ -62,12 +65,14 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { let hash_spans_initial = tcx.sess.opts.debuginfo != NoDebugInfo; let check_overflow_initial = tcx.sess.overflow_checks(); - let mut ignored_attr_names: Vec<_> = ich::IGNORED_ATTRIBUTES - .iter() - .map(|&s| Symbol::intern(s)) - .collect(); - - ignored_attr_names.sort(); + debug_assert!(ich::IGNORED_ATTRIBUTES.len() > 0); + IGNORED_ATTR_NAMES.with(|names| { + let mut names = names.borrow_mut(); + if names.is_empty() { + names.extend(ich::IGNORED_ATTRIBUTES.iter() + .map(|&s| Symbol::intern(s))); + } + }); StableHashingContext { tcx, @@ -77,7 +82,6 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { hash_bodies: true, overflow_checks_enabled: check_overflow_initial, node_id_hashing_mode: NodeIdHashingMode::HashDefPath, - ignored_attr_names, } } @@ -151,7 +155,9 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { #[inline] pub fn is_ignored_attr(&self, name: Symbol) -> bool { - self.ignored_attr_names.binary_search(&name).is_ok() + IGNORED_ATTR_NAMES.with(|names| { + names.borrow().contains(&name) + }) } pub fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self, diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index a75527c14bd69..4e3caca2b6131 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -169,6 +169,11 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for [ast:: fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { + if self.len() == 0 { + self.len().hash_stable(hcx, hasher); + return + } + // Some attributes are always ignored during hashing. let filtered: AccumulateVec<[&ast::Attribute; 8]> = self .iter() From ba6f93ca76d7d71399a13d5c9722c3239497f8ef Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Thu, 14 Sep 2017 14:01:40 +0200 Subject: [PATCH 20/24] incr.comp.: Make the StableHashingContext mostly independent of the tcx. --- src/librustc/ich/hcx.rs | 49 ++++++++++++++++--- src/librustc/ich/impls_hir.rs | 16 ++---- src/librustc/ich/impls_syntax.rs | 4 +- src/librustc/ty/context.rs | 4 +- src/librustc_incremental/calculate_svh/mod.rs | 27 +++++----- 5 files changed, 61 insertions(+), 39 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 616b966cb5058..136190f7573c1 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -9,11 +9,12 @@ // except according to those terms. use hir; -use hir::def_id::DefId; +use hir::def_id::{DefId, DefIndex}; use hir::map::DefPathHash; use ich::{self, CachingCodemapView}; use session::config::DebugInfoLevel::NoDebugInfo; use ty::{self, TyCtxt, fast_reject}; +use session::Session; use std::cmp::Ord; use std::hash as std_hash; @@ -42,6 +43,7 @@ thread_local!(static IGNORED_ATTR_NAMES: RefCell<FxHashSet<Symbol>> = /// things (e.g. each DefId/DefPath is only hashed once). pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, + body_resolver: BodyResolver<'gcx>, hash_spans: bool, hash_bodies: bool, overflow_checks_enabled: bool, @@ -59,6 +61,20 @@ pub enum NodeIdHashingMode { HashDefPath, } +/// The BodyResolver allows to map a BodyId to the corresponding hir::Body. +/// We could also just store a plain reference to the hir::Crate but we want +/// to avoid that the crate is used to get untracked access to all of the HIR. +#[derive(Clone, Copy)] +struct BodyResolver<'hir>(&'hir hir::Crate); + +impl<'hir> BodyResolver<'hir> { + // Return a reference to the hir::Body with the given BodyId. + // DOES NOT DO ANY TRACKING, use carefully. + fn body(self, id: hir::BodyId) -> &'hir hir::Body { + self.0.body(id) + } +} + impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { @@ -74,8 +90,11 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { } }); + let body_resolver = BodyResolver(tcx.dep_graph.with_ignore(|| tcx.hir.krate())); + StableHashingContext { tcx, + body_resolver, caching_codemap: None, raw_codemap: tcx.sess.codemap(), hash_spans: hash_spans_initial, @@ -85,6 +104,11 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { } } + #[inline] + pub fn sess(&self) -> &'gcx Session { + self.tcx.sess + } + pub fn force_span_hashing(mut self) -> Self { self.hash_spans = true; self @@ -121,13 +145,13 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { } #[inline] - pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { - self.tcx + pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash { + self.tcx.def_path_hash(def_id) } #[inline] - pub fn def_path_hash(&mut self, def_id: DefId) -> DefPathHash { - self.tcx.def_path_hash(def_id) + pub fn local_def_path_hash(&self, def_index: DefIndex) -> DefPathHash { + self.tcx.hir.definitions().def_path_hash(def_index) } #[inline] @@ -221,6 +245,16 @@ impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx> } } +impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hasher: &mut StableHasher<W>) { + if hcx.hash_bodies() { + hcx.body_resolver.body(*self).hash_stable(hcx, hasher); + } + } +} + impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { #[inline] fn hash_stable<W: StableHasherResult>(&self, @@ -250,7 +284,7 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for h fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> (DefPathHash, hir::ItemLocalId) { - let def_path_hash = hcx.tcx().hir.definitions().def_path_hash(self.owner); + let def_path_hash = hcx.local_def_path_hash(self.owner); (def_path_hash, self.local_id) } } @@ -378,10 +412,9 @@ pub fn hash_stable_trait_impls<'a, 'tcx, 'gcx, W, R>( } { - let tcx = hcx.tcx(); let mut keys: AccumulateVec<[_; 8]> = non_blanket_impls.keys() - .map(|k| (k, k.map_def(|d| tcx.def_path_hash(d)))) + .map(|k| (k, k.map_def(|d| hcx.def_path_hash(d)))) .collect(); keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2)); keys.len().hash_stable(hcx, hasher); diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 3c89e10a0d2d9..aa4826528ec6d 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -34,7 +34,7 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for D #[inline] fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { - hcx.tcx().def_path_hash(*self) + hcx.def_path_hash(*self) } } @@ -995,16 +995,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId { - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>) { - if hcx.hash_bodies() { - hcx.tcx().hir.body(*self).hash_stable(hcx, hasher); - } - } -} - impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId { type KeyType = (DefPathHash, hir::ItemLocalId); @@ -1119,7 +1109,7 @@ for hir::def_id::DefIndex { fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher<W>) { - hcx.tcx().hir.definitions().def_path_hash(*self).hash_stable(hcx, hasher); + hcx.local_def_path_hash(*self).hash_stable(hcx, hasher); } } @@ -1129,7 +1119,7 @@ for hir::def_id::DefIndex { #[inline] fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { - hcx.tcx().hir.definitions().def_path_hash(*self) + hcx.local_def_path_hash(*self) } } diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 4e3caca2b6131..6bcbce4b69304 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -324,11 +324,11 @@ fn hash_token<'a, 'gcx, 'tcx, W: StableHasherResult>(token: &token::Token, // in a stable way, in addition to the HIR. // Since this is hardly used anywhere, just emit a // warning for now. - if hcx.tcx().sess.opts.debugging_opts.incremental.is_some() { + if hcx.sess().opts.debugging_opts.incremental.is_some() { let msg = format!("Quasi-quoting might make incremental \ compilation very inefficient: {:?}", non_terminal); - hcx.tcx().sess.span_warn(error_reporting_span, &msg[..]); + hcx.sess().span_warn(error_reporting_span, &msg[..]); } std_hash::Hash::hash(non_terminal, hasher); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0ea466a1bbcc3..61cd5db9a1948 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -736,9 +736,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Typeck krate: local_id_root.krate, index: closure_expr_id, }; - (hcx.tcx().def_path_hash(var_owner_def_id), + (hcx.def_path_hash(var_owner_def_id), var_id.local_id, - hcx.tcx().def_path_hash(closure_def_id)) + hcx.def_path_hash(closure_def_id)) }); closure_tys.hash_stable(hcx, hasher); diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index d8e201d3acdcf..60e1f238f44a4 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -90,6 +90,7 @@ impl<'a> ::std::ops::Index<&'a DepNode> for IncrementalHashesMap { } struct ComputeItemHashesVisitor<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, hcx: StableHashingContext<'a, 'tcx, 'tcx>, hashes: IncrementalHashesMap, } @@ -101,14 +102,14 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { item_like: T) where T: HashStable<StableHashingContext<'a, 'tcx, 'tcx>> { - if !hash_bodies && !self.hcx.tcx().sess.opts.build_dep_graph() { + if !hash_bodies && !self.tcx.sess.opts.build_dep_graph() { // If we just need the hashes in order to compute the SVH, we don't // need have two hashes per item. Just the one containing also the // item's body is sufficient. return } - let def_path_hash = self.hcx.tcx().hir.definitions().def_path_hash(def_index); + let def_path_hash = self.hcx.local_def_path_hash(def_index); let mut hasher = IchHasher::new(); self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| { @@ -125,14 +126,12 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash); self.hashes.insert(dep_node, item_hash); - let tcx = self.hcx.tcx(); let bytes_hashed = - tcx.sess.perf_stats.incr_comp_bytes_hashed.get() + - bytes_hashed; - tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed); + self.tcx.sess.perf_stats.incr_comp_bytes_hashed.get() + bytes_hashed; + self.tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed); if hash_bodies { - let in_scope_traits_map = tcx.in_scope_traits_map(def_index); + let in_scope_traits_map = self.tcx.in_scope_traits_map(def_index); let mut hasher = IchHasher::new(); in_scope_traits_map.hash_stable(&mut self.hcx, &mut hasher); let dep_node = def_path_hash.to_dep_node(DepKind::InScopeTraits); @@ -141,12 +140,11 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { } fn compute_crate_hash(&mut self) { - let tcx = self.hcx.tcx(); - let krate = tcx.hir.krate(); + let krate = self.tcx.hir.krate(); let mut crate_state = IchHasher::new(); - let crate_disambiguator = tcx.sess.local_crate_disambiguator(); + let crate_disambiguator = self.tcx.sess.local_crate_disambiguator(); "crate_disambiguator".hash(&mut crate_state); crate_disambiguator.as_str().len().hash(&mut crate_state); crate_disambiguator.as_str().hash(&mut crate_state); @@ -221,7 +219,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { fn compute_and_store_ich_for_trait_impls(&mut self, krate: &'tcx hir::Crate) { - let tcx = self.hcx.tcx(); + let tcx = self.tcx; let mut impls: Vec<(DefPathHash, Fingerprint)> = krate .trait_impls @@ -266,7 +264,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { - let def_index = self.hcx.tcx().hir.local_def_id(item.id).index; + let def_index = self.tcx.hir.local_def_id(item.id).index; self.compute_and_store_ich_for_item_like(def_index, false, item); @@ -276,7 +274,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> } fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) { - let def_index = self.hcx.tcx().hir.local_def_id(item.id).index; + let def_index = self.tcx.hir.local_def_id(item.id).index; self.compute_and_store_ich_for_item_like(def_index, false, item); @@ -286,7 +284,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> } fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) { - let def_index = self.hcx.tcx().hir.local_def_id(item.id).index; + let def_index = self.tcx.hir.local_def_id(item.id).index; self.compute_and_store_ich_for_item_like(def_index, false, item); @@ -304,6 +302,7 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) let krate = tcx.hir.krate(); let mut visitor = ComputeItemHashesVisitor { + tcx, hcx: StableHashingContext::new(tcx), hashes: IncrementalHashesMap::new(), }; From d5b1fee6fd658bf464902d46f9a6c9c2f8ab87d7 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Thu, 14 Sep 2017 15:10:24 +0200 Subject: [PATCH 21/24] incr.comp.: Remove tcx from StableHashingContext. --- src/librustc/dep_graph/dep_node.rs | 4 +- src/librustc/hir/map/mod.rs | 8 +- src/librustc/ich/hcx.rs | 88 +++++++------ src/librustc/ich/impls_hir.rs | 120 +++++++++--------- src/librustc/ich/impls_mir.rs | 80 ++++++------ src/librustc/ich/impls_syntax.rs | 48 +++---- src/librustc/ich/impls_ty.rs | 104 +++++++-------- src/librustc/lint/levels.rs | 4 +- src/librustc/macros.rs | 16 +-- src/librustc/middle/region.rs | 4 +- src/librustc/mir/cache.rs | 4 +- .../traits/specialize/specialization_graph.rs | 4 +- src/librustc/ty/context.rs | 13 +- src/librustc/ty/fast_reject.rs | 6 +- src/librustc/ty/layout.rs | 8 +- src/librustc/ty/mod.rs | 8 +- src/librustc/ty/trait_def.rs | 4 +- src/librustc/ty/util.rs | 4 +- src/librustc_driver/driver.rs | 2 +- src/librustc_driver/test.rs | 2 +- src/librustc_incremental/calculate_svh/mod.rs | 6 +- src/librustc_metadata/astencode.rs | 4 +- src/librustc_metadata/isolated_encoder.rs | 16 +-- src/librustc_metadata/schema.rs | 8 +- src/librustc_trans/context.rs | 4 +- src/librustc_typeck/variance/constraints.rs | 4 +- src/librustdoc/core.rs | 2 +- src/librustdoc/test.rs | 2 +- 28 files changed, 300 insertions(+), 277 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 1dcc9272d4e02..7c21bba49f81b 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -603,12 +603,12 @@ trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug { } impl<'a, 'gcx: 'tcx + 'a, 'tcx: 'a, T> DepNodeParams<'a, 'gcx, 'tcx> for T - where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + fmt::Debug + where T: HashStable<StableHashingContext<'gcx>> + fmt::Debug { default const CAN_RECONSTRUCT_QUERY_KEY: bool = false; default fn to_fingerprint(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Fingerprint { - let mut hcx = StableHashingContext::new(tcx); + let mut hcx = tcx.create_stable_hashing_context(); let mut hasher = StableHasher::new(); self.hash_stable(&mut hcx, &mut hasher); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d043d8346e6a8..b2d6886e7f228 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -247,7 +247,7 @@ pub struct Map<'hir> { /// plain old integers. map: Vec<MapEntry<'hir>>, - definitions: Definitions, + definitions: &'hir Definitions, /// Bodies inlined from other crates are cached here. inlined_bodies: RefCell<DefIdMap<&'hir Body>>, @@ -304,8 +304,8 @@ impl<'hir> Map<'hir> { } #[inline] - pub fn definitions(&self) -> &Definitions { - &self.definitions + pub fn definitions(&self) -> &'hir Definitions { + self.definitions } pub fn def_key(&self, def_id: DefId) -> DefKey { @@ -1013,7 +1013,7 @@ impl Named for TraitItem { fn name(&self) -> Name { self.name } } impl Named for ImplItem { fn name(&self) -> Name { self.name } } pub fn map_crate<'hir>(forest: &'hir mut Forest, - definitions: Definitions) + definitions: &'hir Definitions) -> Map<'hir> { let map = { let mut collector = NodeCollector::root(&forest.krate, diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 136190f7573c1..0a2566f069249 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -11,7 +11,9 @@ use hir; use hir::def_id::{DefId, DefIndex}; use hir::map::DefPathHash; +use hir::map::definitions::Definitions; use ich::{self, CachingCodemapView}; +use middle::cstore::CrateStore; use session::config::DebugInfoLevel::NoDebugInfo; use ty::{self, TyCtxt, fast_reject}; use session::Session; @@ -41,8 +43,10 @@ thread_local!(static IGNORED_ATTR_NAMES: RefCell<FxHashSet<Symbol>> = /// enough information to transform DefIds and HirIds into stable DefPaths (i.e. /// a reference to the TyCtxt) and it holds a few caches for speeding up various /// things (e.g. each DefId/DefPath is only hashed once). -pub struct StableHashingContext<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - tcx: TyCtxt<'a, 'gcx, 'tcx>, +pub struct StableHashingContext<'gcx> { + sess: &'gcx Session, + definitions: &'gcx Definitions, + cstore: &'gcx CrateStore, body_resolver: BodyResolver<'gcx>, hash_spans: bool, hash_bodies: bool, @@ -65,21 +69,27 @@ pub enum NodeIdHashingMode { /// We could also just store a plain reference to the hir::Crate but we want /// to avoid that the crate is used to get untracked access to all of the HIR. #[derive(Clone, Copy)] -struct BodyResolver<'hir>(&'hir hir::Crate); +struct BodyResolver<'gcx>(&'gcx hir::Crate); -impl<'hir> BodyResolver<'hir> { +impl<'gcx> BodyResolver<'gcx> { // Return a reference to the hir::Body with the given BodyId. // DOES NOT DO ANY TRACKING, use carefully. - fn body(self, id: hir::BodyId) -> &'hir hir::Body { + fn body(self, id: hir::BodyId) -> &'gcx hir::Body { self.0.body(id) } } -impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { - - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { - let hash_spans_initial = tcx.sess.opts.debuginfo != NoDebugInfo; - let check_overflow_initial = tcx.sess.overflow_checks(); +impl<'gcx> StableHashingContext<'gcx> { + // The `krate` here is only used for mapping BodyIds to Bodies. + // Don't use it for anything else or you'll run the risk of + // leaking data out of the tracking system. + pub fn new(sess: &'gcx Session, + krate: &'gcx hir::Crate, + definitions: &'gcx Definitions, + cstore: &'gcx CrateStore) + -> Self { + let hash_spans_initial = sess.opts.debuginfo != NoDebugInfo; + let check_overflow_initial = sess.overflow_checks(); debug_assert!(ich::IGNORED_ATTRIBUTES.len() > 0); IGNORED_ATTR_NAMES.with(|names| { @@ -90,13 +100,13 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { } }); - let body_resolver = BodyResolver(tcx.dep_graph.with_ignore(|| tcx.hir.krate())); - StableHashingContext { - tcx, - body_resolver, + sess, + body_resolver: BodyResolver(krate), + definitions, + cstore, caching_codemap: None, - raw_codemap: tcx.sess.codemap(), + raw_codemap: sess.codemap(), hash_spans: hash_spans_initial, hash_bodies: true, overflow_checks_enabled: check_overflow_initial, @@ -106,7 +116,7 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { #[inline] pub fn sess(&self) -> &'gcx Session { - self.tcx.sess + self.sess } pub fn force_span_hashing(mut self) -> Self { @@ -146,12 +156,16 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { #[inline] pub fn def_path_hash(&self, def_id: DefId) -> DefPathHash { - self.tcx.def_path_hash(def_id) + if def_id.is_local() { + self.definitions.def_path_hash(def_id.index) + } else { + self.cstore.def_path_hash(def_id) + } } #[inline] pub fn local_def_path_hash(&self, def_index: DefIndex) -> DefPathHash { - self.tcx.hir.definitions().def_path_hash(def_index) + self.definitions.def_path_hash(def_index) } #[inline] @@ -239,15 +253,15 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> { } impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx> { - type ContextType = StableHashingContext<'a, 'gcx, 'lcx>; + type ContextType = StableHashingContext<'gcx>; fn create_stable_hashing_context(&self) -> Self::ContextType { - StableHashingContext::new(*self) + (*self).create_stable_hashing_context() } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::BodyId { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { if hcx.hash_bodies() { hcx.body_resolver.body(*self).hash_stable(hcx, hasher); @@ -255,10 +269,10 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::HirId { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { match hcx.node_id_hashing_mode { NodeIdHashingMode::Ignore => { @@ -270,52 +284,52 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::H local_id, } = *self; - hcx.tcx.hir.definitions().def_path_hash(owner).hash_stable(hcx, hasher); + hcx.local_def_path_hash(owner).hash_stable(hcx, hasher); local_id.hash_stable(hcx, hasher); } } } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::HirId { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::HirId { type KeyType = (DefPathHash, hir::ItemLocalId); #[inline] fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a, 'gcx, 'tcx>) + hcx: &StableHashingContext<'gcx>) -> (DefPathHash, hir::ItemLocalId) { let def_path_hash = hcx.local_def_path_hash(self.owner); (def_path_hash, self.local_id) } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::NodeId { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { match hcx.node_id_hashing_mode { NodeIdHashingMode::Ignore => { // Don't do anything. } NodeIdHashingMode::HashDefPath => { - hcx.tcx.hir.node_to_hir_id(*self).hash_stable(hcx, hasher); + hcx.definitions.node_to_hir_id(*self).hash_stable(hcx, hasher); } } } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for ast::NodeId { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for ast::NodeId { type KeyType = (DefPathHash, hir::ItemLocalId); #[inline] fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a, 'gcx, 'tcx>) + hcx: &StableHashingContext<'gcx>) -> (DefPathHash, hir::ItemLocalId) { - hcx.tcx.hir.node_to_hir_id(*self).to_stable_hash_key(hcx) + hcx.definitions.node_to_hir_id(*self).to_stable_hash_key(hcx) } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Span { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span { // Hash a span in a stable way. We can't directly hash the span's BytePos // fields (that would be similar to hashing pointers, since those are just @@ -327,7 +341,7 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Span { // Also, hashing filenames is expensive so we avoid doing it twice when the // span starts and ends in the same file, which is almost always the case. fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use syntax_pos::Pos; @@ -390,8 +404,8 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Span { } } -pub fn hash_stable_trait_impls<'a, 'tcx, 'gcx, W, R>( - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, +pub fn hash_stable_trait_impls<'gcx, W, R>( + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>, blanket_impls: &Vec<DefId>, non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>) diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index aa4826528ec6d..9582b03ce1c8a 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -20,28 +20,28 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, use std::mem; use syntax::ast; -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for DefId { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for DefId { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { hcx.def_path_hash(*self).hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for DefId { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for DefId { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'gcx>) -> DefPathHash { hcx.def_path_hash(*self) } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for CrateNum { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { hcx.def_path_hash(DefId { krate: *self, @@ -50,11 +50,11 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for CrateN } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for CrateNum { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for CrateNum { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'gcx>) -> DefPathHash { let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX }; def_id.to_stable_hash_key(hcx) } @@ -62,13 +62,13 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for C impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index }); -impl<'a, 'gcx, 'lcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'lcx>> +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::ItemLocalId { type KeyType = hir::ItemLocalId; #[inline] fn to_stable_hash_key(&self, - _: &StableHashingContext<'a, 'gcx, 'lcx>) + _: &StableHashingContext<'gcx>) -> hir::ItemLocalId { *self } @@ -81,9 +81,9 @@ for hir::ItemLocalId { // want to pick up on a reference changing its target, so we hash the NodeIds // in "DefPath Mode". -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::ItemId { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::ItemId { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::ItemId { id @@ -95,9 +95,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::I } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::TraitItemId { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitItemId { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::TraitItemId { node_id @@ -109,9 +109,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::T } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::ImplItemId { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::ImplItemId { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::ImplItemId { node_id @@ -231,9 +231,9 @@ impl_stable_hash_for!(struct hir::TypeBinding { span }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Ty { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Ty { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { hcx.while_hashing_hir_bodies(true, |hcx| { let hir::Ty { @@ -292,9 +292,9 @@ impl_stable_hash_for!(enum hir::FunctionRetTy { Return(t) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::TraitRef { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitRef { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::TraitRef { ref path, @@ -329,9 +329,9 @@ impl_stable_hash_for!(struct hir::MacroDef { }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Block { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Block { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::Block { ref stmts, @@ -377,9 +377,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Pat { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Pat { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::Pat { id: _, @@ -504,9 +504,9 @@ impl_stable_hash_for!(enum hir::UnsafeSource { UserProvided }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Expr { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Expr { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { hcx.while_hashing_hir_bodies(true, |hcx| { let hir::Expr { @@ -622,9 +622,9 @@ impl_stable_hash_for!(enum hir::LoopSource { ForLoop }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::MatchSource { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::MatchSource { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use hir::MatchSource; @@ -673,9 +673,9 @@ impl_stable_hash_for!(enum hir::ScopeTarget { Loop(loop_id_result) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Ident { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::Ident { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ast::Ident { ref name, @@ -686,9 +686,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::I } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::TraitItem { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitItem { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::TraitItem { id, @@ -720,9 +720,9 @@ impl_stable_hash_for!(enum hir::TraitItemKind { Type(bounds, rhs) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::ImplItem { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::ImplItem { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::ImplItem { id, @@ -753,9 +753,9 @@ impl_stable_hash_for!(enum hir::ImplItemKind { Type(t) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Visibility { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Visibility { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -774,9 +774,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::V } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Defaultness { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Defaultness { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -795,9 +795,9 @@ impl_stable_hash_for!(enum hir::ImplPolarity { Negative }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Mod { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Mod { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::Mod { inner, @@ -850,9 +850,9 @@ impl_stable_hash_for!(enum hir::VariantData { Unit(id) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Item { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Item { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hash_spans = match self.node { hir::ItemStatic(..) | @@ -933,10 +933,10 @@ impl_stable_hash_for!(struct hir::ImplItemRef { defaultness }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::AssociatedItemKind { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -977,9 +977,9 @@ impl_stable_hash_for!(struct hir::Arg { hir_id }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::Body { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::Body { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::Body { ref arguments, @@ -995,12 +995,12 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::B } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::BodyId { type KeyType = (DefPathHash, hir::ItemLocalId); #[inline] fn to_stable_hash_key(&self, - hcx: &StableHashingContext<'a, 'gcx, 'tcx>) + hcx: &StableHashingContext<'gcx>) -> (DefPathHash, hir::ItemLocalId) { let hir::BodyId { node_id } = *self; node_id.to_stable_hash_key(hcx) @@ -1013,9 +1013,9 @@ impl_stable_hash_for!(struct hir::InlineAsmOutput { is_indirect }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::GlobalAsm { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::GlobalAsm { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::GlobalAsm { asm, @@ -1026,9 +1026,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::G } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::InlineAsm { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::InlineAsm { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let hir::InlineAsm { asm, @@ -1103,22 +1103,22 @@ impl_stable_hash_for!(enum hir::Constness { NotConst }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::def_id::DefIndex { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { hcx.local_def_path_hash(*self).hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for hir::def_id::DefIndex { type KeyType = DefPathHash; #[inline] - fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a, 'gcx, 'tcx>) -> DefPathHash { + fn to_stable_hash_key(&self, hcx: &StableHashingContext<'gcx>) -> DefPathHash { hcx.local_def_path_hash(*self) } } @@ -1129,10 +1129,10 @@ impl_stable_hash_for!(struct hir::def::Export { span }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ::middle::lang_items::LangItem { fn hash_stable<W: StableHasherResult>(&self, - _: &mut StableHashingContext<'a, 'gcx, 'tcx>, + _: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { ::std::hash::Hash::hash(self, hasher); } @@ -1143,10 +1143,10 @@ impl_stable_hash_for!(struct ::middle::lang_items::LanguageItems { missing }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for hir::TraitCandidate { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { let hir::TraitCandidate { diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index dce1639b375b7..9b6613e4cae96 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -33,11 +33,11 @@ impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref }); impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Terminator<'gcx> { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let mir::Terminator { ref kind, @@ -76,61 +76,61 @@ for mir::Terminator<'gcx> { } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Local { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Local { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::BasicBlock { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::BasicBlock { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Field { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Field { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::VisibilityScope { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Promoted { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Promoted { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use rustc_data_structures::indexed_vec::Idx; self.index().hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::TerminatorKind<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); @@ -196,10 +196,10 @@ for mir::TerminatorKind<'gcx> { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::AssertMessage<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); @@ -219,10 +219,10 @@ for mir::AssertMessage<'gcx> { impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::StatementKind<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); @@ -256,12 +256,12 @@ for mir::StatementKind<'gcx> { } } -impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ValidationOperand<'gcx, T> - where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + where T: HashStable<StableHashingContext<'gcx>> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { self.lval.hash_stable(hcx, hasher); @@ -273,9 +273,9 @@ impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(region_scope) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Lvalue<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -292,14 +292,14 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::L } } -impl<'a, 'gcx, 'tcx, B, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, B, V, T> HashStable<StableHashingContext<'gcx>> for mir::Projection<'gcx, B, V, T> - where B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + where B: HashStable<StableHashingContext<'gcx>>, + V: HashStable<StableHashingContext<'gcx>>, + T: HashStable<StableHashingContext<'gcx>> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let mir::Projection { ref base, @@ -311,13 +311,13 @@ for mir::Projection<'gcx, B, V, T> } } -impl<'a, 'gcx, 'tcx, V, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, V, T> HashStable<StableHashingContext<'gcx>> for mir::ProjectionElem<'gcx, V, T> - where V: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + where V: HashStable<StableHashingContext<'gcx>>, + T: HashStable<StableHashingContext<'gcx>> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -348,9 +348,9 @@ for mir::ProjectionElem<'gcx, V, T> impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Operand<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Operand<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); @@ -365,9 +365,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::O } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Rvalue<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Rvalue<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); @@ -425,10 +425,10 @@ impl_stable_hash_for!(enum mir::CastKind { Unsize }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::AggregateKind<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -487,9 +487,9 @@ impl_stable_hash_for!(enum mir::NullOp { impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Literal<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Literal<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 6bcbce4b69304..6821ac8529800 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -28,42 +28,42 @@ use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey, StableHasher, StableHasherResult}; use rustc_data_structures::accumulate_vec::AccumulateVec; -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for InternedString { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for InternedString { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let s: &str = &**self; s.hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for InternedString { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for InternedString { type KeyType = InternedString; #[inline] fn to_stable_hash_key(&self, - _: &StableHashingContext<'a, 'gcx, 'tcx>) + _: &StableHashingContext<'gcx>) -> InternedString { self.clone() } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Name { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::Name { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { self.as_str().hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Name { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for ast::Name { type KeyType = InternedString; #[inline] fn to_stable_hash_key(&self, - _: &StableHashingContext<'a, 'gcx, 'tcx>) + _: &StableHashingContext<'gcx>) -> InternedString { self.as_str() } @@ -110,10 +110,10 @@ impl_stable_hash_for!(struct ::syntax::attr::Stability { rustc_const_unstable }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ::syntax::attr::StabilityLevel { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -165,9 +165,9 @@ impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, ident }); impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) }); impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for [ast::Attribute] { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for [ast::Attribute] { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { if self.len() == 0 { self.len().hash_stable(hcx, hasher); @@ -190,9 +190,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for [ast:: } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::Attribute { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ast::Attribute { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { // Make sure that these have been filtered out. debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)); @@ -219,10 +219,10 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ast::A } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for tokenstream::TokenTree { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -241,10 +241,10 @@ for tokenstream::TokenTree { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for tokenstream::TokenStream { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { for sub_tt in self.trees() { sub_tt.hash_stable(hcx, hasher); @@ -252,10 +252,10 @@ for tokenstream::TokenStream { } } -fn hash_token<'a, 'gcx, 'tcx, W: StableHasherResult>(token: &token::Token, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, - hasher: &mut StableHasher<W>, - error_reporting_span: Span) { +fn hash_token<'gcx, W: StableHasherResult>(token: &token::Token, + hcx: &mut StableHashingContext<'gcx>, + hasher: &mut StableHasher<W>, + error_reporting_span: Span) { mem::discriminant(token).hash_stable(hcx, hasher); match *token { token::Token::Eq | @@ -358,9 +358,9 @@ impl_stable_hash_for!(enum ::syntax::ast::MetaItemKind { NameValue(lit) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for FileMap { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for FileMap { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let FileMap { ref name, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 371a9c966440a..e3ecaae953a6b 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -20,30 +20,30 @@ use middle::region; use traits; use ty; -impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for &'gcx ty::Slice<T> - where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> { + where T: HashStable<StableHashingContext<'gcx>> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { (&self[..]).hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::subst::Kind<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { self.as_type().hash_stable(hcx, hasher); self.as_region().hash_stable(hcx, hasher); } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::RegionKind { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -81,10 +81,10 @@ for ty::RegionKind { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::adjustment::AutoBorrow<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -99,10 +99,10 @@ for ty::adjustment::AutoBorrow<'gcx> { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::adjustment::Adjust<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -134,10 +134,10 @@ impl_stable_hash_for!(enum ty::BorrowKind { MutBorrow }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::UpvarCapture<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -161,11 +161,11 @@ impl_stable_hash_for!(struct ty::FnSig<'tcx> { abi }); -impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Binder<T> - where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for ty::Binder<T> + where T: HashStable<StableHashingContext<'gcx>> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::Binder(ref inner) = *self; inner.hash_stable(hcx, hasher); @@ -185,13 +185,13 @@ impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref }); impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 }); impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b }); -impl<'a, 'gcx, 'tcx, A, B> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, A, B> HashStable<StableHashingContext<'gcx>> for ty::OutlivesPredicate<A, B> - where A: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, - B: HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, + where A: HashStable<StableHashingContext<'gcx>>, + B: HashStable<StableHashingContext<'gcx>>, { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::OutlivesPredicate(ref a, ref b) = *self; a.hash_stable(hcx, hasher); @@ -203,9 +203,9 @@ impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty } impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Predicate<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::Predicate<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -245,9 +245,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Pr } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::AdtFlags { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::AdtFlags { fn hash_stable<W: StableHasherResult>(&self, - _: &mut StableHashingContext<'a, 'gcx, 'tcx>, + _: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { std_hash::Hash::hash(self, hasher); } @@ -272,10 +272,10 @@ impl_stable_hash_for!(struct ty::FieldDef { vis }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ::middle::const_val::ConstVal<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use middle::const_val::ConstVal::*; use middle::const_val::ConstAggregate::*; @@ -347,10 +347,10 @@ impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> { kind }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ::middle::const_val::ErrKind<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use middle::const_val::ErrKind::*; @@ -410,9 +410,9 @@ impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized { Struct(index) }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Generics { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::Generics { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::Generics { parent, @@ -438,10 +438,10 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Ge } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::RegionParameterDef { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::RegionParameterDef { name, @@ -466,12 +466,12 @@ impl_stable_hash_for!(struct ty::TypeParameterDef { pure_wrt_drop }); -impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for ::middle::resolve_lifetime::Set1<T> - where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + where T: HashStable<StableHashingContext<'gcx>> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use middle::resolve_lifetime::Set1; @@ -522,11 +522,11 @@ impl_stable_hash_for!(enum ::middle::region::Scope { Remainder(block_remainder) }); -impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for region::Scope { +impl<'gcx> ToStableHashKey<StableHashingContext<'gcx>> for region::Scope { type KeyType = region::Scope; #[inline] - fn to_stable_hash_key(&self, _: &StableHashingContext<'a, 'gcx, 'tcx>) -> region::Scope { + fn to_stable_hash_key(&self, _: &StableHashingContext<'gcx>) -> region::Scope { *self } } @@ -552,11 +552,11 @@ impl_stable_hash_for!(enum ty::BoundRegion { BrEnv }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::TypeVariants<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use ty::TypeVariants::*; @@ -648,11 +648,11 @@ impl_stable_hash_for!(struct ty::TypeAndMut<'tcx> { mutbl }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::ExistentialPredicate<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { @@ -685,9 +685,9 @@ impl_stable_hash_for!(struct ty::Instance<'tcx> { substs }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::InstanceDef<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::InstanceDef<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); @@ -721,9 +721,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::In } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::TraitDef { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::TraitDef { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::TraitDef { // We already have the def_path_hash below, no need to hash it twice @@ -751,9 +751,9 @@ impl_stable_hash_for!(struct ty::DtorckConstraint<'tcx> { }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::CrateVariancesMap { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::CrateVariancesMap { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::CrateVariancesMap { ref dependencies, @@ -789,12 +789,12 @@ impl_stable_hash_for!(enum ty::AssociatedItemContainer { }); -impl<'a, 'gcx, 'tcx, T> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for ty::steal::Steal<T> - where T: HashStable<StableHashingContext<'a, 'gcx, 'tcx>> + where T: HashStable<StableHashingContext<'gcx>> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { self.borrow().hash_stable(hcx, hasher); } @@ -816,10 +816,10 @@ impl_stable_hash_for!(enum ::middle::privacy::AccessLevel { Public }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ::middle::privacy::AccessLevels { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { let ::middle::privacy::AccessLevels { diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index eb2b136e417d3..21dfd3267df51 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -386,10 +386,10 @@ impl LintLevelMap { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LintLevelMap { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for LintLevelMap { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let LintLevelMap { ref sets, diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs index f3d66b49de5a8..f0285d6a93782 100644 --- a/src/librustc/macros.rs +++ b/src/librustc/macros.rs @@ -73,10 +73,10 @@ macro_rules! __impl_stable_hash_field { #[macro_export] macro_rules! impl_stable_hash_for { (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* }) => { - impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $enum_name { + impl<'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'tcx>> for $enum_name { #[inline] fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self, - __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>, + __ctx: &mut $crate::ich::StableHashingContext<'tcx>, __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) { use $enum_name::*; ::std::mem::discriminant(self).hash_stable(__ctx, __hasher); @@ -92,10 +92,10 @@ macro_rules! impl_stable_hash_for { } }; (struct $struct_name:path { $($field:ident),* }) => { - impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $struct_name { + impl<'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'tcx>> for $struct_name { #[inline] fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self, - __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>, + __ctx: &mut $crate::ich::StableHashingContext<'tcx>, __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) { let $struct_name { $(ref $field),* @@ -106,10 +106,10 @@ macro_rules! impl_stable_hash_for { } }; (tuple_struct $struct_name:path { $($field:ident),* }) => { - impl<'a, 'tcx, 'lcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx, 'lcx>> for $struct_name { + impl<'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'tcx>> for $struct_name { #[inline] fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self, - __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx, 'lcx>, + __ctx: &mut $crate::ich::StableHashingContext<'tcx>, __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) { let $struct_name ( $(ref $field),* @@ -125,11 +125,11 @@ macro_rules! impl_stable_hash_for { macro_rules! impl_stable_hash_for_spanned { ($T:path) => ( - impl<'a, 'tcx, 'lcx> HashStable<StableHashingContext<'a, 'tcx, 'lcx>> for ::syntax::codemap::Spanned<$T> + impl<'tcx> HashStable<StableHashingContext<'tcx>> for ::syntax::codemap::Spanned<$T> { #[inline] fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'tcx, 'lcx>, + hcx: &mut StableHashingContext<'tcx>, hasher: &mut StableHasher<W>) { self.node.hash_stable(hcx, hasher); self.span.hash_stable(hcx, hasher); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 5c6feddb1fdf2..5b286c6593b7a 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1239,9 +1239,9 @@ pub fn provide(providers: &mut Providers) { }; } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ScopeTree { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ScopeTree { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ScopeTree { root_body, diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 73c702fedb816..efc2f647cfdf5 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -35,9 +35,9 @@ impl serialize::Decodable for Cache { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Cache { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for Cache { fn hash_stable<W: StableHasherResult>(&self, - _: &mut StableHashingContext<'a, 'gcx, 'tcx>, + _: &mut StableHashingContext<'gcx>, _: &mut StableHasher<W>) { // do nothing } diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 6895e0e8a3456..0651d1904bf06 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -369,9 +369,9 @@ pub fn ancestors(tcx: TyCtxt, } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Children { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for Children { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let Children { ref nonblanket_impls, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 61cd5db9a1948..8005714433f5e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -687,9 +687,9 @@ impl<'tcx> TypeckTables<'tcx> { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for TypeckTables<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for TypeckTables<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::TypeckTables { local_id_root, @@ -1225,6 +1225,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Rc<Any> { self.cstore.crate_data_as_rc_any(cnum) } + + pub fn create_stable_hashing_context(self) -> StableHashingContext<'gcx> { + let krate = self.dep_graph.with_ignore(|| self.gcx.hir.krate()); + + StableHashingContext::new(self.sess, + krate, + self.hir.definitions(), + self.cstore) + } } impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 86ae4bb92df07..490bfe78a9a1f 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -144,12 +144,12 @@ impl<D: Copy + Debug + Ord + Eq + Hash> SimplifiedTypeGen<D> { } } -impl<'a, 'gcx, 'tcx, D> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for SimplifiedTypeGen<D> +impl<'gcx, D> HashStable<StableHashingContext<'gcx>> for SimplifiedTypeGen<D> where D: Copy + Debug + Ord + Eq + Hash + - HashStable<StableHashingContext<'a, 'gcx, 'tcx>>, + HashStable<StableHashingContext<'gcx>>, { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 1ae1e7007ac5e..1709f9ed2df1c 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -2306,10 +2306,10 @@ impl<'a, 'tcx> TyLayout<'tcx> { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for Layout +impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use ty::layout::Layout::*; mem::discriminant(self).hash_stable(hcx, hasher); @@ -2399,10 +2399,10 @@ impl_stable_hash_for!(struct ::ty::layout::Size { raw }); -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for LayoutError<'gcx> +impl<'gcx> HashStable<StableHashingContext<'gcx>> for LayoutError<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { use ty::layout::LayoutError::*; mem::discriminant(self).hash_stable(hcx, hasher); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index da00f12edacb0..32d8a5114a79d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -500,9 +500,9 @@ impl<'tcx> TyS<'tcx> { } } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::TyS<'gcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::TyS<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::TyS { ref sty, @@ -1334,9 +1334,9 @@ impl<'tcx> serialize::UseSpecializedEncodable for &'tcx AdtDef { impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {} -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for AdtDef { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for AdtDef { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let ty::AdtDef { did, diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 9ae6c3516a5cf..e0b05c2ba39ac 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -186,9 +186,9 @@ pub(super) fn trait_impls_of_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }) } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for TraitImpls { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for TraitImpls { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let TraitImpls { ref blanket_impls, diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 16ae3cdbf1796..27819f551b9b3 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -12,7 +12,7 @@ use hir::def_id::{DefId, LOCAL_CRATE}; use hir::map::DefPathData; -use ich::{StableHashingContext, NodeIdHashingMode}; +use ich::NodeIdHashingMode; use middle::const_val::ConstVal; use traits::{self, Reveal}; use ty::{self, Ty, TyCtxt, TypeFoldable}; @@ -214,7 +214,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { /// context it's calculated within. This is used by the `type_id` intrinsic. pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 { let mut hasher = StableHasher::new(); - let mut hcx = StableHashingContext::new(self); + let mut hcx = self.create_stable_hashing_context(); // We want the type_id be independent of the types free regions, so we // erase them. The erase_regions() call will also anonymize bound diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 32a160bcffcef..d50d3deb67347 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -175,7 +175,7 @@ pub fn compile_input(sess: &Session, // Construct the HIR map let hir_map = time(sess.time_passes(), "indexing hir", - || hir_map::map_crate(&mut hir_forest, defs)); + || hir_map::map_crate(&mut hir_forest, &defs)); { let _ignore = hir_map.dep_graph.in_ignore(); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 34f4e0e7b0c95..daabf481e461f 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -133,7 +133,7 @@ fn test_env<F>(source_string: &str, let arena = DroplessArena::new(); let arenas = ty::GlobalArenas::new(); - let hir_map = hir_map::map_crate(&mut hir_forest, defs); + let hir_map = hir_map::map_crate(&mut hir_forest, &defs); // run just enough stuff to build a tcx: let named_region_map = resolve_lifetime::krate(&sess, &*cstore, &hir_map); diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index 60e1f238f44a4..0329aa8d6741b 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -91,7 +91,7 @@ impl<'a> ::std::ops::Index<&'a DepNode> for IncrementalHashesMap { struct ComputeItemHashesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - hcx: StableHashingContext<'a, 'tcx, 'tcx>, + hcx: StableHashingContext<'tcx>, hashes: IncrementalHashesMap, } @@ -100,7 +100,7 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { def_index: DefIndex, hash_bodies: bool, item_like: T) - where T: HashStable<StableHashingContext<'a, 'tcx, 'tcx>> + where T: HashStable<StableHashingContext<'tcx>> { if !hash_bodies && !self.tcx.sess.opts.build_dep_graph() { // If we just need the hashes in order to compute the SVH, we don't @@ -303,7 +303,7 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) let mut visitor = ComputeItemHashesVisitor { tcx, - hcx: StableHashingContext::new(tcx), + hcx: tcx.create_stable_hashing_context(), hashes: IncrementalHashesMap::new(), }; diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 3bc281e5486a8..d9ab2562efff2 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -16,7 +16,7 @@ use schema::*; use rustc::hir; use rustc::ty::{self, TyCtxt}; -use rustc::ich::{StableHashingContext, Fingerprint}; +use rustc::ich::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[derive(RustcEncodable, RustcDecodable)] @@ -43,7 +43,7 @@ impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> { // In order to avoid having to hash hir::Bodies from extern crates, we // hash them here, during export, and store the hash with metadata. let stable_bodies_hash = { - let mut hcx = StableHashingContext::new(self.tcx); + let mut hcx = self.tcx.create_stable_hashing_context(); let mut hasher = StableHasher::new(); hcx.while_hashing_hir_bodies(true, |hcx| { diff --git a/src/librustc_metadata/isolated_encoder.rs b/src/librustc_metadata/isolated_encoder.rs index b9ad9086c039a..7dc50fe29df07 100644 --- a/src/librustc_metadata/isolated_encoder.rs +++ b/src/librustc_metadata/isolated_encoder.rs @@ -23,7 +23,7 @@ use rustc_serialize::Encodable; pub struct IsolatedEncoder<'a, 'b: 'a, 'tcx: 'b> { pub tcx: TyCtxt<'b, 'tcx, 'tcx>, ecx: &'a mut EncodeContext<'b, 'tcx>, - hcx: Option<(StableHashingContext<'b, 'tcx, 'tcx>, StableHasher<Fingerprint>)>, + hcx: Option<(StableHashingContext<'tcx>, StableHasher<Fingerprint>)>, } impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { @@ -40,9 +40,9 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { // Except when -Zquery-dep-graph is specified because we don't // want to mess up our tests. let hcx = if tcx.sess.opts.debugging_opts.query_dep_graph { - StableHashingContext::new(tcx) + tcx.create_stable_hashing_context() } else { - StableHashingContext::new(tcx).force_span_hashing() + tcx.create_stable_hashing_context().force_span_hashing() }; Some((hcx, StableHasher::new())) @@ -61,7 +61,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } pub fn lazy<T>(&mut self, value: &T) -> Lazy<T> - where T: Encodable + HashStable<StableHashingContext<'b, 'tcx, 'tcx>> + where T: Encodable + HashStable<StableHashingContext<'tcx>> { if let Some((ref mut hcx, ref mut hasher)) = self.hcx { value.hash_stable(hcx, hasher); @@ -72,7 +72,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { pub fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T> where I: IntoIterator<Item = T>, - T: Encodable + HashStable<StableHashingContext<'b, 'tcx, 'tcx>> + T: Encodable + HashStable<StableHashingContext<'tcx>> { if let Some((ref mut hcx, ref mut hasher)) = self.hcx { let iter = iter.into_iter(); @@ -111,7 +111,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { pub fn lazy_seq_ref<'x, I, T>(&mut self, iter: I) -> LazySeq<T> where I: IntoIterator<Item = &'x T>, - T: 'x + Encodable + HashStable<StableHashingContext<'b, 'tcx, 'tcx>> + T: 'x + Encodable + HashStable<StableHashingContext<'tcx>> { if let Some((ref mut hcx, ref mut hasher)) = self.hcx { let iter = iter.into_iter(); @@ -149,7 +149,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } pub fn lazy_seq_from_slice<T>(&mut self, slice: &[T]) -> LazySeq<T> - where T: Encodable + HashStable<StableHashingContext<'b, 'tcx, 'tcx>> + where T: Encodable + HashStable<StableHashingContext<'tcx>> { if let Some((ref mut hcx, ref mut hasher)) = self.hcx { slice.hash_stable(hcx, hasher); @@ -159,7 +159,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } pub fn lazy_seq_ref_from_slice<T>(&mut self, slice: &[&T]) -> LazySeq<T> - where T: Encodable + HashStable<StableHashingContext<'b, 'tcx, 'tcx>> + where T: Encodable + HashStable<StableHashingContext<'tcx>> { if let Some((ref mut hcx, ref mut hasher)) = self.hcx { slice.hash_stable(hcx, hasher); diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index ee196d74bb814..dad0d26d2715d 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -229,9 +229,9 @@ pub struct TraitImpls { pub impls: LazySeq<DefIndex>, } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for TraitImpls { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for TraitImpls { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { let TraitImpls { trait_id: (krate, def_index), @@ -312,9 +312,9 @@ pub enum EntryKind<'tcx> { AssociatedConst(AssociatedContainer, u8), } -impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for EntryKind<'tcx> { +impl<'gcx> HashStable<StableHashingContext<'gcx>> for EntryKind<'gcx> { fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, + hcx: &mut StableHashingContext<'gcx>, hasher: &mut StableHasher<W>) { mem::discriminant(self).hash_stable(hcx, hasher); match *self { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 40fc07cfd4f62..7e75eb9c78bab 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -141,10 +141,10 @@ impl<'a, 'tcx> DepGraphSafe for SharedCrateContext<'a, 'tcx> { } impl<'a, 'tcx> StableHashingContextProvider for SharedCrateContext<'a, 'tcx> { - type ContextType = StableHashingContext<'a, 'tcx, 'tcx>; + type ContextType = StableHashingContext<'tcx>; fn create_stable_hashing_context(&self) -> Self::ContextType { - StableHashingContext::new(self.tcx) + self.tcx.create_stable_hashing_context() } } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 4918dd78b3793..29da763f334c7 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -141,10 +141,10 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> { } impl<'a, 'tcx> StableHashingContextProvider for ConstraintContext<'a, 'tcx> { - type ContextType = StableHashingContext<'a, 'tcx, 'tcx>; + type ContextType = StableHashingContext<'tcx>; fn create_stable_hashing_context(&self) -> Self::ContextType { - StableHashingContext::new(self.terms_cx.tcx) + self.terms_cx.tcx.create_stable_hashing_context() } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 277e2909ba9ed..1663e5ad14286 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -175,7 +175,7 @@ pub fn run_core(search_paths: SearchPaths, let arena = DroplessArena::new(); let arenas = GlobalArenas::new(); - let hir_map = hir_map::map_crate(&mut hir_forest, defs); + let hir_map = hir_map::map_crate(&mut hir_forest, &defs); let output_filenames = driver::build_output_filenames(&input, &None, &None, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 95c0f5f5d6364..36efc37a8095c 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -124,7 +124,7 @@ pub fn run(input: &str, render_type); { - let map = hir::map::map_crate(&mut hir_forest, defs); + let map = hir::map::map_crate(&mut hir_forest, &defs); let krate = map.krate(); let mut hir_collector = HirCollector { sess: &sess, From 74d6b850fd731597fe2f03408a0397a972c13641 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Mon, 18 Sep 2017 12:14:52 +0200 Subject: [PATCH 22/24] incr.comp.: Fix rebase fallout. --- src/librustc/ich/hcx.rs | 4 +- .../error_reporting/different_lifetimes.rs | 12 +-- src/librustc/middle/exported_symbols.rs | 5 ++ src/librustc/middle/trans.rs | 79 +++++++++++++++++++ src/librustc/session/config.rs | 33 ++++++++ src/librustc_data_structures/stable_hasher.rs | 8 ++ src/librustc_trans/base.rs | 25 ++---- src/librustc_trans/context.rs | 3 +- 8 files changed, 138 insertions(+), 31 deletions(-) diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index 0a2566f069249..64fc63002da1f 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -15,7 +15,7 @@ use hir::map::definitions::Definitions; use ich::{self, CachingCodemapView}; use middle::cstore::CrateStore; use session::config::DebugInfoLevel::NoDebugInfo; -use ty::{self, TyCtxt, fast_reject}; +use ty::{TyCtxt, fast_reject}; use session::Session; use std::cmp::Ord; @@ -252,7 +252,7 @@ impl<'gcx> StableHashingContext<'gcx> { } } -impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx> { +impl<'a, 'gcx, 'lcx> StableHashingContextProvider for TyCtxt<'a, 'gcx, 'lcx> { type ContextType = StableHashingContext<'gcx>; fn create_stable_hashing_context(&self) -> Self::ContextType { (*self).create_stable_hashing_context() diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index ef28b5b42b0dd..6c57130a9955f 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -332,10 +332,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { (Some(rl::Region::EarlyBound(_, id)), ty::BrNamed(def_id, _)) => { debug!("EarlyBound self.infcx.tcx.hir.local_def_id(id)={:?} \ - def_id={:?}", - self.infcx.tcx.hir.local_def_id(id), - def_id); - if self.infcx.tcx.hir.local_def_id(id) == def_id { + def_id={:?}", id, def_id); + if id == def_id { self.found_it = true; return; // we can stop visiting now } @@ -344,11 +342,9 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for TyPathVisitor<'a, 'gcx, 'tcx> { (Some(rl::Region::LateBound(debruijn_index, id)), ty::BrNamed(def_id, _)) => { debug!("FindNestedTypeVisitor::visit_ty: LateBound depth = {:?}", debruijn_index.depth); - debug!("self.infcx.tcx.hir.local_def_id(id)={:?}", - self.infcx.tcx.hir.local_def_id(id)); + debug!("id={:?}", id); debug!("def_id={:?}", def_id); - if debruijn_index.depth == self.depth && - self.infcx.tcx.hir.local_def_id(id) == def_id { + if debruijn_index.depth == self.depth && id == def_id { self.found_it = true; return; // we can stop visiting now } diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs index 230878f854595..d650dbe88b5c8 100644 --- a/src/librustc/middle/exported_symbols.rs +++ b/src/librustc/middle/exported_symbols.rs @@ -19,6 +19,11 @@ pub enum SymbolExportLevel { Rust, } +impl_stable_hash_for!(enum self::SymbolExportLevel { + C, + Rust +}); + impl SymbolExportLevel { pub fn is_below_threshold(self, threshold: SymbolExportLevel) -> bool { if threshold == SymbolExportLevel::Rust { diff --git a/src/librustc/middle/trans.rs b/src/librustc/middle/trans.rs index 9a50125754846..7744c9c3d1238 100644 --- a/src/librustc/middle/trans.rs +++ b/src/librustc/middle/trans.rs @@ -12,6 +12,9 @@ use syntax::ast::NodeId; use syntax::symbol::InternedString; use ty::Instance; use util::nodemap::FxHashMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasherResult, + StableHasher}; +use ich::{Fingerprint, StableHashingContext, NodeIdHashingMode}; #[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)] pub enum TransItem<'tcx> { @@ -20,6 +23,26 @@ pub enum TransItem<'tcx> { GlobalAsm(NodeId), } +impl<'tcx> HashStable<StableHashingContext<'tcx>> for TransItem<'tcx> { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'tcx>, + hasher: &mut StableHasher<W>) { + ::std::mem::discriminant(self).hash_stable(hcx, hasher); + + match *self { + TransItem::Fn(ref instance) => { + instance.hash_stable(hcx, hasher); + } + TransItem::Static(node_id) | + TransItem::GlobalAsm(node_id) => { + hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { + node_id.hash_stable(hcx, hasher); + }) + } + } + } +} + pub struct CodegenUnit<'tcx> { /// A name for this CGU. Incremental compilation requires that /// name be unique amongst **all** crates. Therefore, it should @@ -44,6 +67,20 @@ pub enum Linkage { Common, } +impl_stable_hash_for!(enum self::Linkage { + External, + AvailableExternally, + LinkOnceAny, + LinkOnceODR, + WeakAny, + WeakODR, + Appending, + Internal, + Private, + ExternalWeak, + Common +}); + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Visibility { Default, @@ -51,6 +88,12 @@ pub enum Visibility { Protected, } +impl_stable_hash_for!(enum self::Visibility { + Default, + Hidden, + Protected +}); + impl<'tcx> CodegenUnit<'tcx> { pub fn new(name: InternedString) -> CodegenUnit<'tcx> { CodegenUnit { @@ -78,6 +121,29 @@ impl<'tcx> CodegenUnit<'tcx> { } } +impl<'tcx> HashStable<StableHashingContext<'tcx>> for CodegenUnit<'tcx> { + fn hash_stable<W: StableHasherResult>(&self, + hcx: &mut StableHashingContext<'tcx>, + hasher: &mut StableHasher<W>) { + let CodegenUnit { + ref items, + name, + } = *self; + + name.hash_stable(hcx, hasher); + + let mut items: Vec<(Fingerprint, _)> = items.iter().map(|(trans_item, &attrs)| { + let mut hasher = StableHasher::new(); + trans_item.hash_stable(hcx, &mut hasher); + let trans_item_fingerprint = hasher.finish(); + (trans_item_fingerprint, attrs) + }).collect(); + + items.sort_unstable_by_key(|i| i.0); + items.hash_stable(hcx, hasher); + } +} + #[derive(Clone, Default)] pub struct Stats { pub n_glues_created: usize, @@ -92,6 +158,18 @@ pub struct Stats { pub fn_stats: Vec<(String, usize)>, } +impl_stable_hash_for!(struct self::Stats { + n_glues_created, + n_null_glues, + n_real_glues, + n_fns, + n_inlines, + n_closures, + n_llvm_insns, + llvm_insns, + fn_stats +}); + impl Stats { pub fn extend(&mut self, stats: Stats) { self.n_glues_created += stats.n_glues_created; @@ -108,3 +186,4 @@ impl Stats { self.fn_stats.extend(stats.fn_stats); } } + diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index df2de17f1e471..f079d7d43389a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -19,8 +19,10 @@ pub use self::DebugInfoLevel::*; use session::{early_error, early_warn, Session}; use session::search_paths::SearchPaths; +use ich::StableHashingContext; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; use rustc_back::target::Target; +use rustc_data_structures::stable_hasher::ToStableHashKey; use lint; use middle::cstore; @@ -90,6 +92,25 @@ pub enum OutputType { DepInfo, } +impl_stable_hash_for!(enum self::OutputType { + Bitcode, + Assembly, + LlvmAssembly, + Mir, + Metadata, + Object, + Exe, + DepInfo +}); + +impl<'tcx> ToStableHashKey<StableHashingContext<'tcx>> for OutputType { + type KeyType = OutputType; + #[inline] + fn to_stable_hash_key(&self, _: &StableHashingContext<'tcx>) -> Self::KeyType { + *self + } +} + impl OutputType { fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool { match *self { @@ -149,6 +170,10 @@ impl Default for ErrorOutputType { #[derive(Clone, Hash)] pub struct OutputTypes(BTreeMap<OutputType, Option<PathBuf>>); +impl_stable_hash_for!(tuple_struct self::OutputTypes { + map +}); + impl OutputTypes { pub fn new(entries: &[(OutputType, Option<PathBuf>)]) -> OutputTypes { OutputTypes(BTreeMap::from_iter(entries.iter() @@ -373,6 +398,14 @@ pub struct OutputFilenames { pub outputs: OutputTypes, } +impl_stable_hash_for!(struct self::OutputFilenames { + out_directory, + out_filestem, + single_output_file, + extra, + outputs +}); + /// Codegen unit names generated by the numbered naming scheme will contain this /// marker right before the index of the codegen unit. pub const NUMBERED_CODEGEN_UNIT_MARKER: &'static str = ".cgu-"; diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index e18c1969a91cc..f6b23af2f7374 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -386,6 +386,14 @@ impl<CTX> HashStable<CTX> for String { } } +impl<HCX> ToStableHashKey<HCX> for String { + type KeyType = String; + #[inline] + fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType { + self.clone() + } +} + impl<CTX> HashStable<CTX> for bool { #[inline] fn hash_stable<W: StableHasherResult>(&self, diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 1e1b9929f0e37..ba15f3522ac1f 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -41,7 +41,6 @@ use rustc::middle::trans::{Linkage, Visibility, Stats}; use rustc::middle::cstore::{EncodedMetadata, EncodedMetadataHashes}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::Providers; -use rustc::dep_graph::AssertDepGraphSafe; use rustc::middle::cstore::{self, LinkMeta, LinkagePreference}; use rustc::hir::map as hir_map; use rustc::util::common::{time, print_time_passes_entry}; @@ -894,7 +893,7 @@ fn iter_globals(llmod: llvm::ModuleRef) -> ValueIter { /// This list is later used by linkers to determine the set of symbols needed to /// be exposed from a dynamic library and it's also encoded into the metadata. pub fn find_exported_symbols(tcx: TyCtxt) -> NodeSet { - tcx.reachable_set(LOCAL_CRATE).iter().cloned().filter(|&id| { + tcx.reachable_set(LOCAL_CRATE).0.iter().cloned().filter(|&id| { // Next, we want to ignore some FFI functions that are not exposed from // this crate. Reachable FFI functions can be lumped into two // categories: @@ -1370,8 +1369,8 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let dep_node = cgu.work_product_dep_node(); let ((stats, module), _) = tcx.dep_graph.with_task(dep_node, - AssertDepGraphSafe(tcx), - AssertDepGraphSafe(cgu), + tcx, + cgu, module_translation); let time_to_translate = start_time.elapsed(); @@ -1392,14 +1391,10 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, return stats; fn module_translation<'a, 'tcx>( - tcx: AssertDepGraphSafe<TyCtxt<'a, 'tcx, 'tcx>>, - args: AssertDepGraphSafe<Arc<CodegenUnit<'tcx>>>) + tcx: TyCtxt<'a, 'tcx, 'tcx>, + cgu: Arc<CodegenUnit<'tcx>>) -> (Stats, ModuleTranslation) { - // FIXME(#40304): We ought to be using the id as a key and some queries, I think. - let AssertDepGraphSafe(tcx) = tcx; - let AssertDepGraphSafe(cgu) = args; - let cgu_name = cgu.name().to_string(); let cgu_id = cgu.work_product_id(); let symbol_name_hash = cgu.compute_symbol_name_hash(tcx); @@ -1564,6 +1559,7 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { Visibility::Default => llvm::Visibility::Default, Visibility::Hidden => llvm::Visibility::Hidden, Visibility::Protected => llvm::Visibility::Protected, + } } // FIXME(mw): Anything that is produced via DepGraph::with_task() must implement @@ -1577,17 +1573,8 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { mod temp_stable_hash_impls { use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, HashStable}; - use context::Stats; use ModuleTranslation; - impl<HCX> HashStable<HCX> for Stats { - fn hash_stable<W: StableHasherResult>(&self, - _: &mut HCX, - _: &mut StableHasher<W>) { - // do nothing - } - } - impl<HCX> HashStable<HCX> for ModuleTranslation { fn hash_stable<W: StableHasherResult>(&self, _: &mut HCX, diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 7e75eb9c78bab..b394911c9234d 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -27,9 +27,8 @@ use type_::Type; use rustc_data_structures::base_n; use rustc::middle::trans::Stats; use rustc_data_structures::stable_hasher::StableHashingContextProvider; -use rustc::session::config::{self, NoDebugInfo, OutputFilenames}; -use rustc::session::Session; use rustc::session::config::{self, NoDebugInfo}; +use rustc::session::Session; use rustc::ty::layout::{LayoutCx, LayoutError, LayoutTyper, TyLayout}; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; From 4961a8e2bd8a6d2144ee90b4ec568a1c5b7a3241 Mon Sep 17 00:00:00 2001 From: Michael Woerister <michaelwoerister@posteo> Date: Mon, 18 Sep 2017 13:14:38 +0200 Subject: [PATCH 23/24] incr.comp.: Fix ICE caused by trying to hash INVALID_CRATE_NUM. --- src/librustc/ty/maps.rs | 2 +- src/librustc_trans/back/symbol_export.rs | 33 +++++++++++------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 5207aaa0c5b2f..c0045483ced47 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -1417,7 +1417,7 @@ define_maps! { <'tcx> [] fn all_crate_nums: all_crate_nums_node(CrateNum) -> Rc<Vec<CrateNum>>, [] fn exported_symbols: ExportedSymbols(CrateNum) - -> Arc<Vec<(String, DefId, SymbolExportLevel)>>, + -> Arc<Vec<(String, Option<DefId>, SymbolExportLevel)>>, [] fn collect_and_partition_translation_items: collect_and_partition_translation_items_node(CrateNum) -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>), diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index 844442edbc872..e1f97e2c923db 100644 --- a/src/librustc_trans/back/symbol_export.rs +++ b/src/librustc_trans/back/symbol_export.rs @@ -14,7 +14,7 @@ use std::sync::Arc; use base; use monomorphize::Instance; use rustc::hir::def_id::CrateNum; -use rustc::hir::def_id::{DefId, LOCAL_CRATE, INVALID_CRATE, CRATE_DEF_INDEX}; +use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::exported_symbols::SymbolExportLevel; use rustc::session::config; use rustc::ty::TyCtxt; @@ -24,7 +24,7 @@ use rustc_allocator::ALLOCATOR_METHODS; pub type ExportedSymbols = FxHashMap< CrateNum, - Arc<Vec<(String, DefId, SymbolExportLevel)>>, + Arc<Vec<(String, Option<DefId>, SymbolExportLevel)>>, >; pub fn threshold(tcx: TyCtxt) -> SymbolExportLevel { @@ -65,11 +65,13 @@ pub fn provide_local(providers: &mut Providers) { Rc::new(tcx.exported_symbols(cnum) .iter() .filter_map(|&(_, id, level)| { - if level.is_below_threshold(export_threshold) { - Some(id) - } else { - None - } + id.and_then(|id| { + if level.is_below_threshold(export_threshold) { + Some(id) + } else { + None + } + }) }) .collect()) }; @@ -95,25 +97,20 @@ pub fn provide_local(providers: &mut Providers) { let name = tcx.symbol_name(Instance::mono(tcx, def_id)); let export_level = export_level(tcx, def_id); debug!("EXPORTED SYMBOL (local): {} ({:?})", name, export_level); - (str::to_owned(&name), def_id, export_level) + (str::to_owned(&name), Some(def_id), export_level) }) .collect(); - const INVALID_DEF_ID: DefId = DefId { - krate: INVALID_CRATE, - index: CRATE_DEF_INDEX, - }; - if let Some(_) = *tcx.sess.entry_fn.borrow() { local_crate.push(("main".to_string(), - INVALID_DEF_ID, + None, SymbolExportLevel::C)); } if tcx.sess.allocator_kind.get().is_some() { for method in ALLOCATOR_METHODS { local_crate.push((format!("__rust_{}", method.name), - INVALID_DEF_ID, + None, SymbolExportLevel::Rust)); } } @@ -123,12 +120,12 @@ pub fn provide_local(providers: &mut Providers) { let idx = def_id.index; let disambiguator = tcx.sess.local_crate_disambiguator(); let registrar = tcx.sess.generate_derive_registrar_symbol(disambiguator, idx); - local_crate.push((registrar, def_id, SymbolExportLevel::C)); + local_crate.push((registrar, Some(def_id), SymbolExportLevel::C)); } if tcx.sess.crate_types.borrow().contains(&config::CrateTypeDylib) { local_crate.push((metadata_symbol_name(tcx), - INVALID_DEF_ID, + None, SymbolExportLevel::Rust)); } Arc::new(local_crate) @@ -178,7 +175,7 @@ pub fn provide_extern(providers: &mut Providers) { export_level(tcx, def_id) }; debug!("EXPORTED SYMBOL (re-export): {} ({:?})", name, export_level); - (str::to_owned(&name), def_id, export_level) + (str::to_owned(&name), Some(def_id), export_level) }) .collect(); From 90ce24ab699bc44ab2474fa6bf22fde5ead180e9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume1.gomez@gmail.com> Date: Mon, 18 Sep 2017 12:51:48 +0200 Subject: [PATCH 24/24] Fix run button --- src/librustdoc/html/static/rustdoc.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index c15051376bf27..b1aac2da1c2f7 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -817,6 +817,7 @@ span.since { position: absolute; left: -1px; margin-top: 7px; + z-index: 1; } .tooltip { @@ -853,3 +854,7 @@ span.since { border-style: solid; border-color: transparent black transparent transparent; } + +pre.rust { + position: relative; +}