Auto merge of #55912 - kennytm:rollup, r=kennytm
Rollup of 20 pull requests Successful merges: - #55136 (Remove short doc where it starts with a codeblock) - #55711 (Format BtreeMap::range_mut example) - #55722 (impl_stable_hash_for: support enums and tuple structs with generic parameters) - #55754 (Avoid converting bytes to UTF-8 strings to print, just pass bytes to stdout/err) - #55804 (rustdoc: don't inline `pub use some_crate` unless directly asked to) - #55805 (Move `static_assert!` into librustc_data_structures) - #55837 (Make PhantomData #[structural_match]) - #55840 (Fix TLS errors when downloading stage0) - #55843 (add FromIterator<A> to Box<[A]>) - #55858 (Small fixes on code blocks in rustdoc) - #55863 (Fix a typo in std::panic) - #55870 (Fix typos.) - #55874 (string: Add documentation for `From` impls) - #55879 (save-analysis: Don't panic for macro-generated use globs) - #55882 (Reference count `crate_inherent_impls`s return value.) - #55888 (miri: for uniformity, also move memory_deallocated to AllocationExtra) - #55889 (global allocators: add a few comments) - #55896 (Document optimizations enabled by FusedIterator) - #55905 (Change `Lit::short_name` to `Lit::literal_name`.) - #55908 (Fix their/there grammar nit)
This commit is contained in:
commit
f1d61837d1
62 changed files with 613 additions and 519 deletions
|
@ -5,7 +5,7 @@ This directory contains the source code of the rust project, including:
|
||||||
|
|
||||||
For more information on how various parts of the compiler work, see the [rustc guide].
|
For more information on how various parts of the compiler work, see the [rustc guide].
|
||||||
|
|
||||||
Their is also useful content in the following READMEs, which are gradually being moved over to the guide:
|
There is also useful content in the following READMEs, which are gradually being moved over to the guide:
|
||||||
- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/query
|
- https://github.com/rust-lang/rust/tree/master/src/librustc/ty/query
|
||||||
- https://github.com/rust-lang/rust/tree/master/src/librustc/dep_graph
|
- https://github.com/rust-lang/rust/tree/master/src/librustc/dep_graph
|
||||||
- https://github.com/rust-lang/rust/blob/master/src/librustc/infer/region_constraints
|
- https://github.com/rust-lang/rust/blob/master/src/librustc/infer/region_constraints
|
||||||
|
|
|
@ -79,8 +79,8 @@ def _download(path, url, probably_big, verbose, exception):
|
||||||
# see http://serverfault.com/questions/301128/how-to-download
|
# see http://serverfault.com/questions/301128/how-to-download
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
run(["PowerShell.exe", "/nologo", "-Command",
|
run(["PowerShell.exe", "/nologo", "-Command",
|
||||||
"(New-Object System.Net.WebClient)"
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
|
||||||
".DownloadFile('{}', '{}')".format(url, path)],
|
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)],
|
||||||
verbose=verbose,
|
verbose=verbose,
|
||||||
exception=exception)
|
exception=exception)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -203,7 +203,7 @@ impl Step for StdLink {
|
||||||
|
|
||||||
/// Link all libstd rlibs/dylibs into the sysroot location.
|
/// Link all libstd rlibs/dylibs into the sysroot location.
|
||||||
///
|
///
|
||||||
/// Links those artifacts generated by `compiler` to a the `stage` compiler's
|
/// Links those artifacts generated by `compiler` to the `stage` compiler's
|
||||||
/// sysroot for the specified `host` and `target`.
|
/// sysroot for the specified `host` and `target`.
|
||||||
///
|
///
|
||||||
/// Note that this assumes that `compiler` has already generated the libstd
|
/// Note that this assumes that `compiler` has already generated the libstd
|
||||||
|
|
|
@ -186,6 +186,9 @@ mod bar {
|
||||||
|
|
||||||
Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere.
|
Now we'll have a `Re-exports` line, and `Bar` will not link to anywhere.
|
||||||
|
|
||||||
|
One special case: In Rust 2018 and later, if you `pub use` one of your dependencies, `rustdoc` will
|
||||||
|
not eagerly inline it as a module unless you add `#[doc(inline)}`.
|
||||||
|
|
||||||
## `#[doc(hidden)]`
|
## `#[doc(hidden)]`
|
||||||
|
|
||||||
Any item annotated with `#[doc(hidden)]` will not appear in the documentation, unless
|
Any item annotated with `#[doc(hidden)]` will not appear in the documentation, unless
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
# containing LLDB commands (one command per line), this script will execute the commands one after
|
# containing LLDB commands (one command per line), this script will execute the commands one after
|
||||||
# the other.
|
# the other.
|
||||||
# LLDB also has the -s and -S commandline options which also execute a list of commands from a text
|
# LLDB also has the -s and -S commandline options which also execute a list of commands from a text
|
||||||
# file. However, this command are execute `immediately`: a the command of a `run` or `continue`
|
# file. However, this command are execute `immediately`: the command of a `run` or `continue`
|
||||||
# command will be executed immediately after the `run` or `continue`, without waiting for the next
|
# command will be executed immediately after the `run` or `continue`, without waiting for the next
|
||||||
# breakpoint to be hit. This a command sequence like the following will not yield reliable results:
|
# breakpoint to be hit. This a command sequence like the following will not yield reliable results:
|
||||||
#
|
#
|
||||||
|
|
|
@ -21,6 +21,10 @@ use core::usize;
|
||||||
pub use core::alloc::*;
|
pub use core::alloc::*;
|
||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
|
// These are the magic symbols to call the global allocator. rustc generates
|
||||||
|
// them from the `#[global_allocator]` attribute if there is one, or uses the
|
||||||
|
// default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`)
|
||||||
|
// otherwise.
|
||||||
#[allocator]
|
#[allocator]
|
||||||
#[rustc_allocator_nounwind]
|
#[rustc_allocator_nounwind]
|
||||||
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
|
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
|
||||||
|
|
|
@ -73,7 +73,7 @@ use core::convert::From;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
use core::iter::FusedIterator;
|
use core::iter::{Iterator, FromIterator, FusedIterator};
|
||||||
use core::marker::{Unpin, Unsize};
|
use core::marker::{Unpin, Unsize};
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
|
@ -81,6 +81,7 @@ use core::ops::{CoerceUnsized, DispatchFromDyn, Deref, DerefMut, Generator, Gene
|
||||||
use core::ptr::{self, NonNull, Unique};
|
use core::ptr::{self, NonNull, Unique};
|
||||||
use core::task::{LocalWaker, Poll};
|
use core::task::{LocalWaker, Poll};
|
||||||
|
|
||||||
|
use vec::Vec;
|
||||||
use raw_vec::RawVec;
|
use raw_vec::RawVec;
|
||||||
use str::from_boxed_utf8_unchecked;
|
use str::from_boxed_utf8_unchecked;
|
||||||
|
|
||||||
|
@ -699,6 +700,13 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
|
||||||
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
|
#[unstable(feature = "dispatch_from_dyn", issue = "0")]
|
||||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}
|
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}
|
||||||
|
|
||||||
|
#[stable(feature = "boxed_slice_from_iter", since = "1.32.0")]
|
||||||
|
impl<A> FromIterator<A> for Box<[A]> {
|
||||||
|
fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
|
||||||
|
iter.into_iter().collect::<Vec<_>>().into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "box_slice_clone", since = "1.3.0")]
|
#[stable(feature = "box_slice_clone", since = "1.3.0")]
|
||||||
impl<T: Clone> Clone for Box<[T]> {
|
impl<T: Clone> Clone for Box<[T]> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
|
|
@ -140,3 +140,11 @@ fn str_slice() {
|
||||||
let boxed: Box<str> = Box::from(s);
|
let boxed: Box<str> = Box::from(s);
|
||||||
assert_eq!(&*boxed, s)
|
assert_eq!(&*boxed, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn boxed_slice_from_iter() {
|
||||||
|
let iter = 0..100;
|
||||||
|
let boxed: Box<[u32]> = iter.collect();
|
||||||
|
assert_eq!(boxed.len(), 100);
|
||||||
|
assert_eq!(boxed[7], 7);
|
||||||
|
}
|
||||||
|
|
|
@ -853,9 +853,10 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::collections::BTreeMap;
|
/// use std::collections::BTreeMap;
|
||||||
///
|
///
|
||||||
/// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"].iter()
|
/// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"]
|
||||||
/// .map(|&s| (s, 0))
|
/// .iter()
|
||||||
/// .collect();
|
/// .map(|&s| (s, 0))
|
||||||
|
/// .collect();
|
||||||
/// for (_, balance) in map.range_mut("B".."Cheryl") {
|
/// for (_, balance) in map.range_mut("B".."Cheryl") {
|
||||||
/// *balance += 100;
|
/// *balance += 100;
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -2206,6 +2206,20 @@ impl<'a> From<&'a str> for String {
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
#[stable(feature = "string_from_box", since = "1.18.0")]
|
#[stable(feature = "string_from_box", since = "1.18.0")]
|
||||||
impl From<Box<str>> for String {
|
impl From<Box<str>> for String {
|
||||||
|
/// Converts the given boxed `str` slice to a `String`.
|
||||||
|
/// It is notable that the `str` slice is owned.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Basic usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let s1: String = String::from("hello world");
|
||||||
|
/// let s2: Box<str> = s1.into_boxed_str();
|
||||||
|
/// let s3: String = String::from(s2);
|
||||||
|
///
|
||||||
|
/// assert_eq!("hello world", s3)
|
||||||
|
/// ```
|
||||||
fn from(s: Box<str>) -> String {
|
fn from(s: Box<str>) -> String {
|
||||||
s.into_string()
|
s.into_string()
|
||||||
}
|
}
|
||||||
|
@ -2213,6 +2227,19 @@ impl From<Box<str>> for String {
|
||||||
|
|
||||||
#[stable(feature = "box_from_str", since = "1.20.0")]
|
#[stable(feature = "box_from_str", since = "1.20.0")]
|
||||||
impl From<String> for Box<str> {
|
impl From<String> for Box<str> {
|
||||||
|
/// Converts the given `String` to a boxed `str` slice that is owned.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Basic usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let s1: String = String::from("hello world");
|
||||||
|
/// let s2: Box<str> = Box::from(s1);
|
||||||
|
/// let s3: String = String::from(s2);
|
||||||
|
///
|
||||||
|
/// assert_eq!("hello world", s3)
|
||||||
|
/// ```
|
||||||
fn from(s: String) -> Box<str> {
|
fn from(s: String) -> Box<str> {
|
||||||
s.into_boxed_str()
|
s.into_boxed_str()
|
||||||
}
|
}
|
||||||
|
@ -2272,6 +2299,20 @@ impl<'a> FromIterator<String> for Cow<'a, str> {
|
||||||
|
|
||||||
#[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
|
#[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
|
||||||
impl From<String> for Vec<u8> {
|
impl From<String> for Vec<u8> {
|
||||||
|
/// Converts the given `String` to a vector `Vec` that holds values of type `u8`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Basic usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let s1 = String::from("hello world");
|
||||||
|
/// let v1 = Vec::from(s1);
|
||||||
|
///
|
||||||
|
/// for b in v1 {
|
||||||
|
/// println!("{}", b);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
fn from(string: String) -> Vec<u8> {
|
fn from(string: String) -> Vec<u8> {
|
||||||
string.into_bytes()
|
string.into_bytes()
|
||||||
}
|
}
|
||||||
|
|
|
@ -960,7 +960,7 @@ impl<T, U, E> Product<Result<U, E>> for Result<T, E>
|
||||||
///
|
///
|
||||||
/// Calling next on a fused iterator that has returned `None` once is guaranteed
|
/// Calling next on a fused iterator that has returned `None` once is guaranteed
|
||||||
/// to return [`None`] again. This trait should be implemented by all iterators
|
/// to return [`None`] again. This trait should be implemented by all iterators
|
||||||
/// that behave this way because it allows for some significant optimizations.
|
/// that behave this way because it allows optimizing [`Iterator::fuse`].
|
||||||
///
|
///
|
||||||
/// Note: In general, you should not use `FusedIterator` in generic bounds if
|
/// Note: In general, you should not use `FusedIterator` in generic bounds if
|
||||||
/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`]
|
/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`]
|
||||||
|
|
|
@ -128,6 +128,7 @@
|
||||||
#![feature(const_transmute)]
|
#![feature(const_transmute)]
|
||||||
#![feature(reverse_bits)]
|
#![feature(reverse_bits)]
|
||||||
#![feature(non_exhaustive)]
|
#![feature(non_exhaustive)]
|
||||||
|
#![feature(structural_match)]
|
||||||
|
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
|
@ -578,6 +578,7 @@ macro_rules! impls{
|
||||||
///
|
///
|
||||||
/// [drop check]: ../../nomicon/dropck.html
|
/// [drop check]: ../../nomicon/dropck.html
|
||||||
#[lang = "phantom_data"]
|
#[lang = "phantom_data"]
|
||||||
|
#[structural_match]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct PhantomData<T:?Sized>;
|
pub struct PhantomData<T:?Sized>;
|
||||||
|
|
||||||
|
|
|
@ -1896,7 +1896,7 @@ mod traits {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||||
// is_char_boundary checks that the index is in [0, .len()]
|
// is_char_boundary checks that the index is in [0, .len()]
|
||||||
// canot reuse `get` as above, because of NLL trouble
|
// cannot reuse `get` as above, because of NLL trouble
|
||||||
if self.start <= self.end &&
|
if self.start <= self.end &&
|
||||||
slice.is_char_boundary(self.start) &&
|
slice.is_char_boundary(self.start) &&
|
||||||
slice.is_char_boundary(self.end) {
|
slice.is_char_boundary(self.end) {
|
||||||
|
|
|
@ -37,68 +37,31 @@ impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator,
|
||||||
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
|
impl_stable_hash_for!(struct mir::UnsafetyViolation { source_info, description, details, kind });
|
||||||
impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
|
impl_stable_hash_for!(struct mir::UnsafetyCheckResult { violations, unsafe_blocks });
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>>
|
impl_stable_hash_for!(enum mir::BorrowKind {
|
||||||
for mir::BorrowKind {
|
Shared,
|
||||||
#[inline]
|
Shallow,
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
Unique,
|
||||||
hcx: &mut StableHashingContext<'a>,
|
Mut { allow_two_phase_borrow },
|
||||||
hasher: &mut StableHasher<W>) {
|
});
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
|
|
||||||
match *self {
|
impl_stable_hash_for!(enum mir::UnsafetyViolationKind {
|
||||||
mir::BorrowKind::Shared |
|
General,
|
||||||
mir::BorrowKind::Shallow |
|
MinConstFn,
|
||||||
mir::BorrowKind::Unique => {}
|
ExternStatic(lint_node_id),
|
||||||
mir::BorrowKind::Mut { allow_two_phase_borrow } => {
|
BorrowPacked(lint_node_id),
|
||||||
allow_two_phase_borrow.hash_stable(hcx, hasher);
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>>
|
|
||||||
for mir::UnsafetyViolationKind {
|
|
||||||
#[inline]
|
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
|
||||||
hcx: &mut StableHashingContext<'a>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
|
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
mir::UnsafetyViolationKind::General => {}
|
|
||||||
mir::UnsafetyViolationKind::MinConstFn => {}
|
|
||||||
mir::UnsafetyViolationKind::ExternStatic(lint_node_id) |
|
|
||||||
mir::UnsafetyViolationKind::BorrowPacked(lint_node_id) => {
|
|
||||||
lint_node_id.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_stable_hash_for!(struct mir::Terminator<'tcx> {
|
impl_stable_hash_for!(struct mir::Terminator<'tcx> {
|
||||||
kind,
|
kind,
|
||||||
source_info
|
source_info
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for mir::ClearCrossCrate<T>
|
impl_stable_hash_for!(
|
||||||
where T: HashStable<StableHashingContext<'a>>
|
impl<T> for enum mir::ClearCrossCrate<T> [ mir::ClearCrossCrate ] {
|
||||||
{
|
Clear,
|
||||||
#[inline]
|
Set(value),
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
|
||||||
hcx: &mut StableHashingContext<'a>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
match *self {
|
|
||||||
mir::ClearCrossCrate::Clear => {}
|
|
||||||
mir::ClearCrossCrate::Set(ref value) => {
|
|
||||||
value.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
|
impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -224,20 +224,10 @@ impl_stable_hash_for!(enum ty::BorrowKind {
|
||||||
MutBorrow
|
MutBorrow
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
impl_stable_hash_for!(impl<'gcx> for enum ty::UpvarCapture<'gcx> [ ty::UpvarCapture ] {
|
||||||
for ty::UpvarCapture<'gcx> {
|
ByValue,
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
ByRef(up_var_borrow),
|
||||||
hcx: &mut StableHashingContext<'a>,
|
});
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
match *self {
|
|
||||||
ty::UpvarCapture::ByValue => {}
|
|
||||||
ty::UpvarCapture::ByRef(ref up_var_borrow) => {
|
|
||||||
up_var_borrow.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ty::GenSig<'tcx> {
|
impl_stable_hash_for!(struct ty::GenSig<'tcx> {
|
||||||
yield_ty,
|
yield_ty,
|
||||||
|
@ -272,64 +262,23 @@ impl_stable_hash_for!(enum ty::Visibility {
|
||||||
impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
|
impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
|
||||||
impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
|
impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
|
||||||
impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
|
impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b });
|
||||||
|
impl_stable_hash_for!(impl<A, B> for tuple_struct ty::OutlivesPredicate<A, B> { a, b });
|
||||||
impl<'a, 'gcx, A, B> HashStable<StableHashingContext<'a>>
|
|
||||||
for ty::OutlivesPredicate<A, B>
|
|
||||||
where A: HashStable<StableHashingContext<'a>>,
|
|
||||||
B: HashStable<StableHashingContext<'a>>,
|
|
||||||
{
|
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
|
||||||
hcx: &mut StableHashingContext<'a>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
let ty::OutlivesPredicate(ref a, ref b) = *self;
|
|
||||||
a.hash_stable(hcx, hasher);
|
|
||||||
b.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
|
impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
|
||||||
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
|
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
|
||||||
|
|
||||||
|
impl_stable_hash_for!(
|
||||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::Predicate<'gcx> {
|
impl<'tcx> for enum ty::Predicate<'tcx> [ ty::Predicate ] {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
Trait(pred),
|
||||||
hcx: &mut StableHashingContext<'a>,
|
Subtype(pred),
|
||||||
hasher: &mut StableHasher<W>) {
|
RegionOutlives(pred),
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
TypeOutlives(pred),
|
||||||
match *self {
|
Projection(pred),
|
||||||
ty::Predicate::Trait(ref pred) => {
|
WellFormed(ty),
|
||||||
pred.hash_stable(hcx, hasher);
|
ObjectSafe(def_id),
|
||||||
}
|
ClosureKind(def_id, closure_substs, closure_kind),
|
||||||
ty::Predicate::Subtype(ref pred) => {
|
ConstEvaluatable(def_id, substs),
|
||||||
pred.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::Predicate::RegionOutlives(ref pred) => {
|
|
||||||
pred.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::Predicate::TypeOutlives(ref pred) => {
|
|
||||||
pred.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::Predicate::Projection(ref pred) => {
|
|
||||||
pred.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::Predicate::WellFormed(ty) => {
|
|
||||||
ty.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::Predicate::ObjectSafe(def_id) => {
|
|
||||||
def_id.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::Predicate::ClosureKind(def_id, closure_substs, closure_kind) => {
|
|
||||||
def_id.hash_stable(hcx, hasher);
|
|
||||||
closure_substs.hash_stable(hcx, hasher);
|
|
||||||
closure_kind.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::Predicate::ConstEvaluatable(def_id, substs) => {
|
|
||||||
def_id.hash_stable(hcx, hasher);
|
|
||||||
substs.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for ty::AdtFlags {
|
impl<'a> HashStable<StableHashingContext<'a>> for ty::AdtFlags {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
fn hash_stable<W: StableHasherResult>(&self,
|
||||||
|
@ -358,70 +307,39 @@ impl_stable_hash_for!(struct ty::FieldDef {
|
||||||
vis,
|
vis,
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
impl_stable_hash_for!(
|
||||||
for ::mir::interpret::ConstValue<'gcx> {
|
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
Unevaluated(def_id, substs),
|
||||||
hcx: &mut StableHashingContext<'a>,
|
Scalar(val),
|
||||||
hasher: &mut StableHasher<W>) {
|
ScalarPair(a, b),
|
||||||
use mir::interpret::ConstValue::*;
|
ByRef(id, alloc, offset),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
impl_stable_hash_for! {
|
||||||
|
impl<Tag> for struct mir::interpret::Pointer<Tag> {
|
||||||
match *self {
|
alloc_id,
|
||||||
Unevaluated(def_id, substs) => {
|
offset,
|
||||||
def_id.hash_stable(hcx, hasher);
|
tag,
|
||||||
substs.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
Scalar(val) => {
|
|
||||||
val.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ScalarPair(a, b) => {
|
|
||||||
a.hash_stable(hcx, hasher);
|
|
||||||
b.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ByRef(id, alloc, offset) => {
|
|
||||||
id.hash_stable(hcx, hasher);
|
|
||||||
alloc.hash_stable(hcx, hasher);
|
|
||||||
offset.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Tag> HashStable<StableHashingContext<'a>>
|
impl_stable_hash_for!(
|
||||||
for ::mir::interpret::Pointer<Tag>
|
impl<Tag> for enum mir::interpret::Scalar<Tag> [ mir::interpret::Scalar ] {
|
||||||
where Tag: HashStable<StableHashingContext<'a>>
|
Bits { bits, size },
|
||||||
{
|
Ptr(ptr),
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
|
||||||
hcx: &mut StableHashingContext<'a>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
let ::mir::interpret::Pointer { alloc_id, offset, tag } = self;
|
|
||||||
alloc_id.hash_stable(hcx, hasher);
|
|
||||||
offset.hash_stable(hcx, hasher);
|
|
||||||
tag.hash_stable(hcx, hasher);
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
impl<'a, Tag> HashStable<StableHashingContext<'a>>
|
impl_stable_hash_for!(
|
||||||
for ::mir::interpret::Scalar<Tag>
|
impl<'tcx, M> for enum mir::interpret::AllocType<'tcx, M> [ mir::interpret::AllocType ] {
|
||||||
where Tag: HashStable<StableHashingContext<'a>>
|
Function(instance),
|
||||||
{
|
Static(def_id),
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
Memory(mem),
|
||||||
hcx: &mut StableHashingContext<'a>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
use mir::interpret::Scalar::*;
|
|
||||||
|
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
match self {
|
|
||||||
Bits { bits, size } => {
|
|
||||||
bits.hash_stable(hcx, hasher);
|
|
||||||
size.hash_stable(hcx, hasher);
|
|
||||||
},
|
|
||||||
Ptr(ptr) => ptr.hash_stable(hcx, hasher),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
|
// AllocIds get resolved to whatever they point to (to be stable)
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
|
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
|
||||||
fn hash_stable<W: StableHasherResult>(
|
fn hash_stable<W: StableHasherResult>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -437,23 +355,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, M: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
|
// Allocations treat their relocations specially
|
||||||
for mir::interpret::AllocType<'gcx, M> {
|
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
|
||||||
hcx: &mut StableHashingContext<'a>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
use mir::interpret::AllocType::*;
|
|
||||||
|
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
|
|
||||||
match *self {
|
|
||||||
Function(instance) => instance.hash_stable(hcx, hasher),
|
|
||||||
Static(def_id) => def_id.hash_stable(hcx, hasher),
|
|
||||||
Memory(ref mem) => mem.hash_stable(hcx, hasher),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
|
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
|
||||||
fn hash_stable<W: StableHasherResult>(
|
fn hash_stable<W: StableHasherResult>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -485,7 +387,7 @@ impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
|
||||||
TooGeneric
|
TooGeneric
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
|
impl_stable_hash_for!(struct mir::interpret::FrameInfo {
|
||||||
span,
|
span,
|
||||||
lint_root,
|
lint_root,
|
||||||
location
|
location
|
||||||
|
@ -499,124 +401,75 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
|
||||||
predicates
|
predicates
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
|
impl_stable_hash_for!(
|
||||||
for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
impl<'tcx, O> for enum mir::interpret::EvalErrorKind<'tcx, O>
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
[ mir::interpret::EvalErrorKind ]
|
||||||
hcx: &mut StableHashingContext<'a>,
|
{
|
||||||
hasher: &mut StableHasher<W>) {
|
FunctionArgCountMismatch,
|
||||||
use mir::interpret::EvalErrorKind::*;
|
DanglingPointerDeref,
|
||||||
|
DoubleFree,
|
||||||
mem::discriminant(&self).hash_stable(hcx, hasher);
|
InvalidMemoryAccess,
|
||||||
|
InvalidFunctionPointer,
|
||||||
match *self {
|
InvalidBool,
|
||||||
FunctionArgCountMismatch |
|
InvalidNullPointerUsage,
|
||||||
DanglingPointerDeref |
|
ReadPointerAsBytes,
|
||||||
DoubleFree |
|
ReadBytesAsPointer,
|
||||||
InvalidMemoryAccess |
|
ReadForeignStatic,
|
||||||
InvalidFunctionPointer |
|
InvalidPointerMath,
|
||||||
InvalidBool |
|
DeadLocal,
|
||||||
InvalidNullPointerUsage |
|
StackFrameLimitReached,
|
||||||
ReadPointerAsBytes |
|
OutOfTls,
|
||||||
ReadBytesAsPointer |
|
TlsOutOfBounds,
|
||||||
ReadForeignStatic |
|
CalledClosureAsFunction,
|
||||||
InvalidPointerMath |
|
VtableForArgumentlessMethod,
|
||||||
DeadLocal |
|
ModifiedConstantMemory,
|
||||||
StackFrameLimitReached |
|
AssumptionNotHeld,
|
||||||
OutOfTls |
|
InlineAsm,
|
||||||
TlsOutOfBounds |
|
ReallocateNonBasePtr,
|
||||||
CalledClosureAsFunction |
|
DeallocateNonBasePtr,
|
||||||
VtableForArgumentlessMethod |
|
HeapAllocZeroBytes,
|
||||||
ModifiedConstantMemory |
|
Unreachable,
|
||||||
AssumptionNotHeld |
|
ReadFromReturnPointer,
|
||||||
InlineAsm |
|
UnimplementedTraitSelection,
|
||||||
ReallocateNonBasePtr |
|
TypeckError,
|
||||||
DeallocateNonBasePtr |
|
TooGeneric,
|
||||||
HeapAllocZeroBytes |
|
DerefFunctionPointer,
|
||||||
Unreachable |
|
ExecuteMemory,
|
||||||
ReadFromReturnPointer |
|
OverflowNeg,
|
||||||
UnimplementedTraitSelection |
|
RemainderByZero,
|
||||||
TypeckError |
|
DivisionByZero,
|
||||||
TooGeneric |
|
GeneratorResumedAfterReturn,
|
||||||
DerefFunctionPointer |
|
GeneratorResumedAfterPanic,
|
||||||
ExecuteMemory |
|
ReferencedConstant,
|
||||||
OverflowNeg |
|
InfiniteLoop,
|
||||||
RemainderByZero |
|
ReadUndefBytes(offset),
|
||||||
DivisionByZero |
|
InvalidDiscriminant(val),
|
||||||
GeneratorResumedAfterReturn |
|
Panic { msg, file, line, col },
|
||||||
GeneratorResumedAfterPanic |
|
MachineError(err),
|
||||||
ReferencedConstant |
|
FunctionAbiMismatch(a, b),
|
||||||
InfiniteLoop => {}
|
FunctionArgMismatch(a, b),
|
||||||
ReadUndefBytes(offset) => offset.hash_stable(hcx, hasher),
|
FunctionRetMismatch(a, b),
|
||||||
InvalidDiscriminant(val) => val.hash_stable(hcx, hasher),
|
NoMirFor(s),
|
||||||
Panic { ref msg, ref file, line, col } => {
|
UnterminatedCString(ptr),
|
||||||
msg.hash_stable(hcx, hasher);
|
PointerOutOfBounds { ptr, access, allocation_size },
|
||||||
file.hash_stable(hcx, hasher);
|
InvalidBoolOp(bop),
|
||||||
line.hash_stable(hcx, hasher);
|
Unimplemented(s),
|
||||||
col.hash_stable(hcx, hasher);
|
BoundsCheck { len, index },
|
||||||
},
|
Intrinsic(s),
|
||||||
MachineError(ref err) => err.hash_stable(hcx, hasher),
|
InvalidChar(c),
|
||||||
FunctionAbiMismatch(a, b) => {
|
AbiViolation(s),
|
||||||
a.hash_stable(hcx, hasher);
|
AlignmentCheckFailed { required, has },
|
||||||
b.hash_stable(hcx, hasher)
|
ValidationFailure(s),
|
||||||
},
|
TypeNotPrimitive(ty),
|
||||||
FunctionArgMismatch(a, b) => {
|
ReallocatedWrongMemoryKind(a, b),
|
||||||
a.hash_stable(hcx, hasher);
|
DeallocatedWrongMemoryKind(a, b),
|
||||||
b.hash_stable(hcx, hasher)
|
IncorrectAllocationInformation(a, b, c, d),
|
||||||
},
|
Layout(lay),
|
||||||
FunctionRetMismatch(a, b) => {
|
HeapAllocNonPowerOfTwoAlignment(n),
|
||||||
a.hash_stable(hcx, hasher);
|
PathNotFound(v),
|
||||||
b.hash_stable(hcx, hasher)
|
Overflow(op),
|
||||||
},
|
|
||||||
NoMirFor(ref s) => s.hash_stable(hcx, hasher),
|
|
||||||
UnterminatedCString(ptr) => ptr.hash_stable(hcx, hasher),
|
|
||||||
PointerOutOfBounds {
|
|
||||||
ptr,
|
|
||||||
access,
|
|
||||||
allocation_size,
|
|
||||||
} => {
|
|
||||||
ptr.hash_stable(hcx, hasher);
|
|
||||||
access.hash_stable(hcx, hasher);
|
|
||||||
allocation_size.hash_stable(hcx, hasher)
|
|
||||||
},
|
|
||||||
InvalidBoolOp(bop) => bop.hash_stable(hcx, hasher),
|
|
||||||
Unimplemented(ref s) => s.hash_stable(hcx, hasher),
|
|
||||||
BoundsCheck { ref len, ref index } => {
|
|
||||||
len.hash_stable(hcx, hasher);
|
|
||||||
index.hash_stable(hcx, hasher)
|
|
||||||
},
|
|
||||||
Intrinsic(ref s) => s.hash_stable(hcx, hasher),
|
|
||||||
InvalidChar(c) => c.hash_stable(hcx, hasher),
|
|
||||||
AbiViolation(ref s) => s.hash_stable(hcx, hasher),
|
|
||||||
AlignmentCheckFailed {
|
|
||||||
required,
|
|
||||||
has,
|
|
||||||
} => {
|
|
||||||
required.hash_stable(hcx, hasher);
|
|
||||||
has.hash_stable(hcx, hasher)
|
|
||||||
},
|
|
||||||
ValidationFailure(ref s) => s.hash_stable(hcx, hasher),
|
|
||||||
TypeNotPrimitive(ty) => ty.hash_stable(hcx, hasher),
|
|
||||||
ReallocatedWrongMemoryKind(ref a, ref b) => {
|
|
||||||
a.hash_stable(hcx, hasher);
|
|
||||||
b.hash_stable(hcx, hasher)
|
|
||||||
},
|
|
||||||
DeallocatedWrongMemoryKind(ref a, ref b) => {
|
|
||||||
a.hash_stable(hcx, hasher);
|
|
||||||
b.hash_stable(hcx, hasher)
|
|
||||||
},
|
|
||||||
IncorrectAllocationInformation(a, b, c, d) => {
|
|
||||||
a.hash_stable(hcx, hasher);
|
|
||||||
b.hash_stable(hcx, hasher);
|
|
||||||
c.hash_stable(hcx, hasher);
|
|
||||||
d.hash_stable(hcx, hasher)
|
|
||||||
},
|
|
||||||
Layout(lay) => lay.hash_stable(hcx, hasher),
|
|
||||||
HeapAllocNonPowerOfTwoAlignment(n) => n.hash_stable(hcx, hasher),
|
|
||||||
PathNotFound(ref v) => v.hash_stable(hcx, hasher),
|
|
||||||
Overflow(op) => op.hash_stable(hcx, hasher),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
impl_stable_hash_for!(enum mir::interpret::Lock {
|
impl_stable_hash_for!(enum mir::interpret::Lock {
|
||||||
NoLock,
|
NoLock,
|
||||||
|
@ -663,47 +516,18 @@ impl_stable_hash_for!(struct ty::GenericParamDef {
|
||||||
kind
|
kind
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<'a> HashStable<StableHashingContext<'a>> for ty::GenericParamDefKind {
|
impl_stable_hash_for!(enum ty::GenericParamDefKind {
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
Lifetime,
|
||||||
hcx: &mut StableHashingContext<'a>,
|
Type { has_default, object_lifetime_default, synthetic },
|
||||||
hasher: &mut StableHasher<W>) {
|
});
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
match *self {
|
|
||||||
ty::GenericParamDefKind::Lifetime => {}
|
|
||||||
ty::GenericParamDefKind::Type {
|
|
||||||
has_default,
|
|
||||||
ref object_lifetime_default,
|
|
||||||
ref synthetic,
|
|
||||||
} => {
|
|
||||||
has_default.hash_stable(hcx, hasher);
|
|
||||||
object_lifetime_default.hash_stable(hcx, hasher);
|
|
||||||
synthetic.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
|
impl_stable_hash_for!(
|
||||||
for ::middle::resolve_lifetime::Set1<T>
|
impl<T> for enum ::middle::resolve_lifetime::Set1<T> [ ::middle::resolve_lifetime::Set1 ] {
|
||||||
where T: HashStable<StableHashingContext<'a>>
|
Empty,
|
||||||
{
|
Many,
|
||||||
fn hash_stable<W: StableHasherResult>(&self,
|
One(value),
|
||||||
hcx: &mut StableHashingContext<'a>,
|
|
||||||
hasher: &mut StableHasher<W>) {
|
|
||||||
use middle::resolve_lifetime::Set1;
|
|
||||||
|
|
||||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
|
||||||
match *self {
|
|
||||||
Set1::Empty |
|
|
||||||
Set1::Many => {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
Set1::One(ref value) => {
|
|
||||||
value.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
|
impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
|
||||||
ExplicitOrElided,
|
ExplicitOrElided,
|
||||||
|
@ -1250,7 +1074,7 @@ impl_stable_hash_for!(
|
||||||
);
|
);
|
||||||
|
|
||||||
impl_stable_hash_for!(
|
impl_stable_hash_for!(
|
||||||
impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
|
struct infer::canonical::CanonicalVarValues<'tcx> {
|
||||||
var_values
|
var_values
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1369,7 +1193,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_stable_hash_for!(
|
impl_stable_hash_for!(
|
||||||
impl<'tcx> for struct traits::ProgramClause<'tcx> {
|
struct traits::ProgramClause<'tcx> {
|
||||||
goal, hypotheses, category
|
goal, hypotheses, category
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1404,7 +1228,7 @@ impl_stable_hash_for!(struct ty::subst::UserSubsts<'tcx> { substs, user_self_ty
|
||||||
impl_stable_hash_for!(struct ty::subst::UserSelfTy<'tcx> { impl_def_id, self_ty });
|
impl_stable_hash_for!(struct ty::subst::UserSelfTy<'tcx> { impl_def_id, self_ty });
|
||||||
|
|
||||||
impl_stable_hash_for!(
|
impl_stable_hash_for!(
|
||||||
impl<'tcx> for struct traits::Environment<'tcx> {
|
struct traits::Environment<'tcx> {
|
||||||
clauses,
|
clauses,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -132,7 +132,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||||
///
|
///
|
||||||
/// See the `region_obligations` field of `InferCtxt` for some
|
/// See the `region_obligations` field of `InferCtxt` for some
|
||||||
/// comments about how this function fits into the overall expected
|
/// comments about how this function fits into the overall expected
|
||||||
/// flow of the the inferencer. The key point is that it is
|
/// flow of the inferencer. The key point is that it is
|
||||||
/// invoked after all type-inference variables have been bound --
|
/// invoked after all type-inference variables have been bound --
|
||||||
/// towards the end of regionck. This also ensures that the
|
/// towards the end of regionck. This also ensures that the
|
||||||
/// region-bound-pairs are available (see comments above regarding
|
/// region-bound-pairs are available (see comments above regarding
|
||||||
|
|
|
@ -62,16 +62,6 @@ macro_rules! span_bug {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! static_assert {
|
|
||||||
($name:ident: $test:expr) => {
|
|
||||||
// Use the bool to access an array such that if the bool is false, the access
|
|
||||||
// is out-of-bounds.
|
|
||||||
#[allow(dead_code)]
|
|
||||||
static $name: () = [()][!$test as usize];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! __impl_stable_hash_field {
|
macro_rules! __impl_stable_hash_field {
|
||||||
($field:ident, $ctx:expr, $hasher:expr) => ($field.hash_stable($ctx, $hasher));
|
($field:ident, $ctx:expr, $hasher:expr) => ($field.hash_stable($ctx, $hasher));
|
||||||
|
@ -81,6 +71,7 @@ macro_rules! __impl_stable_hash_field {
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_stable_hash_for {
|
macro_rules! impl_stable_hash_for {
|
||||||
|
// Enums
|
||||||
// FIXME(mark-i-m): Some of these should be `?` rather than `*`. See the git blame and change
|
// FIXME(mark-i-m): Some of these should be `?` rather than `*`. See the git blame and change
|
||||||
// them back when `?` is supported again.
|
// them back when `?` is supported again.
|
||||||
(enum $enum_name:path {
|
(enum $enum_name:path {
|
||||||
|
@ -91,12 +82,37 @@ macro_rules! impl_stable_hash_for {
|
||||||
$( { $($named_field:ident $(-> $named_delegate:tt)*),* } )*
|
$( { $($named_field:ident $(-> $named_delegate:tt)*),* } )*
|
||||||
),* $(,)*
|
),* $(,)*
|
||||||
}) => {
|
}) => {
|
||||||
impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $enum_name {
|
impl_stable_hash_for!(
|
||||||
|
impl<> for enum $enum_name [ $enum_name ] { $( $variant
|
||||||
|
$( ( $($field $(-> $delegate)*),* ) )*
|
||||||
|
$( { $($named_field $(-> $named_delegate)*),* } )*
|
||||||
|
),* }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
// We want to use the enum name both in the `impl ... for $enum_name` as well as for
|
||||||
|
// importing all the variants. Unfortunately it seems we have to take the name
|
||||||
|
// twice for this purpose
|
||||||
|
(impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*>
|
||||||
|
for enum $enum_name:path
|
||||||
|
[ $enum_path:path ]
|
||||||
|
{
|
||||||
|
$( $variant:ident
|
||||||
|
// this incorrectly allows specifying both tuple-like and struct-like fields, as in `Variant(a,b){c,d}`,
|
||||||
|
// when it should be only one or the other
|
||||||
|
$( ( $($field:ident $(-> $delegate:tt)*),* ) )*
|
||||||
|
$( { $($named_field:ident $(-> $named_delegate:tt)*),* } )*
|
||||||
|
),* $(,)*
|
||||||
|
}) => {
|
||||||
|
impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*>
|
||||||
|
::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>
|
||||||
|
for $enum_name
|
||||||
|
where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
||||||
__ctx: &mut $crate::ich::StableHashingContext<'a>,
|
__ctx: &mut $crate::ich::StableHashingContext<'a>,
|
||||||
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
||||||
use $enum_name::*;
|
use $enum_path::*;
|
||||||
::std::mem::discriminant(self).hash_stable(__ctx, __hasher);
|
::std::mem::discriminant(self).hash_stable(__ctx, __hasher);
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -110,41 +126,17 @@ macro_rules! impl_stable_hash_for {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Structs
|
||||||
// FIXME(mark-i-m): same here.
|
// FIXME(mark-i-m): same here.
|
||||||
(struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => {
|
(struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => {
|
||||||
impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name {
|
impl_stable_hash_for!(
|
||||||
#[inline]
|
impl<'tcx> for struct $struct_name { $($field $(-> $delegate)*),* }
|
||||||
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
);
|
||||||
__ctx: &mut $crate::ich::StableHashingContext<'a>,
|
|
||||||
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
|
||||||
let $struct_name {
|
|
||||||
$(ref $field),*
|
|
||||||
} = *self;
|
|
||||||
|
|
||||||
$( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
// FIXME(mark-i-m): same here.
|
(impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*> for struct $struct_name:path {
|
||||||
(tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => {
|
|
||||||
impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name {
|
|
||||||
#[inline]
|
|
||||||
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
|
||||||
__ctx: &mut $crate::ich::StableHashingContext<'a>,
|
|
||||||
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
|
||||||
let $struct_name (
|
|
||||||
$(ref $field),*
|
|
||||||
) = *self;
|
|
||||||
|
|
||||||
$( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
(impl<$tcx:lifetime $(, $lt:lifetime $(: $lt_bound:lifetime)*)* $(, $T:ident)*> for struct $struct_name:path {
|
|
||||||
$($field:ident $(-> $delegate:tt)*),* $(,)*
|
$($field:ident $(-> $delegate:tt)*),* $(,)*
|
||||||
}) => {
|
}) => {
|
||||||
impl<'a, $tcx, $($lt $(: $lt_bound)*,)* $($T,)*>
|
impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*>
|
||||||
::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name
|
::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name
|
||||||
where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
|
where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
|
||||||
{
|
{
|
||||||
|
@ -156,6 +148,32 @@ macro_rules! impl_stable_hash_for {
|
||||||
$(ref $field),*
|
$(ref $field),*
|
||||||
} = *self;
|
} = *self;
|
||||||
|
|
||||||
|
$( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Tuple structs
|
||||||
|
// We cannot use normale parentheses here, the parser won't allow it
|
||||||
|
// FIXME(mark-i-m): same here.
|
||||||
|
(tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => {
|
||||||
|
impl_stable_hash_for!(
|
||||||
|
impl<'tcx> for tuple_struct $struct_name { $($field $(-> $delegate)*),* }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
(impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*>
|
||||||
|
for tuple_struct $struct_name:path { $($field:ident $(-> $delegate:tt)*),* $(,)* }) => {
|
||||||
|
impl<'a, $($lt $(: $lt_bound)*,)* $($T,)*>
|
||||||
|
::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>> for $struct_name
|
||||||
|
where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
|
||||||
|
__ctx: &mut $crate::ich::StableHashingContext<'a>,
|
||||||
|
__hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
|
||||||
|
let $struct_name (
|
||||||
|
$(ref $field),*
|
||||||
|
) = *self;
|
||||||
|
|
||||||
$( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
|
$( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,17 @@ pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Default + Clone {
|
||||||
) -> EvalResult<'tcx> {
|
) -> EvalResult<'tcx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Hook for performing extra checks on a memory deallocation.
|
||||||
|
/// `size` will be the size of the allocation.
|
||||||
|
#[inline]
|
||||||
|
fn memory_deallocated(
|
||||||
|
_alloc: &mut Allocation<Tag, Self>,
|
||||||
|
_ptr: Pointer<Tag>,
|
||||||
|
_size: Size,
|
||||||
|
) -> EvalResult<'tcx> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AllocationExtra<()> for () {}
|
impl AllocationExtra<()> for () {}
|
||||||
|
|
|
@ -1720,14 +1720,14 @@ pub struct Statement<'tcx> {
|
||||||
pub kind: StatementKind<'tcx>,
|
pub kind: StatementKind<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Statement<'_>>() == 56);
|
||||||
|
|
||||||
impl<'tcx> Statement<'tcx> {
|
impl<'tcx> Statement<'tcx> {
|
||||||
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
|
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
|
||||||
/// invalidating statement indices in `Location`s.
|
/// invalidating statement indices in `Location`s.
|
||||||
pub fn make_nop(&mut self) {
|
pub fn make_nop(&mut self) {
|
||||||
// `Statement` contributes significantly to peak memory usage. Make
|
|
||||||
// sure it doesn't get bigger.
|
|
||||||
static_assert!(STATEMENT_IS_AT_MOST_56_BYTES: mem::size_of::<Statement<'_>>() <= 56);
|
|
||||||
|
|
||||||
self.kind = StatementKind::Nop
|
self.kind = StatementKind::Nop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2617,7 +2617,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: &ty::Const<'_>) -> fmt::Resu
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// print function definitons
|
// print function definitions
|
||||||
if let FnDef(did, _) = ty.sty {
|
if let FnDef(did, _) = ty.sty {
|
||||||
return write!(f, "{}", item_path_str(did));
|
return write!(f, "{}", item_path_str(did));
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
|
||||||
//
|
//
|
||||||
// It does the actual traversal of the graph, while the `next` method on the iterator
|
// It does the actual traversal of the graph, while the `next` method on the iterator
|
||||||
// just pops off of the stack. `visit_stack` is a stack containing pairs of nodes and
|
// just pops off of the stack. `visit_stack` is a stack containing pairs of nodes and
|
||||||
// iterators over the sucessors of those nodes. Each iteration attempts to get the next
|
// iterators over the successors of those nodes. Each iteration attempts to get the next
|
||||||
// node from the top of the stack, then pushes that node and an iterator over the
|
// node from the top of the stack, then pushes that node and an iterator over the
|
||||||
// successors to the top of the stack. This loop only grows `visit_stack`, stopping when
|
// successors to the top of the stack. This loop only grows `visit_stack`, stopping when
|
||||||
// we reach a child that has no children that we haven't already visited.
|
// we reach a child that has no children that we haven't already visited.
|
||||||
|
@ -163,7 +163,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
|
||||||
// The state of the stack starts out with just the root node (`A` in this case);
|
// The state of the stack starts out with just the root node (`A` in this case);
|
||||||
// [(A, [B, C])]
|
// [(A, [B, C])]
|
||||||
//
|
//
|
||||||
// When the first call to `traverse_sucessor` happens, the following happens:
|
// When the first call to `traverse_successor` happens, the following happens:
|
||||||
//
|
//
|
||||||
// [(B, [D]), // `B` taken from the successors of `A`, pushed to the
|
// [(B, [D]), // `B` taken from the successors of `A`, pushed to the
|
||||||
// // top of the stack along with the successors of `B`
|
// // top of the stack along with the successors of `B`
|
||||||
|
|
|
@ -823,12 +823,6 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
|
||||||
|
|
||||||
impl<'tcx> CommonTypes<'tcx> {
|
impl<'tcx> CommonTypes<'tcx> {
|
||||||
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
|
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
|
||||||
// Ensure our type representation does not grow
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
|
||||||
static_assert!(ASSERT_TY_KIND: ::std::mem::size_of::<ty::TyKind<'_>>() <= 24);
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
|
||||||
static_assert!(ASSERT_TYS: ::std::mem::size_of::<ty::TyS<'_>>() <= 32);
|
|
||||||
|
|
||||||
let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
|
let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
|
||||||
let mk_region = |r| {
|
let mk_region = |r| {
|
||||||
if let Some(r) = interners.region.borrow().get(&r) {
|
if let Some(r) = interners.region.borrow().get(&r) {
|
||||||
|
|
|
@ -515,6 +515,10 @@ pub struct TyS<'tcx> {
|
||||||
outer_exclusive_binder: ty::DebruijnIndex,
|
outer_exclusive_binder: ty::DebruijnIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
static_assert!(MEM_SIZE_OF_TY_S: ::std::mem::size_of::<TyS<'_>>() == 32);
|
||||||
|
|
||||||
impl<'tcx> Ord for TyS<'tcx> {
|
impl<'tcx> Ord for TyS<'tcx> {
|
||||||
fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
|
fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
|
||||||
self.sty.cmp(&other.sty)
|
self.sty.cmp(&other.sty)
|
||||||
|
|
|
@ -291,7 +291,8 @@ define_queries! { <'tcx>
|
||||||
/// Gets a complete map from all types to their inherent impls.
|
/// Gets a complete map from all types to their inherent impls.
|
||||||
/// Not meant to be used directly outside of coherence.
|
/// Not meant to be used directly outside of coherence.
|
||||||
/// (Defined only for LOCAL_CRATE)
|
/// (Defined only for LOCAL_CRATE)
|
||||||
[] fn crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
|
[] fn crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum)
|
||||||
|
-> Lrc<CrateInherentImpls>,
|
||||||
|
|
||||||
/// Checks all types in the krate for overlap in their inherent impls. Reports errors.
|
/// Checks all types in the krate for overlap in their inherent impls. Reports errors.
|
||||||
/// Not meant to be used directly outside of coherence.
|
/// Not meant to be used directly outside of coherence.
|
||||||
|
|
|
@ -100,7 +100,7 @@ pub(super) struct JobOwner<'a, 'tcx: 'a, Q: QueryDescription<'tcx> + 'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
|
impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
|
||||||
/// Either gets a JobOwner corresponding the the query, allowing us to
|
/// Either gets a JobOwner corresponding the query, allowing us to
|
||||||
/// start executing the query, or it returns with the result of the query.
|
/// start executing the query, or it returns with the result of the query.
|
||||||
/// If the query is executing elsewhere, this will wait for it.
|
/// If the query is executing elsewhere, this will wait for it.
|
||||||
/// If the query panicked, this will silently panic.
|
/// If the query panicked, this will silently panic.
|
||||||
|
@ -314,7 +314,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
/// Try to read a node index for the node dep_node.
|
/// Try to read a node index for the node dep_node.
|
||||||
/// A node will have an index, when it's already been marked green, or when we can mark it
|
/// A node will have an index, when it's already been marked green, or when we can mark it
|
||||||
/// green. This function will mark the current task as a reader of the specified node, when
|
/// green. This function will mark the current task as a reader of the specified node, when
|
||||||
/// the a node index can be found for that node.
|
/// a node index can be found for that node.
|
||||||
pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option<DepNodeIndex> {
|
pub(super) fn try_mark_green_and_read(self, dep_node: &DepNode) -> Option<DepNodeIndex> {
|
||||||
match self.dep_graph.node_color(dep_node) {
|
match self.dep_graph.node_color(dep_node) {
|
||||||
Some(DepNodeColor::Green(dep_node_index)) => {
|
Some(DepNodeColor::Green(dep_node_index)) => {
|
||||||
|
|
|
@ -211,6 +211,10 @@ pub enum TyKind<'tcx> {
|
||||||
Error,
|
Error,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
static_assert!(MEM_SIZE_OF_TY_KIND: ::std::mem::size_of::<TyKind<'_>>() == 24);
|
||||||
|
|
||||||
/// A closure can be modeled as a struct that looks like:
|
/// A closure can be modeled as a struct that looks like:
|
||||||
///
|
///
|
||||||
/// struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> {
|
/// struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> {
|
||||||
|
|
|
@ -895,7 +895,7 @@ impl<S: Semantics> Float for IeeeFloat<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The intermediate result of the multiplication has "2 * S::PRECISION"
|
// The intermediate result of the multiplication has "2 * S::PRECISION"
|
||||||
// signicant bit; adjust the addend to be consistent with mul result.
|
// significant bit; adjust the addend to be consistent with mul result.
|
||||||
let mut ext_addend_sig = [addend.sig[0], 0];
|
let mut ext_addend_sig = [addend.sig[0], 0];
|
||||||
|
|
||||||
// Extend the addend significand to ext_precision - 1. This guarantees
|
// Extend the addend significand to ext_precision - 1. This guarantees
|
||||||
|
@ -920,7 +920,7 @@ impl<S: Semantics> Float for IeeeFloat<S> {
|
||||||
|
|
||||||
// Convert the result having "2 * S::PRECISION" significant-bits back to the one
|
// Convert the result having "2 * S::PRECISION" significant-bits back to the one
|
||||||
// having "S::PRECISION" significant-bits. First, move the radix point from
|
// having "S::PRECISION" significant-bits. First, move the radix point from
|
||||||
// poision "2*S::PRECISION - 1" to "S::PRECISION - 1". The exponent need to be
|
// position "2*S::PRECISION - 1" to "S::PRECISION - 1". The exponent need to be
|
||||||
// adjusted by "2*S::PRECISION - 1" - "S::PRECISION - 1" = "S::PRECISION".
|
// adjusted by "2*S::PRECISION - 1" - "S::PRECISION - 1" = "S::PRECISION".
|
||||||
self.exp -= S::PRECISION as ExpInt + 1;
|
self.exp -= S::PRECISION as ExpInt + 1;
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ const WASM_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
/// When rustdoc is running, provide a list of all known features so that all their respective
|
/// When rustdoc is running, provide a list of all known features so that all their respective
|
||||||
/// primtives may be documented.
|
/// primitives may be documented.
|
||||||
///
|
///
|
||||||
/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
|
/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
|
||||||
/// iterator!
|
/// iterator!
|
||||||
|
|
|
@ -613,7 +613,7 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||||
// from the CodeView line tables in the object files.
|
// from the CodeView line tables in the object files.
|
||||||
self.cmd.arg("/DEBUG");
|
self.cmd.arg("/DEBUG");
|
||||||
|
|
||||||
// This will cause the Microsoft linker to embed .natvis info into the the PDB file
|
// This will cause the Microsoft linker to embed .natvis info into the PDB file
|
||||||
let sysroot = self.sess.sysroot();
|
let sysroot = self.sess.sysroot();
|
||||||
let natvis_dir_path = sysroot.join("lib\\rustlib\\etc");
|
let natvis_dir_path = sysroot.join("lib\\rustlib\\etc");
|
||||||
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
|
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
|
||||||
|
|
|
@ -57,6 +57,7 @@ extern crate rustc_cratesio_shim;
|
||||||
|
|
||||||
pub use rustc_serialize::hex::ToHex;
|
pub use rustc_serialize::hex::ToHex;
|
||||||
|
|
||||||
|
pub mod macros;
|
||||||
pub mod svh;
|
pub mod svh;
|
||||||
pub mod base_n;
|
pub mod base_n;
|
||||||
pub mod bit_set;
|
pub mod bit_set;
|
||||||
|
|
21
src/librustc_data_structures/macros.rs
Normal file
21
src/librustc_data_structures/macros.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <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.
|
||||||
|
|
||||||
|
/// A simple static assertion macro. The first argument should be a unique
|
||||||
|
/// ALL_CAPS identifier that describes the condition.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! static_assert {
|
||||||
|
($name:ident: $test:expr) => {
|
||||||
|
// Use the bool to access an array such that if the bool is false, the access
|
||||||
|
// is out-of-bounds.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
static $name: () = [()][!$test as usize];
|
||||||
|
}
|
||||||
|
}
|
|
@ -490,7 +490,7 @@ fn create_dir(sess: &Session, path: &Path, dir_tag: &str) -> Result<(),()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocate a the lock-file and lock it.
|
/// Allocate the lock-file and lock it.
|
||||||
fn lock_directory(sess: &Session,
|
fn lock_directory(sess: &Session,
|
||||||
session_dir: &Path)
|
session_dir: &Path)
|
||||||
-> Result<(flock::Lock, PathBuf), ()> {
|
-> Result<(flock::Lock, PathBuf), ()> {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use rustc::mir::{BasicBlock, Location, Mir};
|
use rustc::mir::{BasicBlock, Location, Mir};
|
||||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||||
|
|
||||||
/// Maps between a MIR Location, which identifies the a particular
|
/// Maps between a MIR Location, which identifies a particular
|
||||||
/// statement within a basic block, to a "rich location", which
|
/// statement within a basic block, to a "rich location", which
|
||||||
/// identifies at a finer granularity. In particular, we distinguish
|
/// identifies at a finer granularity. In particular, we distinguish
|
||||||
/// the *start* of a statement and the *mid-point*. The mid-point is
|
/// the *start* of a statement and the *mid-point*. The mid-point is
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl RegionValueElements {
|
||||||
} = self.to_location(index);
|
} = self.to_location(index);
|
||||||
if statement_index == 0 {
|
if statement_index == 0 {
|
||||||
// If this is a basic block head, then the predecessors are
|
// If this is a basic block head, then the predecessors are
|
||||||
// the the terminators of other basic blocks
|
// the terminators of other basic blocks
|
||||||
stack.extend(
|
stack.extend(
|
||||||
mir.predecessors_for(block)
|
mir.predecessors_for(block)
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -17,7 +17,7 @@ use std::hash::Hash;
|
||||||
|
|
||||||
use rustc::hir::{self, def_id::DefId};
|
use rustc::hir::{self, def_id::DefId};
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::ty::{self, layout::{Size, TyLayout}, query::TyCtxtAt};
|
use rustc::ty::{self, layout::TyLayout, query::TyCtxtAt};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Allocation, AllocId, EvalResult, Scalar, AllocationExtra,
|
Allocation, AllocId, EvalResult, Scalar, AllocationExtra,
|
||||||
|
@ -174,16 +174,6 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
|
||||||
dest: PlaceTy<'tcx, Self::PointerTag>,
|
dest: PlaceTy<'tcx, Self::PointerTag>,
|
||||||
) -> EvalResult<'tcx>;
|
) -> EvalResult<'tcx>;
|
||||||
|
|
||||||
/// Hook for performing extra checks when memory gets deallocated.
|
|
||||||
#[inline]
|
|
||||||
fn memory_deallocated(
|
|
||||||
_alloc: &mut Allocation<Self::PointerTag, Self::AllocExtra>,
|
|
||||||
_ptr: Pointer<Self::PointerTag>,
|
|
||||||
_size: Size,
|
|
||||||
) -> EvalResult<'tcx> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add the tag for a newly allocated pointer.
|
/// Add the tag for a newly allocated pointer.
|
||||||
fn tag_new_allocation(
|
fn tag_new_allocation(
|
||||||
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
||||||
|
|
|
@ -225,7 +225,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||||
|
|
||||||
// Let the machine take some extra action
|
// Let the machine take some extra action
|
||||||
let size = Size::from_bytes(alloc.bytes.len() as u64);
|
let size = Size::from_bytes(alloc.bytes.len() as u64);
|
||||||
M::memory_deallocated(&mut alloc, ptr, size)?;
|
AllocationExtra::memory_deallocated(&mut alloc, ptr, size)?;
|
||||||
|
|
||||||
// Don't forget to remember size and align of this now-dead allocation
|
// Don't forget to remember size and align of this now-dead allocation
|
||||||
let old = self.dead_alloc_map.insert(
|
let old = self.dead_alloc_map.insert(
|
||||||
|
|
|
@ -1254,21 +1254,25 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let sub_span =
|
// Otherwise it's a span with wrong macro expansion info, which
|
||||||
self.span.sub_span_of_token(use_tree.span, token::BinOp(token::Star));
|
// we don't want to track anyway, since it's probably macro-internal `use`
|
||||||
if !self.span.filter_generated(use_tree.span) {
|
if let Some(sub_span) =
|
||||||
let span =
|
self.span.sub_span_of_token(use_tree.span, token::BinOp(token::Star))
|
||||||
self.span_from_span(sub_span.expect("No span found for use glob"));
|
{
|
||||||
self.dumper.import(&access, Import {
|
if !self.span.filter_generated(use_tree.span) {
|
||||||
kind: ImportKind::GlobUse,
|
let span = self.span_from_span(sub_span);
|
||||||
ref_id: None,
|
|
||||||
span,
|
self.dumper.import(&access, Import {
|
||||||
alias_span: None,
|
kind: ImportKind::GlobUse,
|
||||||
name: "*".to_owned(),
|
ref_id: None,
|
||||||
value: names.join(", "),
|
span,
|
||||||
parent,
|
alias_span: None,
|
||||||
});
|
name: "*".to_owned(),
|
||||||
self.write_sub_paths(&path);
|
value: names.join(", "),
|
||||||
|
parent,
|
||||||
|
});
|
||||||
|
self.write_sub_paths(&path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::UseTreeKind::Nested(ref nested_items) => {
|
ast::UseTreeKind::Nested(ref nested_items) => {
|
||||||
|
|
|
@ -550,7 +550,7 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||||
/// current expression. As each subpart is processed, they may set
|
/// current expression. As each subpart is processed, they may set
|
||||||
/// the flag to `Always` etc. Finally, at the end, we take the
|
/// the flag to `Always` etc. Finally, at the end, we take the
|
||||||
/// result and "union" it with the original value, so that when we
|
/// result and "union" it with the original value, so that when we
|
||||||
/// return the flag indicates if any subpart of the the parent
|
/// return the flag indicates if any subpart of the parent
|
||||||
/// expression (up to and including this part) has diverged. So,
|
/// expression (up to and including this part) has diverged. So,
|
||||||
/// if you read it after evaluating a subexpression `X`, the value
|
/// if you read it after evaluating a subexpression `X`, the value
|
||||||
/// you get indicates whether any subexpression that was
|
/// you get indicates whether any subexpression that was
|
||||||
|
|
|
@ -31,7 +31,7 @@ use syntax_pos::Span;
|
||||||
/// On-demand query: yields a map containing all types mapped to their inherent impls.
|
/// On-demand query: yields a map containing all types mapped to their inherent impls.
|
||||||
pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
crate_num: CrateNum)
|
crate_num: CrateNum)
|
||||||
-> CrateInherentImpls {
|
-> Lrc<CrateInherentImpls> {
|
||||||
assert_eq!(crate_num, LOCAL_CRATE);
|
assert_eq!(crate_num, LOCAL_CRATE);
|
||||||
|
|
||||||
let krate = tcx.hir.krate();
|
let krate = tcx.hir.krate();
|
||||||
|
@ -42,7 +42,7 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
krate.visit_all_item_likes(&mut collect);
|
krate.visit_all_item_likes(&mut collect);
|
||||||
collect.impls_map
|
Lrc::new(collect.impls_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// On-demand query: yields a vector of the inherent impls for a specific type.
|
/// On-demand query: yields a vector of the inherent impls for a specific type.
|
||||||
|
|
|
@ -3502,13 +3502,16 @@ impl Clean<Vec<Item>> for doctree::Import {
|
||||||
// forcefully don't inline if this is not public or if the
|
// forcefully don't inline if this is not public or if the
|
||||||
// #[doc(no_inline)] attribute is present.
|
// #[doc(no_inline)] attribute is present.
|
||||||
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
|
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
|
||||||
let denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
|
let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| {
|
||||||
a.name() == "doc" && match a.meta_item_list() {
|
a.name() == "doc" && match a.meta_item_list() {
|
||||||
Some(l) => attr::list_contains_name(&l, "no_inline") ||
|
Some(l) => attr::list_contains_name(&l, "no_inline") ||
|
||||||
attr::list_contains_name(&l, "hidden"),
|
attr::list_contains_name(&l, "hidden"),
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Also check whether imports were asked to be inlined, in case we're trying to re-export a
|
||||||
|
// crate in Rust 2018+
|
||||||
|
let please_inline = self.attrs.lists("doc").has_word("inline");
|
||||||
let path = self.path.clean(cx);
|
let path = self.path.clean(cx);
|
||||||
let inner = if self.glob {
|
let inner = if self.glob {
|
||||||
if !denied {
|
if !denied {
|
||||||
|
@ -3521,6 +3524,16 @@ impl Clean<Vec<Item>> for doctree::Import {
|
||||||
Import::Glob(resolve_use_source(cx, path))
|
Import::Glob(resolve_use_source(cx, path))
|
||||||
} else {
|
} else {
|
||||||
let name = self.name;
|
let name = self.name;
|
||||||
|
if !please_inline {
|
||||||
|
match path.def {
|
||||||
|
Def::Mod(did) => if !did.is_local() && did.index == CRATE_DEF_INDEX {
|
||||||
|
// if we're `pub use`ing an extern crate root, don't inline it unless we
|
||||||
|
// were specifically asked for it
|
||||||
|
denied = true;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
if !denied {
|
if !denied {
|
||||||
let mut visited = FxHashSet::default();
|
let mut visited = FxHashSet::default();
|
||||||
if let Some(items) = inline::try_inline(cx, path.def, name, &mut visited) {
|
if let Some(items) = inline::try_inline(cx, path.def, name, &mut visited) {
|
||||||
|
|
|
@ -399,7 +399,6 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
|
||||||
fn check_if_allowed_tag(t: &Tag) -> bool {
|
fn check_if_allowed_tag(t: &Tag) -> bool {
|
||||||
match *t {
|
match *t {
|
||||||
Tag::Paragraph
|
Tag::Paragraph
|
||||||
| Tag::CodeBlock(_)
|
|
||||||
| Tag::Item
|
| Tag::Item
|
||||||
| Tag::Emphasis
|
| Tag::Emphasis
|
||||||
| Tag::Strong
|
| Tag::Strong
|
||||||
|
@ -420,29 +419,36 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
||||||
if !self.started {
|
if !self.started {
|
||||||
self.started = true;
|
self.started = true;
|
||||||
}
|
}
|
||||||
let event = self.inner.next();
|
while let Some(event) = self.inner.next() {
|
||||||
let mut is_start = true;
|
let mut is_start = true;
|
||||||
let is_allowed_tag = match event {
|
let is_allowed_tag = match event {
|
||||||
Some(Event::Start(ref c)) => {
|
Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => {
|
||||||
self.depth += 1;
|
return None;
|
||||||
check_if_allowed_tag(c)
|
}
|
||||||
}
|
Event::Start(ref c) => {
|
||||||
Some(Event::End(ref c)) => {
|
self.depth += 1;
|
||||||
self.depth -= 1;
|
check_if_allowed_tag(c)
|
||||||
is_start = false;
|
}
|
||||||
check_if_allowed_tag(c)
|
Event::End(ref c) => {
|
||||||
}
|
self.depth -= 1;
|
||||||
_ => true,
|
is_start = false;
|
||||||
};
|
check_if_allowed_tag(c)
|
||||||
if is_allowed_tag == false {
|
}
|
||||||
if is_start {
|
_ => {
|
||||||
Some(Event::Start(Tag::Paragraph))
|
true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return if is_allowed_tag == false {
|
||||||
|
if is_start {
|
||||||
|
Some(Event::Start(Tag::Paragraph))
|
||||||
|
} else {
|
||||||
|
Some(Event::End(Tag::Paragraph))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Some(Event::End(Tag::Paragraph))
|
Some(event)
|
||||||
}
|
};
|
||||||
} else {
|
|
||||||
event
|
|
||||||
}
|
}
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2584,24 +2584,39 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
_ => "",
|
_ => "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let stab = myitem.stability_class();
|
||||||
|
let add = if stab.is_some() {
|
||||||
|
" "
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
let doc_value = myitem.doc_value().unwrap_or("");
|
let doc_value = myitem.doc_value().unwrap_or("");
|
||||||
write!(w, "
|
write!(w, "\
|
||||||
<tr class='{stab} module-item'>
|
<tr class='{stab}{add}module-item'>\
|
||||||
<td><a class=\"{class}\" href=\"{href}\"
|
<td><a class=\"{class}\" href=\"{href}\" \
|
||||||
title='{title_type} {title}'>{name}</a>{unsafety_flag}</td>
|
title='{title}'>{name}</a>{unsafety_flag}</td>\
|
||||||
<td class='docblock-short'>
|
<td class='docblock-short'>{stab_docs}{docs}\
|
||||||
{stab_docs} {docs}
|
</td>\
|
||||||
</td>
|
|
||||||
</tr>",
|
</tr>",
|
||||||
name = *myitem.name.as_ref().unwrap(),
|
name = *myitem.name.as_ref().unwrap(),
|
||||||
stab_docs = stab_docs,
|
stab_docs = stab_docs,
|
||||||
docs = MarkdownSummaryLine(doc_value, &myitem.links()),
|
docs = MarkdownSummaryLine(doc_value, &myitem.links()),
|
||||||
class = myitem.type_(),
|
class = myitem.type_(),
|
||||||
stab = myitem.stability_class().unwrap_or(String::new()),
|
add = add,
|
||||||
|
stab = stab.unwrap_or_else(|| String::new()),
|
||||||
unsafety_flag = unsafety_flag,
|
unsafety_flag = unsafety_flag,
|
||||||
href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()),
|
href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()),
|
||||||
title_type = myitem.type_(),
|
title = [full_path(cx, myitem), myitem.type_().to_string()]
|
||||||
title = full_path(cx, myitem))?;
|
.iter()
|
||||||
|
.filter_map(|s| if !s.is_empty() {
|
||||||
|
Some(s.as_str())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" "),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2262,17 +2262,17 @@
|
||||||
onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {
|
onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {
|
||||||
if (hasClass(e, 'compile_fail')) {
|
if (hasClass(e, 'compile_fail')) {
|
||||||
e.addEventListener("mouseover", function(event) {
|
e.addEventListener("mouseover", function(event) {
|
||||||
e.previousElementSibling.childNodes[0].style.color = '#f00';
|
this.parentElement.previousElementSibling.childNodes[0].style.color = '#f00';
|
||||||
});
|
});
|
||||||
e.addEventListener("mouseout", function(event) {
|
e.addEventListener("mouseout", function(event) {
|
||||||
e.previousElementSibling.childNodes[0].style.color = '';
|
this.parentElement.previousElementSibling.childNodes[0].style.color = '';
|
||||||
});
|
});
|
||||||
} else if (hasClass(e, 'ignore')) {
|
} else if (hasClass(e, 'ignore')) {
|
||||||
e.addEventListener("mouseover", function(event) {
|
e.addEventListener("mouseover", function(event) {
|
||||||
e.previousElementSibling.childNodes[0].style.color = '#ff9200';
|
this.parentElement.previousElementSibling.childNodes[0].style.color = '#ff9200';
|
||||||
});
|
});
|
||||||
e.addEventListener("mouseout", function(event) {
|
e.addEventListener("mouseout", function(event) {
|
||||||
e.previousElementSibling.childNodes[0].style.color = '';
|
this.parentElement.previousElementSibling.childNodes[0].style.color = '';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
lineNumbersFunc(e);
|
lineNumbersFunc(e);
|
||||||
|
|
|
@ -284,6 +284,7 @@ nav.sub {
|
||||||
|
|
||||||
body:not(.source) .example-wrap {
|
body:not(.source) .example-wrap {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.example-wrap {
|
.example-wrap {
|
||||||
|
@ -303,6 +304,10 @@ body:not(.source) .example-wrap > pre.rust {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body:not(.source) .example-wrap > pre {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#search {
|
#search {
|
||||||
margin-left: 230px;
|
margin-left: 230px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -142,6 +142,7 @@ pub use alloc_crate::alloc::*;
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct System;
|
pub struct System;
|
||||||
|
|
||||||
|
// The Alloc impl just forwards to the GlobalAlloc impl, which is in `std::sys::*::alloc`.
|
||||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||||
unsafe impl Alloc for System {
|
unsafe impl Alloc for System {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -226,6 +227,10 @@ pub fn rust_oom(layout: Layout) -> ! {
|
||||||
#[unstable(feature = "alloc_internals", issue = "0")]
|
#[unstable(feature = "alloc_internals", issue = "0")]
|
||||||
pub mod __default_lib_allocator {
|
pub mod __default_lib_allocator {
|
||||||
use super::{System, Layout, GlobalAlloc};
|
use super::{System, Layout, GlobalAlloc};
|
||||||
|
// These magic symbol names are used as a fallback for implementing the
|
||||||
|
// `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs) when there is
|
||||||
|
// no `#[global_allocator]` attribute.
|
||||||
|
|
||||||
// for symbol names src/librustc/middle/allocator.rs
|
// for symbol names src/librustc/middle/allocator.rs
|
||||||
// for signatures src/librustc_allocator/lib.rs
|
// for signatures src/librustc_allocator/lib.rs
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
/// The entry point for panic of Rust threads.
|
/// The entry point for panic of Rust threads.
|
||||||
///
|
///
|
||||||
/// This allows a program to to terminate immediately and provide feedback
|
/// This allows a program to terminate immediately and provide feedback
|
||||||
/// to the caller of the program. `panic!` should be used when a program reaches
|
/// to the caller of the program. `panic!` should be used when a program reaches
|
||||||
/// an unrecoverable problem.
|
/// an unrecoverable problem.
|
||||||
///
|
///
|
||||||
|
|
|
@ -764,14 +764,15 @@ impl Command {
|
||||||
///
|
///
|
||||||
/// ```should_panic
|
/// ```should_panic
|
||||||
/// use std::process::Command;
|
/// use std::process::Command;
|
||||||
|
/// use std::io::{self, Write};
|
||||||
/// let output = Command::new("/bin/cat")
|
/// let output = Command::new("/bin/cat")
|
||||||
/// .arg("file.txt")
|
/// .arg("file.txt")
|
||||||
/// .output()
|
/// .output()
|
||||||
/// .expect("failed to execute process");
|
/// .expect("failed to execute process");
|
||||||
///
|
///
|
||||||
/// println!("status: {}", output.status);
|
/// println!("status: {}", output.status);
|
||||||
/// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
/// io::stdout().write_all(&output.stdout).unwrap();
|
||||||
/// println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
/// io::stderr().write_all(&output.stderr).unwrap();
|
||||||
///
|
///
|
||||||
/// assert!(output.status.success());
|
/// assert!(output.status.success());
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -951,6 +952,7 @@ impl Stdio {
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use std::process::{Command, Stdio};
|
/// use std::process::{Command, Stdio};
|
||||||
|
/// use std::io::{self, Write};
|
||||||
///
|
///
|
||||||
/// let output = Command::new("rev")
|
/// let output = Command::new("rev")
|
||||||
/// .stdin(Stdio::inherit())
|
/// .stdin(Stdio::inherit())
|
||||||
|
@ -958,7 +960,8 @@ impl Stdio {
|
||||||
/// .output()
|
/// .output()
|
||||||
/// .expect("Failed to execute command");
|
/// .expect("Failed to execute command");
|
||||||
///
|
///
|
||||||
/// println!("You piped in the reverse of: {}", String::from_utf8_lossy(&output.stdout));
|
/// print!("You piped in the reverse of: ");
|
||||||
|
/// io::stdout().write_all(&output.stdout).unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "process", since = "1.0.0")]
|
#[stable(feature = "process", since = "1.0.0")]
|
||||||
pub fn inherit() -> Stdio { Stdio(imp::Stdio::Inherit) }
|
pub fn inherit() -> Stdio { Stdio(imp::Stdio::Inherit) }
|
||||||
|
|
|
@ -20,6 +20,8 @@ use print::pprust;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
use rustc_data_structures::indexed_vec;
|
use rustc_data_structures::indexed_vec;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
use rustc_data_structures::static_assert;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use source_map::{dummy_spanned, respan, Spanned};
|
use source_map::{dummy_spanned, respan, Spanned};
|
||||||
use symbol::{keywords, Symbol};
|
use symbol::{keywords, Symbol};
|
||||||
|
@ -924,6 +926,10 @@ pub struct Expr {
|
||||||
pub attrs: ThinVec<Attribute>,
|
pub attrs: ThinVec<Attribute>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
static_assert!(MEM_SIZE_OF_EXPR: std::mem::size_of::<Expr>() == 88);
|
||||||
|
|
||||||
impl Expr {
|
impl Expr {
|
||||||
/// Whether this expression would be valid somewhere that expects a value, for example, an `if`
|
/// Whether this expression would be valid somewhere that expects a value, for example, an `if`
|
||||||
/// condition.
|
/// condition.
|
||||||
|
|
|
@ -122,7 +122,7 @@ impl<'tt> TokenTreeOrTokenTreeSlice<'tt> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The the `index`-th token tree of `self`.
|
/// The `index`-th token tree of `self`.
|
||||||
fn get_tt(&self, index: usize) -> TokenTree {
|
fn get_tt(&self, index: usize) -> TokenTree {
|
||||||
match *self {
|
match *self {
|
||||||
TtSeq(ref v) => v[index].clone(),
|
TtSeq(ref v) => v[index].clone(),
|
||||||
|
|
|
@ -496,7 +496,7 @@ where
|
||||||
return (None, KleeneOp::ZeroOrMore);
|
return (None, KleeneOp::ZeroOrMore);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #2 is a Kleene op, which is the the only valid option
|
// #2 is a Kleene op, which is the only valid option
|
||||||
Ok(Ok((op, _))) => {
|
Ok(Ok((op, _))) => {
|
||||||
// Warn that `?` as a separator will be deprecated
|
// Warn that `?` as a separator will be deprecated
|
||||||
sess.buffer_lint(
|
sess.buffer_lint(
|
||||||
|
|
|
@ -1956,7 +1956,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
if suffix_illegal {
|
if suffix_illegal {
|
||||||
let sp = self.span;
|
let sp = self.span;
|
||||||
self.expect_no_suffix(sp, &format!("{} literal", lit.short_name()), suf)
|
self.expect_no_suffix(sp, lit.literal_name(), suf)
|
||||||
}
|
}
|
||||||
|
|
||||||
result.unwrap()
|
result.unwrap()
|
||||||
|
|
|
@ -79,14 +79,14 @@ pub enum Lit {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lit {
|
impl Lit {
|
||||||
crate fn short_name(&self) -> &'static str {
|
crate fn literal_name(&self) -> &'static str {
|
||||||
match *self {
|
match *self {
|
||||||
Byte(_) => "byte",
|
Byte(_) => "byte literal",
|
||||||
Char(_) => "char",
|
Char(_) => "char literal",
|
||||||
Integer(_) => "integer",
|
Integer(_) => "integer literal",
|
||||||
Float(_) => "float",
|
Float(_) => "float literal",
|
||||||
Str_(_) | StrRaw(..) => "string",
|
Str_(_) | StrRaw(..) => "string literal",
|
||||||
ByteStr(_) | ByteStrRaw(..) => "byte string"
|
ByteStr(_) | ByteStrRaw(..) => "byte string literal"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct CheckId<T:HasId> { v: T }
|
||||||
// In the code below, the impl of HasId for `&'a usize` does not
|
// In the code below, the impl of HasId for `&'a usize` does not
|
||||||
// actually access the borrowed data, but the point is that the
|
// actually access the borrowed data, but the point is that the
|
||||||
// interface to CheckId does not (and cannot) know that, and therefore
|
// interface to CheckId does not (and cannot) know that, and therefore
|
||||||
// when encountering the a value V of type CheckId<S>, we must
|
// when encountering a value V of type CheckId<S>, we must
|
||||||
// conservatively force the type S to strictly outlive V.
|
// conservatively force the type S to strictly outlive V.
|
||||||
impl<T:HasId> Drop for CheckId<T> {
|
impl<T:HasId> Drop for CheckId<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
|
|
@ -20,8 +20,8 @@ pub struct Portable;
|
||||||
// @has doc_cfg/unix_only/index.html \
|
// @has doc_cfg/unix_only/index.html \
|
||||||
// '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
|
// '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
|
||||||
// 'This is supported on Unix only.'
|
// 'This is supported on Unix only.'
|
||||||
// @matches - '//*[@class=" module-item"]//*[@class="stab portability"]' '\AUnix\Z'
|
// @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\AUnix\Z'
|
||||||
// @matches - '//*[@class=" module-item"]//*[@class="stab portability"]' '\AUnix and ARM\Z'
|
// @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\AUnix and ARM\Z'
|
||||||
// @count - '//*[@class="stab portability"]' 3
|
// @count - '//*[@class="stab portability"]' 3
|
||||||
#[doc(cfg(unix))]
|
#[doc(cfg(unix))]
|
||||||
pub mod unix_only {
|
pub mod unix_only {
|
||||||
|
@ -52,7 +52,7 @@ pub mod unix_only {
|
||||||
|
|
||||||
// the portability header is different on the module view versus the full view
|
// the portability header is different on the module view versus the full view
|
||||||
// @has doc_cfg/index.html
|
// @has doc_cfg/index.html
|
||||||
// @matches - '//*[@class=" module-item"]//*[@class="stab portability"]' '\Aavx\Z'
|
// @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\Aavx\Z'
|
||||||
|
|
||||||
// @has doc_cfg/fn.uses_target_feature.html
|
// @has doc_cfg/fn.uses_target_feature.html
|
||||||
// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
|
// @has - '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
|
||||||
|
|
15
src/test/rustdoc/inline_cross/auxiliary/use_crate.rs
Normal file
15
src/test/rustdoc/inline_cross/auxiliary/use_crate.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <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.
|
||||||
|
|
||||||
|
pub mod asdf {
|
||||||
|
pub struct SomeStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SomeTrait {}
|
11
src/test/rustdoc/inline_cross/auxiliary/use_crate_2.rs
Normal file
11
src/test/rustdoc/inline_cross/auxiliary/use_crate_2.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <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.
|
||||||
|
|
||||||
|
pub struct SomethingElse;
|
37
src/test/rustdoc/inline_cross/use_crate.rs
Normal file
37
src/test/rustdoc/inline_cross/use_crate.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <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.
|
||||||
|
|
||||||
|
// aux-build:use_crate.rs
|
||||||
|
// aux-build:use_crate_2.rs
|
||||||
|
// build-aux-docs
|
||||||
|
// edition:2018
|
||||||
|
// compile-flags:--extern use_crate --extern use_crate_2 -Z unstable-options
|
||||||
|
|
||||||
|
// During the buildup to Rust 2018, rustdoc would eagerly inline `pub use some_crate;` as if it
|
||||||
|
// were a module, so we changed it to make `pub use`ing crate roots remain as a `pub use` statement
|
||||||
|
// in docs... unless you added `#[doc(inline)]`.
|
||||||
|
|
||||||
|
#![crate_name = "local"]
|
||||||
|
|
||||||
|
// @!has-dir local/use_crate
|
||||||
|
// @has local/index.html
|
||||||
|
// @has - '//code' 'pub use use_crate'
|
||||||
|
pub use use_crate;
|
||||||
|
|
||||||
|
// @has-dir local/asdf
|
||||||
|
// @has local/asdf/index.html
|
||||||
|
// @has local/index.html '//a/@href' 'asdf/index.html'
|
||||||
|
pub use use_crate::asdf;
|
||||||
|
|
||||||
|
// @has-dir local/use_crate_2
|
||||||
|
// @has local/use_crate_2/index.html
|
||||||
|
// @has local/index.html '//a/@href' 'use_crate_2/index.html'
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use use_crate_2;
|
22
src/test/rustdoc/short-docblock-codeblock.rs
Normal file
22
src/test/rustdoc/short-docblock-codeblock.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <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.
|
||||||
|
|
||||||
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
// @has foo/index.html '//*[@class="module-item"]//td[@class="docblock-short"]' ""
|
||||||
|
// @!has foo/index.html '//*[@id="module-item"]//td[@class="docblock-short"]' "Some text."
|
||||||
|
// @!has foo/index.html '//*[@id="module-item"]//td[@class="docblock-short"]' "let x = 12;"
|
||||||
|
|
||||||
|
/// ```
|
||||||
|
/// let x = 12;
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Some text.
|
||||||
|
pub fn foo() {}
|
|
@ -18,6 +18,7 @@
|
||||||
extern crate src_links_external;
|
extern crate src_links_external;
|
||||||
|
|
||||||
// @has foo/bar/index.html '//a/@href' '../../src/src_links_external/src-links-external.rs.html#11'
|
// @has foo/bar/index.html '//a/@href' '../../src/src_links_external/src-links-external.rs.html#11'
|
||||||
|
#[doc(inline)]
|
||||||
pub use src_links_external as bar;
|
pub use src_links_external as bar;
|
||||||
|
|
||||||
// @has foo/bar/struct.Foo.html '//a/@href' '../../src/src_links_external/src-links-external.rs.html#11'
|
// @has foo/bar/struct.Foo.html '//a/@href' '../../src/src_links_external/src-links-external.rs.html#11'
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// not descend further into the mod for other occurrences of the same
|
// not descend further into the mod for other occurrences of the same
|
||||||
// error.
|
// error.
|
||||||
//
|
//
|
||||||
// This file sits on its own because the the "weird" occurrences here
|
// This file sits on its own because the "weird" occurrences here
|
||||||
// signal errors, making it incompatible with the "warnings only"
|
// signal errors, making it incompatible with the "warnings only"
|
||||||
// nature of issue-43106-gating-of-builtin-attrs.rs
|
// nature of issue-43106-gating-of-builtin-attrs.rs
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
// run-pass
|
||||||
|
|
||||||
|
// This file checks that `PhantomData` is considered structurally matchable.
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
// A type which is not structurally matchable:
|
||||||
|
struct NotSM;
|
||||||
|
|
||||||
|
// And one that is:
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
struct SM;
|
||||||
|
|
||||||
|
// Check that SM is #[structural_match]:
|
||||||
|
const CSM: SM = SM;
|
||||||
|
match SM {
|
||||||
|
CSM => count += 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check that PhantomData<T> is #[structural_match] even if T is not.
|
||||||
|
const CPD1: PhantomData<NotSM> = PhantomData;
|
||||||
|
match PhantomData {
|
||||||
|
CPD1 => count += 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check that PhantomData<T> is #[structural_match] when T is.
|
||||||
|
const CPD2: PhantomData<SM> = PhantomData;
|
||||||
|
match PhantomData {
|
||||||
|
CPD2 => count += 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check that a type which has a PhantomData is `#[structural_match]`.
|
||||||
|
#[derive(PartialEq, Eq, Default)]
|
||||||
|
struct Foo {
|
||||||
|
alpha: PhantomData<NotSM>,
|
||||||
|
beta: PhantomData<SM>,
|
||||||
|
}
|
||||||
|
|
||||||
|
const CFOO: Foo = Foo {
|
||||||
|
alpha: PhantomData,
|
||||||
|
beta: PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
|
match Foo::default() {
|
||||||
|
CFOO => count += 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Final count must be 4 now if all
|
||||||
|
assert_eq!(count, 4);
|
||||||
|
}
|
|
@ -490,7 +490,7 @@ impl TestProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.compile_pass {
|
if !self.compile_pass {
|
||||||
// run-pass implies must_compile_sucessfully
|
// run-pass implies must_compile_successfully
|
||||||
self.compile_pass = config.parse_compile_pass(ln) || self.run_pass;
|
self.compile_pass = config.parse_compile_pass(ln) || self.run_pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue