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].
|
||||
|
||||
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/dep_graph
|
||||
- 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
|
||||
if sys.platform == 'win32':
|
||||
run(["PowerShell.exe", "/nologo", "-Command",
|
||||
"(New-Object System.Net.WebClient)"
|
||||
".DownloadFile('{}', '{}')".format(url, path)],
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
|
||||
"(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)],
|
||||
verbose=verbose,
|
||||
exception=exception)
|
||||
else:
|
||||
|
|
|
@ -203,7 +203,7 @@ impl Step for StdLink {
|
|||
|
||||
/// 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`.
|
||||
///
|
||||
/// 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.
|
||||
|
||||
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)]`
|
||||
|
||||
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
|
||||
# the other.
|
||||
# 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
|
||||
# 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::*;
|
||||
|
||||
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]
|
||||
#[rustc_allocator_nounwind]
|
||||
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
|
||||
|
|
|
@ -73,7 +73,7 @@ use core::convert::From;
|
|||
use core::fmt;
|
||||
use core::future::Future;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::iter::FusedIterator;
|
||||
use core::iter::{Iterator, FromIterator, FusedIterator};
|
||||
use core::marker::{Unpin, Unsize};
|
||||
use core::mem;
|
||||
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::task::{LocalWaker, Poll};
|
||||
|
||||
use vec::Vec;
|
||||
use raw_vec::RawVec;
|
||||
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")]
|
||||
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")]
|
||||
impl<T: Clone> Clone for Box<[T]> {
|
||||
fn clone(&self) -> Self {
|
||||
|
|
|
@ -140,3 +140,11 @@ fn str_slice() {
|
|||
let boxed: Box<str> = Box::from(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;
|
||||
///
|
||||
/// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"].iter()
|
||||
/// .map(|&s| (s, 0))
|
||||
/// .collect();
|
||||
/// let mut map: BTreeMap<&str, i32> = ["Alice", "Bob", "Carol", "Cheryl"]
|
||||
/// .iter()
|
||||
/// .map(|&s| (s, 0))
|
||||
/// .collect();
|
||||
/// for (_, balance) in map.range_mut("B".."Cheryl") {
|
||||
/// *balance += 100;
|
||||
/// }
|
||||
|
|
|
@ -2206,6 +2206,20 @@ impl<'a> From<&'a str> for String {
|
|||
#[cfg(not(test))]
|
||||
#[stable(feature = "string_from_box", since = "1.18.0")]
|
||||
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 {
|
||||
s.into_string()
|
||||
}
|
||||
|
@ -2213,6 +2227,19 @@ impl From<Box<str>> for String {
|
|||
|
||||
#[stable(feature = "box_from_str", since = "1.20.0")]
|
||||
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> {
|
||||
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")]
|
||||
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> {
|
||||
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
|
||||
/// 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
|
||||
/// you need a fused iterator. Instead, you should just call [`Iterator::fuse`]
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
#![feature(const_transmute)]
|
||||
#![feature(reverse_bits)]
|
||||
#![feature(non_exhaustive)]
|
||||
#![feature(structural_match)]
|
||||
|
||||
#[prelude_import]
|
||||
#[allow(unused)]
|
||||
|
|
|
@ -578,6 +578,7 @@ macro_rules! impls{
|
|||
///
|
||||
/// [drop check]: ../../nomicon/dropck.html
|
||||
#[lang = "phantom_data"]
|
||||
#[structural_match]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct PhantomData<T:?Sized>;
|
||||
|
||||
|
|
|
@ -1896,7 +1896,7 @@ mod traits {
|
|||
#[inline]
|
||||
fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
// 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 &&
|
||||
slice.is_char_boundary(self.start) &&
|
||||
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::UnsafetyCheckResult { violations, unsafe_blocks });
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>>
|
||||
for mir::BorrowKind {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
impl_stable_hash_for!(enum mir::BorrowKind {
|
||||
Shared,
|
||||
Shallow,
|
||||
Unique,
|
||||
Mut { allow_two_phase_borrow },
|
||||
});
|
||||
|
||||
match *self {
|
||||
mir::BorrowKind::Shared |
|
||||
mir::BorrowKind::Shallow |
|
||||
mir::BorrowKind::Unique => {}
|
||||
mir::BorrowKind::Mut { allow_two_phase_borrow } => {
|
||||
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!(enum mir::UnsafetyViolationKind {
|
||||
General,
|
||||
MinConstFn,
|
||||
ExternStatic(lint_node_id),
|
||||
BorrowPacked(lint_node_id),
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct mir::Terminator<'tcx> {
|
||||
kind,
|
||||
source_info
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for mir::ClearCrossCrate<T>
|
||||
where T: HashStable<StableHashingContext<'a>>
|
||||
{
|
||||
#[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::ClearCrossCrate::Clear => {}
|
||||
mir::ClearCrossCrate::Set(ref value) => {
|
||||
value.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
impl_stable_hash_for!(
|
||||
impl<T> for enum mir::ClearCrossCrate<T> [ mir::ClearCrossCrate ] {
|
||||
Clear,
|
||||
Set(value),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
|
||||
#[inline]
|
||||
|
|
|
@ -224,20 +224,10 @@ impl_stable_hash_for!(enum ty::BorrowKind {
|
|||
MutBorrow
|
||||
});
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
||||
for ty::UpvarCapture<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
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!(impl<'gcx> for enum ty::UpvarCapture<'gcx> [ ty::UpvarCapture ] {
|
||||
ByValue,
|
||||
ByRef(up_var_borrow),
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ty::GenSig<'tcx> {
|
||||
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::TraitPredicate<'tcx> { trait_ref });
|
||||
impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, 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!(impl<A, B> for tuple_struct ty::OutlivesPredicate<A, B> { a, b });
|
||||
impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
|
||||
impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { substs, item_def_id });
|
||||
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::Predicate<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
match *self {
|
||||
ty::Predicate::Trait(ref pred) => {
|
||||
pred.hash_stable(hcx, hasher);
|
||||
}
|
||||
ty::Predicate::Subtype(ref pred) => {
|
||||
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_stable_hash_for!(
|
||||
impl<'tcx> for enum ty::Predicate<'tcx> [ ty::Predicate ] {
|
||||
Trait(pred),
|
||||
Subtype(pred),
|
||||
RegionOutlives(pred),
|
||||
TypeOutlives(pred),
|
||||
Projection(pred),
|
||||
WellFormed(ty),
|
||||
ObjectSafe(def_id),
|
||||
ClosureKind(def_id, closure_substs, closure_kind),
|
||||
ConstEvaluatable(def_id, substs),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for ty::AdtFlags {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
|
@ -358,70 +307,39 @@ impl_stable_hash_for!(struct ty::FieldDef {
|
|||
vis,
|
||||
});
|
||||
|
||||
impl<'a, 'gcx> HashStable<StableHashingContext<'a>>
|
||||
for ::mir::interpret::ConstValue<'gcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
use mir::interpret::ConstValue::*;
|
||||
impl_stable_hash_for!(
|
||||
impl<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
|
||||
Unevaluated(def_id, substs),
|
||||
Scalar(val),
|
||||
ScalarPair(a, b),
|
||||
ByRef(id, alloc, offset),
|
||||
}
|
||||
);
|
||||
|
||||
mem::discriminant(self).hash_stable(hcx, hasher);
|
||||
|
||||
match *self {
|
||||
Unevaluated(def_id, substs) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
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_stable_hash_for! {
|
||||
impl<Tag> for struct mir::interpret::Pointer<Tag> {
|
||||
alloc_id,
|
||||
offset,
|
||||
tag,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Tag> HashStable<StableHashingContext<'a>>
|
||||
for ::mir::interpret::Pointer<Tag>
|
||||
where Tag: HashStable<StableHashingContext<'a>>
|
||||
{
|
||||
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_stable_hash_for!(
|
||||
impl<Tag> for enum mir::interpret::Scalar<Tag> [ mir::interpret::Scalar ] {
|
||||
Bits { bits, size },
|
||||
Ptr(ptr),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl<'a, Tag> HashStable<StableHashingContext<'a>>
|
||||
for ::mir::interpret::Scalar<Tag>
|
||||
where Tag: HashStable<StableHashingContext<'a>>
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
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),
|
||||
}
|
||||
impl_stable_hash_for!(
|
||||
impl<'tcx, M> for enum mir::interpret::AllocType<'tcx, M> [ mir::interpret::AllocType ] {
|
||||
Function(instance),
|
||||
Static(def_id),
|
||||
Memory(mem),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// AllocIds get resolved to whatever they point to (to be stable)
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
|
||||
fn hash_stable<W: StableHasherResult>(
|
||||
&self,
|
||||
|
@ -437,23 +355,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, M: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allocations treat their relocations specially
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
|
||||
fn hash_stable<W: StableHasherResult>(
|
||||
&self,
|
||||
|
@ -485,7 +387,7 @@ impl_stable_hash_for!(enum mir::interpret::ErrorHandled {
|
|||
TooGeneric
|
||||
});
|
||||
|
||||
impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
|
||||
impl_stable_hash_for!(struct mir::interpret::FrameInfo {
|
||||
span,
|
||||
lint_root,
|
||||
location
|
||||
|
@ -499,124 +401,75 @@ impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
|
|||
predicates
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, O: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
|
||||
for ::mir::interpret::EvalErrorKind<'gcx, O> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
use mir::interpret::EvalErrorKind::*;
|
||||
|
||||
mem::discriminant(&self).hash_stable(hcx, hasher);
|
||||
|
||||
match *self {
|
||||
FunctionArgCountMismatch |
|
||||
DanglingPointerDeref |
|
||||
DoubleFree |
|
||||
InvalidMemoryAccess |
|
||||
InvalidFunctionPointer |
|
||||
InvalidBool |
|
||||
InvalidNullPointerUsage |
|
||||
ReadPointerAsBytes |
|
||||
ReadBytesAsPointer |
|
||||
ReadForeignStatic |
|
||||
InvalidPointerMath |
|
||||
DeadLocal |
|
||||
StackFrameLimitReached |
|
||||
OutOfTls |
|
||||
TlsOutOfBounds |
|
||||
CalledClosureAsFunction |
|
||||
VtableForArgumentlessMethod |
|
||||
ModifiedConstantMemory |
|
||||
AssumptionNotHeld |
|
||||
InlineAsm |
|
||||
ReallocateNonBasePtr |
|
||||
DeallocateNonBasePtr |
|
||||
HeapAllocZeroBytes |
|
||||
Unreachable |
|
||||
ReadFromReturnPointer |
|
||||
UnimplementedTraitSelection |
|
||||
TypeckError |
|
||||
TooGeneric |
|
||||
DerefFunctionPointer |
|
||||
ExecuteMemory |
|
||||
OverflowNeg |
|
||||
RemainderByZero |
|
||||
DivisionByZero |
|
||||
GeneratorResumedAfterReturn |
|
||||
GeneratorResumedAfterPanic |
|
||||
ReferencedConstant |
|
||||
InfiniteLoop => {}
|
||||
ReadUndefBytes(offset) => offset.hash_stable(hcx, hasher),
|
||||
InvalidDiscriminant(val) => val.hash_stable(hcx, hasher),
|
||||
Panic { ref msg, ref file, line, col } => {
|
||||
msg.hash_stable(hcx, hasher);
|
||||
file.hash_stable(hcx, hasher);
|
||||
line.hash_stable(hcx, hasher);
|
||||
col.hash_stable(hcx, hasher);
|
||||
},
|
||||
MachineError(ref err) => err.hash_stable(hcx, hasher),
|
||||
FunctionAbiMismatch(a, b) => {
|
||||
a.hash_stable(hcx, hasher);
|
||||
b.hash_stable(hcx, hasher)
|
||||
},
|
||||
FunctionArgMismatch(a, b) => {
|
||||
a.hash_stable(hcx, hasher);
|
||||
b.hash_stable(hcx, hasher)
|
||||
},
|
||||
FunctionRetMismatch(a, b) => {
|
||||
a.hash_stable(hcx, hasher);
|
||||
b.hash_stable(hcx, hasher)
|
||||
},
|
||||
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!(
|
||||
impl<'tcx, O> for enum mir::interpret::EvalErrorKind<'tcx, O>
|
||||
[ mir::interpret::EvalErrorKind ]
|
||||
{
|
||||
FunctionArgCountMismatch,
|
||||
DanglingPointerDeref,
|
||||
DoubleFree,
|
||||
InvalidMemoryAccess,
|
||||
InvalidFunctionPointer,
|
||||
InvalidBool,
|
||||
InvalidNullPointerUsage,
|
||||
ReadPointerAsBytes,
|
||||
ReadBytesAsPointer,
|
||||
ReadForeignStatic,
|
||||
InvalidPointerMath,
|
||||
DeadLocal,
|
||||
StackFrameLimitReached,
|
||||
OutOfTls,
|
||||
TlsOutOfBounds,
|
||||
CalledClosureAsFunction,
|
||||
VtableForArgumentlessMethod,
|
||||
ModifiedConstantMemory,
|
||||
AssumptionNotHeld,
|
||||
InlineAsm,
|
||||
ReallocateNonBasePtr,
|
||||
DeallocateNonBasePtr,
|
||||
HeapAllocZeroBytes,
|
||||
Unreachable,
|
||||
ReadFromReturnPointer,
|
||||
UnimplementedTraitSelection,
|
||||
TypeckError,
|
||||
TooGeneric,
|
||||
DerefFunctionPointer,
|
||||
ExecuteMemory,
|
||||
OverflowNeg,
|
||||
RemainderByZero,
|
||||
DivisionByZero,
|
||||
GeneratorResumedAfterReturn,
|
||||
GeneratorResumedAfterPanic,
|
||||
ReferencedConstant,
|
||||
InfiniteLoop,
|
||||
ReadUndefBytes(offset),
|
||||
InvalidDiscriminant(val),
|
||||
Panic { msg, file, line, col },
|
||||
MachineError(err),
|
||||
FunctionAbiMismatch(a, b),
|
||||
FunctionArgMismatch(a, b),
|
||||
FunctionRetMismatch(a, b),
|
||||
NoMirFor(s),
|
||||
UnterminatedCString(ptr),
|
||||
PointerOutOfBounds { ptr, access, allocation_size },
|
||||
InvalidBoolOp(bop),
|
||||
Unimplemented(s),
|
||||
BoundsCheck { len, index },
|
||||
Intrinsic(s),
|
||||
InvalidChar(c),
|
||||
AbiViolation(s),
|
||||
AlignmentCheckFailed { required, has },
|
||||
ValidationFailure(s),
|
||||
TypeNotPrimitive(ty),
|
||||
ReallocatedWrongMemoryKind(a, b),
|
||||
DeallocatedWrongMemoryKind(a, b),
|
||||
IncorrectAllocationInformation(a, b, c, d),
|
||||
Layout(lay),
|
||||
HeapAllocNonPowerOfTwoAlignment(n),
|
||||
PathNotFound(v),
|
||||
Overflow(op),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl_stable_hash_for!(enum mir::interpret::Lock {
|
||||
NoLock,
|
||||
|
@ -663,47 +516,18 @@ impl_stable_hash_for!(struct ty::GenericParamDef {
|
|||
kind
|
||||
});
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for ty::GenericParamDefKind {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
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_stable_hash_for!(enum ty::GenericParamDefKind {
|
||||
Lifetime,
|
||||
Type { has_default, object_lifetime_default, synthetic },
|
||||
});
|
||||
|
||||
impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
|
||||
for ::middle::resolve_lifetime::Set1<T>
|
||||
where T: HashStable<StableHashingContext<'a>>
|
||||
{
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
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!(
|
||||
impl<T> for enum ::middle::resolve_lifetime::Set1<T> [ ::middle::resolve_lifetime::Set1 ] {
|
||||
Empty,
|
||||
Many,
|
||||
One(value),
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl_stable_hash_for!(enum ::middle::resolve_lifetime::LifetimeDefOrigin {
|
||||
ExplicitOrElided,
|
||||
|
@ -1250,7 +1074,7 @@ impl_stable_hash_for!(
|
|||
);
|
||||
|
||||
impl_stable_hash_for!(
|
||||
impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
|
||||
struct infer::canonical::CanonicalVarValues<'tcx> {
|
||||
var_values
|
||||
}
|
||||
);
|
||||
|
@ -1369,7 +1193,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
|
|||
}
|
||||
|
||||
impl_stable_hash_for!(
|
||||
impl<'tcx> for struct traits::ProgramClause<'tcx> {
|
||||
struct traits::ProgramClause<'tcx> {
|
||||
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!(
|
||||
impl<'tcx> for struct traits::Environment<'tcx> {
|
||||
struct traits::Environment<'tcx> {
|
||||
clauses,
|
||||
}
|
||||
);
|
||||
|
|
|
@ -132,7 +132,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
///
|
||||
/// See the `region_obligations` field of `InferCtxt` for some
|
||||
/// 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 --
|
||||
/// towards the end of regionck. This also ensures that the
|
||||
/// 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_rules! __impl_stable_hash_field {
|
||||
($field:ident, $ctx:expr, $hasher:expr) => ($field.hash_stable($ctx, $hasher));
|
||||
|
@ -81,6 +71,7 @@ macro_rules! __impl_stable_hash_field {
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! impl_stable_hash_for {
|
||||
// Enums
|
||||
// FIXME(mark-i-m): Some of these should be `?` rather than `*`. See the git blame and change
|
||||
// them back when `?` is supported again.
|
||||
(enum $enum_name:path {
|
||||
|
@ -91,12 +82,37 @@ macro_rules! impl_stable_hash_for {
|
|||
$( { $($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]
|
||||
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>) {
|
||||
use $enum_name::*;
|
||||
use $enum_path::*;
|
||||
::std::mem::discriminant(self).hash_stable(__ctx, __hasher);
|
||||
|
||||
match *self {
|
||||
|
@ -110,41 +126,17 @@ macro_rules! impl_stable_hash_for {
|
|||
}
|
||||
}
|
||||
};
|
||||
// Structs
|
||||
// FIXME(mark-i-m): same here.
|
||||
(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_stable_hash_for!(
|
||||
impl<'tcx> for struct $struct_name { $($field $(-> $delegate)*),* }
|
||||
);
|
||||
};
|
||||
// FIXME(mark-i-m): same here.
|
||||
(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 {
|
||||
(impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*> for struct $struct_name:path {
|
||||
$($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
|
||||
where $($T: ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a>>),*
|
||||
{
|
||||
|
@ -156,6 +148,32 @@ macro_rules! impl_stable_hash_for {
|
|||
$(ref $field),*
|
||||
} = *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)*) );*
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,17 @@ pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Default + Clone {
|
|||
) -> EvalResult<'tcx> {
|
||||
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 () {}
|
||||
|
|
|
@ -1720,14 +1720,14 @@ pub struct Statement<'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> {
|
||||
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
|
||||
/// invalidating statement indices in `Location`s.
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
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
|
||||
// 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
|
||||
// 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.
|
||||
|
@ -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);
|
||||
// [(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
|
||||
// // 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> {
|
||||
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_region = |r| {
|
||||
if let Some(r) = interners.region.borrow().get(&r) {
|
||||
|
|
|
@ -515,6 +515,10 @@ pub struct TyS<'tcx> {
|
|||
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> {
|
||||
fn cmp(&self, other: &TyS<'tcx>) -> Ordering {
|
||||
self.sty.cmp(&other.sty)
|
||||
|
|
|
@ -291,7 +291,8 @@ define_queries! { <'tcx>
|
|||
/// Gets a complete map from all types to their inherent impls.
|
||||
/// Not meant to be used directly outside of coherence.
|
||||
/// (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.
|
||||
/// 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> {
|
||||
/// 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.
|
||||
/// If the query is executing elsewhere, this will wait for it.
|
||||
/// 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.
|
||||
/// 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
|
||||
/// 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> {
|
||||
match self.dep_graph.node_color(dep_node) {
|
||||
Some(DepNodeColor::Green(dep_node_index)) => {
|
||||
|
|
|
@ -211,6 +211,10 @@ pub enum TyKind<'tcx> {
|
|||
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:
|
||||
///
|
||||
/// 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"
|
||||
// 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];
|
||||
|
||||
// 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
|
||||
// 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".
|
||||
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
|
||||
/// 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
|
||||
/// iterator!
|
||||
|
|
|
@ -613,7 +613,7 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
// from the CodeView line tables in the object files.
|
||||
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 natvis_dir_path = sysroot.join("lib\\rustlib\\etc");
|
||||
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 mod macros;
|
||||
pub mod svh;
|
||||
pub mod base_n;
|
||||
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,
|
||||
session_dir: &Path)
|
||||
-> Result<(flock::Lock, PathBuf), ()> {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
use rustc::mir::{BasicBlock, Location, Mir};
|
||||
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
|
||||
/// identifies at a finer granularity. In particular, we distinguish
|
||||
/// the *start* of a statement and the *mid-point*. The mid-point is
|
||||
|
|
|
@ -112,7 +112,7 @@ impl RegionValueElements {
|
|||
} = self.to_location(index);
|
||||
if statement_index == 0 {
|
||||
// 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(
|
||||
mir.predecessors_for(block)
|
||||
.iter()
|
||||
|
|
|
@ -17,7 +17,7 @@ use std::hash::Hash;
|
|||
|
||||
use rustc::hir::{self, def_id::DefId};
|
||||
use rustc::mir;
|
||||
use rustc::ty::{self, layout::{Size, TyLayout}, query::TyCtxtAt};
|
||||
use rustc::ty::{self, layout::TyLayout, query::TyCtxtAt};
|
||||
|
||||
use super::{
|
||||
Allocation, AllocId, EvalResult, Scalar, AllocationExtra,
|
||||
|
@ -174,16 +174,6 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
|
|||
dest: PlaceTy<'tcx, Self::PointerTag>,
|
||||
) -> 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.
|
||||
fn tag_new_allocation(
|
||||
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 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
|
||||
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()
|
||||
};
|
||||
|
||||
let sub_span =
|
||||
self.span.sub_span_of_token(use_tree.span, token::BinOp(token::Star));
|
||||
if !self.span.filter_generated(use_tree.span) {
|
||||
let span =
|
||||
self.span_from_span(sub_span.expect("No span found for use glob"));
|
||||
self.dumper.import(&access, Import {
|
||||
kind: ImportKind::GlobUse,
|
||||
ref_id: None,
|
||||
span,
|
||||
alias_span: None,
|
||||
name: "*".to_owned(),
|
||||
value: names.join(", "),
|
||||
parent,
|
||||
});
|
||||
self.write_sub_paths(&path);
|
||||
// Otherwise it's a span with wrong macro expansion info, which
|
||||
// we don't want to track anyway, since it's probably macro-internal `use`
|
||||
if let Some(sub_span) =
|
||||
self.span.sub_span_of_token(use_tree.span, token::BinOp(token::Star))
|
||||
{
|
||||
if !self.span.filter_generated(use_tree.span) {
|
||||
let span = self.span_from_span(sub_span);
|
||||
|
||||
self.dumper.import(&access, Import {
|
||||
kind: ImportKind::GlobUse,
|
||||
ref_id: None,
|
||||
span,
|
||||
alias_span: None,
|
||||
name: "*".to_owned(),
|
||||
value: names.join(", "),
|
||||
parent,
|
||||
});
|
||||
self.write_sub_paths(&path);
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
/// the flag to `Always` etc. Finally, at the end, we take the
|
||||
/// 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,
|
||||
/// if you read it after evaluating a subexpression `X`, the value
|
||||
/// 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.
|
||||
pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
crate_num: CrateNum)
|
||||
-> CrateInherentImpls {
|
||||
-> Lrc<CrateInherentImpls> {
|
||||
assert_eq!(crate_num, LOCAL_CRATE);
|
||||
|
||||
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);
|
||||
collect.impls_map
|
||||
Lrc::new(collect.impls_map)
|
||||
}
|
||||
|
||||
/// 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
|
||||
// #[doc(no_inline)] attribute is present.
|
||||
// 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() {
|
||||
Some(l) => attr::list_contains_name(&l, "no_inline") ||
|
||||
attr::list_contains_name(&l, "hidden"),
|
||||
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 inner = if self.glob {
|
||||
if !denied {
|
||||
|
@ -3521,6 +3524,16 @@ impl Clean<Vec<Item>> for doctree::Import {
|
|||
Import::Glob(resolve_use_source(cx, path))
|
||||
} else {
|
||||
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 {
|
||||
let mut visited = FxHashSet::default();
|
||||
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 {
|
||||
match *t {
|
||||
Tag::Paragraph
|
||||
| Tag::CodeBlock(_)
|
||||
| Tag::Item
|
||||
| Tag::Emphasis
|
||||
| Tag::Strong
|
||||
|
@ -420,29 +419,36 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
|||
if !self.started {
|
||||
self.started = true;
|
||||
}
|
||||
let event = self.inner.next();
|
||||
let mut is_start = true;
|
||||
let is_allowed_tag = match event {
|
||||
Some(Event::Start(ref c)) => {
|
||||
self.depth += 1;
|
||||
check_if_allowed_tag(c)
|
||||
}
|
||||
Some(Event::End(ref c)) => {
|
||||
self.depth -= 1;
|
||||
is_start = false;
|
||||
check_if_allowed_tag(c)
|
||||
}
|
||||
_ => true,
|
||||
};
|
||||
if is_allowed_tag == false {
|
||||
if is_start {
|
||||
Some(Event::Start(Tag::Paragraph))
|
||||
while let Some(event) = self.inner.next() {
|
||||
let mut is_start = true;
|
||||
let is_allowed_tag = match event {
|
||||
Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => {
|
||||
return None;
|
||||
}
|
||||
Event::Start(ref c) => {
|
||||
self.depth += 1;
|
||||
check_if_allowed_tag(c)
|
||||
}
|
||||
Event::End(ref c) => {
|
||||
self.depth -= 1;
|
||||
is_start = false;
|
||||
check_if_allowed_tag(c)
|
||||
}
|
||||
_ => {
|
||||
true
|
||||
}
|
||||
};
|
||||
return if is_allowed_tag == false {
|
||||
if is_start {
|
||||
Some(Event::Start(Tag::Paragraph))
|
||||
} else {
|
||||
Some(Event::End(Tag::Paragraph))
|
||||
}
|
||||
} else {
|
||||
Some(Event::End(Tag::Paragraph))
|
||||
}
|
||||
} else {
|
||||
event
|
||||
Some(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("");
|
||||
write!(w, "
|
||||
<tr class='{stab} module-item'>
|
||||
<td><a class=\"{class}\" href=\"{href}\"
|
||||
title='{title_type} {title}'>{name}</a>{unsafety_flag}</td>
|
||||
<td class='docblock-short'>
|
||||
{stab_docs} {docs}
|
||||
</td>
|
||||
write!(w, "\
|
||||
<tr class='{stab}{add}module-item'>\
|
||||
<td><a class=\"{class}\" href=\"{href}\" \
|
||||
title='{title}'>{name}</a>{unsafety_flag}</td>\
|
||||
<td class='docblock-short'>{stab_docs}{docs}\
|
||||
</td>\
|
||||
</tr>",
|
||||
name = *myitem.name.as_ref().unwrap(),
|
||||
stab_docs = stab_docs,
|
||||
docs = MarkdownSummaryLine(doc_value, &myitem.links()),
|
||||
class = myitem.type_(),
|
||||
stab = myitem.stability_class().unwrap_or(String::new()),
|
||||
add = add,
|
||||
stab = stab.unwrap_or_else(|| String::new()),
|
||||
unsafety_flag = unsafety_flag,
|
||||
href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()),
|
||||
title_type = myitem.type_(),
|
||||
title = full_path(cx, myitem))?;
|
||||
title = [full_path(cx, myitem), myitem.type_().to_string()]
|
||||
.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) {
|
||||
if (hasClass(e, 'compile_fail')) {
|
||||
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.previousElementSibling.childNodes[0].style.color = '';
|
||||
this.parentElement.previousElementSibling.childNodes[0].style.color = '';
|
||||
});
|
||||
} else if (hasClass(e, 'ignore')) {
|
||||
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.previousElementSibling.childNodes[0].style.color = '';
|
||||
this.parentElement.previousElementSibling.childNodes[0].style.color = '';
|
||||
});
|
||||
}
|
||||
lineNumbersFunc(e);
|
||||
|
|
|
@ -284,6 +284,7 @@ nav.sub {
|
|||
|
||||
body:not(.source) .example-wrap {
|
||||
display: inline-flex;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.example-wrap {
|
||||
|
@ -303,6 +304,10 @@ body:not(.source) .example-wrap > pre.rust {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
body:not(.source) .example-wrap > pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#search {
|
||||
margin-left: 230px;
|
||||
position: relative;
|
||||
|
|
|
@ -142,6 +142,7 @@ pub use alloc_crate::alloc::*;
|
|||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct System;
|
||||
|
||||
// The Alloc impl just forwards to the GlobalAlloc impl, which is in `std::sys::*::alloc`.
|
||||
#[unstable(feature = "allocator_api", issue = "32838")]
|
||||
unsafe impl Alloc for System {
|
||||
#[inline]
|
||||
|
@ -226,6 +227,10 @@ pub fn rust_oom(layout: Layout) -> ! {
|
|||
#[unstable(feature = "alloc_internals", issue = "0")]
|
||||
pub mod __default_lib_allocator {
|
||||
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 signatures src/librustc_allocator/lib.rs
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
/// 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
|
||||
/// an unrecoverable problem.
|
||||
///
|
||||
|
|
|
@ -764,14 +764,15 @@ impl Command {
|
|||
///
|
||||
/// ```should_panic
|
||||
/// use std::process::Command;
|
||||
/// use std::io::{self, Write};
|
||||
/// let output = Command::new("/bin/cat")
|
||||
/// .arg("file.txt")
|
||||
/// .output()
|
||||
/// .expect("failed to execute process");
|
||||
///
|
||||
/// println!("status: {}", output.status);
|
||||
/// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
|
||||
/// println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
|
||||
/// io::stdout().write_all(&output.stdout).unwrap();
|
||||
/// io::stderr().write_all(&output.stderr).unwrap();
|
||||
///
|
||||
/// assert!(output.status.success());
|
||||
/// ```
|
||||
|
@ -951,6 +952,7 @@ impl Stdio {
|
|||
///
|
||||
/// ```no_run
|
||||
/// use std::process::{Command, Stdio};
|
||||
/// use std::io::{self, Write};
|
||||
///
|
||||
/// let output = Command::new("rev")
|
||||
/// .stdin(Stdio::inherit())
|
||||
|
@ -958,7 +960,8 @@ impl Stdio {
|
|||
/// .output()
|
||||
/// .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")]
|
||||
pub fn inherit() -> Stdio { Stdio(imp::Stdio::Inherit) }
|
||||
|
|
|
@ -20,6 +20,8 @@ use print::pprust;
|
|||
use ptr::P;
|
||||
use rustc_data_structures::indexed_vec;
|
||||
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 source_map::{dummy_spanned, respan, Spanned};
|
||||
use symbol::{keywords, Symbol};
|
||||
|
@ -924,6 +926,10 @@ pub struct Expr {
|
|||
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 {
|
||||
/// Whether this expression would be valid somewhere that expects a value, for example, an `if`
|
||||
/// 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 {
|
||||
match *self {
|
||||
TtSeq(ref v) => v[index].clone(),
|
||||
|
|
|
@ -496,7 +496,7 @@ where
|
|||
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, _))) => {
|
||||
// Warn that `?` as a separator will be deprecated
|
||||
sess.buffer_lint(
|
||||
|
|
|
@ -1956,7 +1956,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
if suffix_illegal {
|
||||
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()
|
||||
|
|
|
@ -79,14 +79,14 @@ pub enum Lit {
|
|||
}
|
||||
|
||||
impl Lit {
|
||||
crate fn short_name(&self) -> &'static str {
|
||||
crate fn literal_name(&self) -> &'static str {
|
||||
match *self {
|
||||
Byte(_) => "byte",
|
||||
Char(_) => "char",
|
||||
Integer(_) => "integer",
|
||||
Float(_) => "float",
|
||||
Str_(_) | StrRaw(..) => "string",
|
||||
ByteStr(_) | ByteStrRaw(..) => "byte string"
|
||||
Byte(_) => "byte literal",
|
||||
Char(_) => "char literal",
|
||||
Integer(_) => "integer literal",
|
||||
Float(_) => "float literal",
|
||||
Str_(_) | StrRaw(..) => "string literal",
|
||||
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
|
||||
// actually access the borrowed data, but the point is that the
|
||||
// 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.
|
||||
impl<T:HasId> Drop for CheckId<T> {
|
||||
fn drop(&mut self) {
|
||||
|
|
|
@ -20,8 +20,8 @@ pub struct Portable;
|
|||
// @has doc_cfg/unix_only/index.html \
|
||||
// '//*[@id="main"]/*[@class="stability"]/*[@class="stab portability"]' \
|
||||
// 'This is supported on Unix only.'
|
||||
// @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\Z'
|
||||
// @matches - '//*[@class="module-item"]//*[@class="stab portability"]' '\AUnix and ARM\Z'
|
||||
// @count - '//*[@class="stab portability"]' 3
|
||||
#[doc(cfg(unix))]
|
||||
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
|
||||
// @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 - '//*[@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;
|
||||
|
||||
// @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;
|
||||
|
||||
// @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
|
||||
// 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"
|
||||
// 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 {
|
||||
// run-pass implies must_compile_sucessfully
|
||||
// run-pass implies must_compile_successfully
|
||||
self.compile_pass = config.parse_compile_pass(ln) || self.run_pass;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue