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
# 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:
/// 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
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
# 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:
#
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;
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;
use core::ptr::{self, NonNull, Unique};
use core::task::{LocalWaker, Poll};
+use vec::Vec;
use raw_vec::RawVec;
use str::from_boxed_utf8_unchecked;
#[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 {
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);
+}
/// ```
/// 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;
/// }
#[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()
}
#[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()
}
#[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()
}
///
/// 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`]
#![feature(const_transmute)]
#![feature(reverse_bits)]
#![feature(non_exhaustive)]
+#![feature(structural_match)]
#[prelude_import]
#[allow(unused)]
///
/// [drop check]: ../../nomicon/dropck.html
#[lang = "phantom_data"]
+#[structural_match]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct PhantomData<T:?Sized>;
#[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) {
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);
-
- 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::BorrowKind {
+ Shared,
+ Shallow,
+ Unique,
+ Mut { allow_two_phase_borrow },
+});
- }
- }
-}
+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]
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,
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,
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::*;
-
- 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<'tcx> for enum mir::interpret::ConstValue<'tcx> [ mir::interpret::ConstValue ] {
+ Unevaluated(def_id, substs),
+ Scalar(val),
+ ScalarPair(a, b),
+ ByRef(id, alloc, offset),
}
-}
+);
-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 struct mir::interpret::Pointer<Tag> {
+ alloc_id,
+ offset,
+ tag,
}
}
-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::*;
+impl_stable_hash_for!(
+ impl<Tag> for enum mir::interpret::Scalar<Tag> [ mir::interpret::Scalar ] {
+ Bits { bits, size },
+ Ptr(ptr),
+ }
+);
- 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,
}
}
-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,
TooGeneric
});
-impl_stable_hash_for!(struct ::mir::interpret::FrameInfo {
+impl_stable_hash_for!(struct mir::interpret::FrameInfo {
span,
lint_root,
location
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,
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<'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;
+impl_stable_hash_for!(enum ty::GenericParamDefKind {
+ Lifetime,
+ Type { has_default, object_lifetime_default, synthetic },
+});
- 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,
);
impl_stable_hash_for!(
- impl<'tcx> for struct infer::canonical::CanonicalVarValues<'tcx> {
+ struct infer::canonical::CanonicalVarValues<'tcx> {
var_values
}
);
}
impl_stable_hash_for!(
- impl<'tcx> for struct traits::ProgramClause<'tcx> {
+ struct traits::ProgramClause<'tcx> {
goal, hypotheses, category
}
);
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,
}
);
///
/// 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
})
}
-#[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));
#[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 {
$( { $($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 {
}
}
};
+ // 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 {
+ impl_stable_hash_for!(
+ impl<'tcx> for struct $struct_name { $($field $(-> $delegate)*),* }
+ );
+ };
+ (impl<$($lt:lifetime $(: $lt_bound:lifetime)* ),* $(,)* $($T:ident),* $(,)*> for 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>,
}
}
};
+ // 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<'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 tuple_struct $struct_name { $($field $(-> $delegate)*),* }
+ );
};
-
- (impl<$tcx:lifetime $(, $lt:lifetime $(: $lt_bound:lifetime)*)* $(, $T:ident)*> for struct $struct_name:path {
- $($field:ident $(-> $delegate:tt)*),* $(,)*
- }) => {
- impl<'a, $tcx, $($lt $(: $lt_bound)*,)* $($T,)*>
+ (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>>),*
{
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 {
+ let $struct_name (
$(ref $field),*
- } = *self;
+ ) = *self;
$( __impl_stable_hash_field!($field, __ctx, __hasher $(, $delegate)*) );*
}
) -> 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 () {}
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
}
_ => {}
}
}
- // print function definitons
+ // print function definitions
if let FnDef(did, _) = ty.sty {
return write!(f, "{}", item_path_str(did));
}
//
// 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.
// 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`
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) {
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)
/// 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.
}
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.
/// 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)) => {
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> {
}
// 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
// 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;
];
/// 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!
// 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) {
pub use rustc_serialize::hex::ToHex;
+pub mod macros;
pub mod svh;
pub mod base_n;
pub mod bit_set;
--- /dev/null
+// 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];
+ }
+}
}
}
-/// 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), ()> {
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
} = 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()
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,
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>,
// 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(
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) => {
/// 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
/// 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();
}
};
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.
// 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 {
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) {
fn check_if_allowed_tag(t: &Tag) -> bool {
match *t {
Tag::Paragraph
- | Tag::CodeBlock(_)
| Tag::Item
| Tag::Emphasis
| Tag::Strong
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
}
}
_ => "",
};
+ 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(" "),
+ )?;
}
}
}
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);
body:not(.source) .example-wrap {
display: inline-flex;
+ margin-bottom: 10px;
}
.example-wrap {
width: 100%;
}
+body:not(.source) .example-wrap > pre {
+ margin: 0;
+}
+
#search {
margin-left: 230px;
position: relative;
#[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]
#[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
/// 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.
///
///
/// ```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());
/// ```
///
/// ```no_run
/// use std::process::{Command, Stdio};
+ /// use std::io::{self, Write};
///
/// let output = Command::new("rev")
/// .stdin(Stdio::inherit())
/// .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) }
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};
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.
}
}
- /// 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(),
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(
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()
}
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"
}
}
// 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) {
// @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 {
// 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"]' \
--- /dev/null
+// 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 {}
--- /dev/null
+// 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;
--- /dev/null
+// 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;
--- /dev/null
+// 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() {}
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'
// 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
--- /dev/null
+// 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);
+}
}
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;
}