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:
bors 2018-11-13 22:17:46 +00:00
commit f1d61837d1
62 changed files with 613 additions and 519 deletions

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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:
#

View file

@ -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;

View file

@ -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 {

View file

@ -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);
}

View file

@ -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;
/// }

View file

@ -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()
}

View file

@ -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`]

View file

@ -128,6 +128,7 @@
#![feature(const_transmute)]
#![feature(reverse_bits)]
#![feature(non_exhaustive)]
#![feature(structural_match)]
#[prelude_import]
#[allow(unused)]

View file

@ -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>;

View file

@ -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) {

View file

@ -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]

View file

@ -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,
}
);

View file

@ -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

View file

@ -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)*) );*
}
}

View file

@ -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 () {}

View file

@ -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));
}

View file

@ -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`

View file

@ -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) {

View file

@ -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)

View file

@ -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.

View file

@ -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)) => {

View file

@ -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> {

View file

@ -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;

View file

@ -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!

View file

@ -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) {

View file

@ -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;

View 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];
}
}

View file

@ -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), ()> {

View file

@ -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

View file

@ -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()

View file

@ -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>,

View file

@ -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(

View file

@ -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) => {

View file

@ -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

View file

@ -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.

View file

@ -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) {

View file

@ -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
}
}

View file

@ -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(" "),
)?;
}
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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.
///

View file

@ -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) }

View file

@ -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.

View file

@ -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(),

View file

@ -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(

View file

@ -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()

View file

@ -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"
}
}

View file

@ -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) {

View file

@ -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"]' \

View 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 {}

View 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;

View 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;

View 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() {}

View file

@ -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'

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}