# 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:
#
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()
}
/// ```
#[inline]
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
- pub fn as_ptr(&self) -> *mut T {
+ pub const fn as_ptr(&self) -> *mut T {
self.value.get()
}
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn get(&self) -> *mut T {
+ pub const fn get(&self) -> *mut T {
&self.value as *const T as *mut T
}
}
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
- pub fn is_ascii(&self) -> bool {
+ pub const fn is_ascii(&self) -> bool {
*self as u32 <= 0x7F
}
/// assert_eq!(vec![1, 3], filtered);
/// ```
#[unstable(feature = "convert_id", issue = "53500")]
-#[rustc_const_unstable(feature = "const_convert_id")]
#[inline]
pub const fn identity<T>(x: T) -> T { x }
/// assert_eq!(None, nope.next());
/// ```
#[stable(feature = "iter_empty", since = "1.2.0")]
-pub fn empty<T>() -> Empty<T> {
+pub const fn empty<T>() -> Empty<T> {
Empty(marker::PhantomData)
}
#![feature(const_fn)]
#![feature(const_int_ops)]
#![feature(const_fn_union)]
-#![feature(const_manually_drop_new)]
#![feature(custom_attribute)]
#![feature(doc_cfg)]
#![feature(doc_spotlight)]
#![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]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
- ptr::read(src as *const T as *const U)
+ ptr::read_unaligned(src as *const T as *const U)
}
/// Opaque type representing the discriminant of an enum.
/// ManuallyDrop::new(Box::new(()));
/// ```
#[stable(feature = "manually_drop", since = "1.20.0")]
- #[rustc_const_unstable(feature = "const_manually_drop_new")]
#[inline]
pub const fn new(value: T) -> ManuallyDrop<T> {
ManuallyDrop { value }
/// ```
#[stable(feature = "manually_drop", since = "1.20.0")]
#[inline]
- pub fn into_inner(slot: ManuallyDrop<T>) -> T {
+ pub const fn into_inner(slot: ManuallyDrop<T>) -> T {
slot.value
}
// therefore this always underestimates (or is exact), but not much.
(((nbits + exp as i64) * 1292913986) >> 32) as i16
}
-
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn count_ones(self) -> u32 {
+ pub const fn count_ones(self) -> u32 {
self.0.count_ones()
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn count_zeros(self) -> u32 {
+ pub const fn count_zeros(self) -> u32 {
self.0.count_zeros()
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn trailing_zeros(self) -> u32 {
+ pub const fn trailing_zeros(self) -> u32 {
self.0.trailing_zeros()
}
}
/// ```
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn rotate_left(self, n: u32) -> Self {
+ pub const fn rotate_left(self, n: u32) -> Self {
Wrapping(self.0.rotate_left(n))
}
/// ```
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn rotate_right(self, n: u32) -> Self {
+ pub const fn rotate_right(self, n: u32) -> Self {
Wrapping(self.0.rotate_right(n))
}
/// ```
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn swap_bytes(self) -> Self {
+ pub const fn swap_bytes(self) -> Self {
Wrapping(self.0.swap_bytes())
}
/// ```
#[unstable(feature = "reverse_bits", issue = "48763")]
#[inline]
- pub fn reverse_bits(self) -> Self {
+ pub const fn reverse_bits(self) -> Self {
Wrapping(self.0.reverse_bits())
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn from_be(x: Self) -> Self {
+ pub const fn from_be(x: Self) -> Self {
Wrapping(<$t>::from_be(x.0))
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn from_le(x: Self) -> Self {
+ pub const fn from_le(x: Self) -> Self {
Wrapping(<$t>::from_le(x.0))
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn to_be(self) -> Self {
+ pub const fn to_be(self) -> Self {
Wrapping(self.0.to_be())
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn to_le(self) -> Self {
+ pub const fn to_le(self) -> Self {
Wrapping(self.0.to_le())
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn leading_zeros(self) -> u32 {
+ pub const fn leading_zeros(self) -> u32 {
self.0.leading_zeros()
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn is_positive(self) -> bool {
+ pub const fn is_positive(self) -> bool {
self.0.is_positive()
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn is_negative(self) -> bool {
+ pub const fn is_negative(self) -> bool {
self.0.is_negative()
}
}
```"),
#[inline]
#[unstable(feature = "wrapping_int_impl", issue = "32463")]
- pub fn leading_zeros(self) -> u32 {
+ pub const fn leading_zeros(self) -> u32 {
self.0.leading_zeros()
}
}
/// ```
#[stable(feature = "inclusive_range_methods", since = "1.27.0")]
#[inline]
- pub fn start(&self) -> &Idx {
+ pub const fn start(&self) -> &Idx {
&self.start
}
/// ```
#[stable(feature = "inclusive_range_methods", since = "1.27.0")]
#[inline]
- pub fn end(&self) -> &Idx {
+ pub const fn end(&self) -> &Idx {
&self.end
}
/// Acquires the underlying `*mut` pointer.
#[stable(feature = "nonnull", since = "1.25.0")]
#[inline]
- pub fn as_ptr(self) -> *mut T {
+ pub const fn as_ptr(self) -> *mut T {
self.pointer.0 as *mut T
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- #[rustc_const_unstable(feature = "const_slice_as_ptr")]
pub const fn as_ptr(&self) -> *const T {
self as *const [T] as *const T
}
#[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) {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
- #[rustc_const_unstable(feature = "const_str_as_ptr")]
pub const fn as_ptr(&self) -> *const u8 {
self as *const str as *const u8
}
///
/// [`subsec_nanos`]: #method.subsec_nanos
#[stable(feature = "duration", since = "1.3.0")]
- #[rustc_const_unstable(feature="duration_getters")]
#[inline]
pub const fn as_secs(&self) -> u64 { self.secs }
/// assert_eq!(duration.subsec_millis(), 432);
/// ```
#[stable(feature = "duration_extras", since = "1.27.0")]
- #[rustc_const_unstable(feature="duration_getters")]
#[inline]
pub const fn subsec_millis(&self) -> u32 { self.nanos / NANOS_PER_MILLI }
/// assert_eq!(duration.subsec_micros(), 234_567);
/// ```
#[stable(feature = "duration_extras", since = "1.27.0")]
- #[rustc_const_unstable(feature="duration_getters")]
#[inline]
pub const fn subsec_micros(&self) -> u32 { self.nanos / NANOS_PER_MICRO }
/// assert_eq!(duration.subsec_nanos(), 10_000_000);
/// ```
#[stable(feature = "duration", since = "1.3.0")]
- #[rustc_const_unstable(feature="duration_getters")]
#[inline]
pub const fn subsec_nanos(&self) -> u32 { self.nanos }
/// ```
#[unstable(feature = "duration_as_u128", issue = "50202")]
#[inline]
- pub fn as_millis(&self) -> u128 {
+ pub const fn as_millis(&self) -> u128 {
self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
}
/// ```
#[unstable(feature = "duration_as_u128", issue = "50202")]
#[inline]
- pub fn as_micros(&self) -> u128 {
+ pub const fn as_micros(&self) -> u128 {
self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
}
/// ```
#[unstable(feature = "duration_as_u128", issue = "50202")]
#[inline]
- pub fn as_nanos(&self) -> u128 {
+ pub const fn as_nanos(&self) -> u128 {
self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
}
/// ```
#[unstable(feature = "duration_float", issue = "54361")]
#[inline]
- pub fn as_float_secs(&self) -> f64 {
+ pub const fn as_float_secs(&self) -> f64 {
(self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
}
///
/// 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));
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`
pub fn items(
&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
- ) -> impl Iterator<Item = ty::AssociatedItem> + 'a {
+ ) -> ty::AssociatedItemsIterator<'a, 'gcx, 'tcx> {
tcx.associated_items(self.def_id())
}
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)
pub fn associated_items(
self,
def_id: DefId,
- ) -> impl Iterator<Item = AssociatedItem> + 'a {
- let def_ids = self.associated_item_def_ids(def_id);
- Box::new((0..def_ids.len()).map(move |i| self.associated_item(def_ids[i])))
- as Box<dyn Iterator<Item = AssociatedItem> + 'a>
+ ) -> AssociatedItemsIterator<'a, 'gcx, 'tcx> {
+ // Ideally, we would use `-> impl Iterator` here, but it falls
+ // afoul of the conservative "capture [restrictions]" we put
+ // in place, so we use a hand-written iterator.
+ //
+ // [restrictions]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
+ AssociatedItemsIterator {
+ tcx: self,
+ def_ids: self.associated_item_def_ids(def_id),
+ next_index: 0,
+ }
}
/// Returns `true` if the impls are the same polarity and the trait either
}
}
+pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> {
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ def_ids: Lrc<Vec<DefId>>,
+ next_index: usize,
+}
+
+impl Iterator for AssociatedItemsIterator<'_, '_, '_> {
+ type Item = AssociatedItem;
+
+ fn next(&mut self) -> Option<AssociatedItem> {
+ let def_id = self.def_ids.get(self.next_index)?;
+ self.next_index += 1;
+ Some(self.tcx.associated_item(*def_id))
+ }
+}
+
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn with_freevars<T, F>(self, fid: NodeId, f: F) -> T where
F: FnOnce(&[hir::Freevar]) -> T,
/// 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()
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) {
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;
/// [`CString`]: struct.CString.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn as_ptr(&self) -> *const c_char {
+ pub const fn as_ptr(&self) -> *const c_char {
self.inner.as_ptr()
}
/// 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.
///
/// assert_eq!(Ipv4Addr::new(45, 22, 13, 197).is_unspecified(), false);
/// ```
#[stable(feature = "ip_shared", since = "1.12.0")]
- pub fn is_unspecified(&self) -> bool {
+ pub const fn is_unspecified(&self) -> bool {
self.inner.s_addr == 0
}
/// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_unstable(feature = "const_ip")]
pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16,
g: u16, h: u16) -> Ipv6Addr {
Ipv6Addr {
/// [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
/// ```
#[stable(feature = "ipv6_to_octets", since = "1.12.0")]
- pub fn octets(&self) -> [u8; 16] {
+ pub const fn octets(&self) -> [u8; 16] {
self.inner.s6_addr
}
}
///
/// ```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(
// 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) {
--- /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;
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'
// compile-pass
-#![feature(duration_getters)]
-
use std::time::Duration;
fn main() {
static FOO: Foo = Foo(UnsafeCell::new(42));
+fn foo() {}
+
static BAR: () = unsafe {
*FOO.0.get() = 5;
- //~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants
-
+ //~^ ERROR statements in statics are unstable (see issue #48821)
// This error is caused by a separate bug that the feature gate error is reported
// even though the feature gate "const_let" is active.
- //~| statements in statics are unstable (see issue #48821)
+
+ foo();
+ //~^ ERROR calls in statics are limited to constant functions, tuple structs and tuple variants
};
fn main() {
-error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
- --> $DIR/mod-static-with-const-fn.rs:27:6
- |
-LL | *FOO.0.get() = 5;
- | ^^^^^^^^^^^
-
error[E0658]: statements in statics are unstable (see issue #48821)
- --> $DIR/mod-static-with-const-fn.rs:27:5
+ --> $DIR/mod-static-with-const-fn.rs:29:5
|
LL | *FOO.0.get() = 5;
| ^^^^^^^^^^^^^^^^
|
= help: add #![feature(const_let)] to the crate attributes to enable
+error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
+ --> $DIR/mod-static-with-const-fn.rs:34:5
+ |
+LL | foo();
+ | ^^^^^
+
error: aborting due to 2 previous errors
Some errors occurred: E0015, E0658.
--- /dev/null
+use std::cell::*;
+
+// not ok, because this would create a silent constant with interior mutability.
+// the rules could be relaxed in the future
+static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
+//~^ ERROR cannot borrow a constant which may contain interior mutability
+
+static FOO3: Wrap<Cell<u32>> = Wrap(Cell::new(42));
+// ok
+static FOO4: Wrap<*mut u32> = Wrap(FOO3.0.as_ptr());
+
+// not ok, because the `as_ptr` call takes a reference to a type with interior mutability
+// which is not allowed in constants
+const FOO2: *mut u32 = Cell::new(42).as_ptr();
+//~^ ERROR cannot borrow a constant which may contain interior mutability
+
+struct IMSafeTrustMe(UnsafeCell<u32>);
+unsafe impl Send for IMSafeTrustMe {}
+unsafe impl Sync for IMSafeTrustMe {}
+
+static BAR: IMSafeTrustMe = IMSafeTrustMe(UnsafeCell::new(5));
+
+
+struct Wrap<T>(T);
+unsafe impl<T> Send for Wrap<T> {}
+unsafe impl<T> Sync for Wrap<T> {}
+
+static BAR_PTR: Wrap<*mut u32> = Wrap(BAR.0.get());
+
+fn main() {}
--- /dev/null
+error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
+ --> $DIR/cell.rs:5:35
+ |
+LL | static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
+ | ^^^^^^^^^^^^^
+
+error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
+ --> $DIR/cell.rs:14:24
+ |
+LL | const FOO2: *mut u32 = Cell::new(42).as_ptr();
+ | ^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0492`.
--- /dev/null
+// run-pass
+
+static X: bool = 'a'.is_ascii();
+static Y: bool = 'รค'.is_ascii();
+
+fn main() {
+ assert!(X);
+ assert!(!Y);
+}
--- /dev/null
+// run-pass
+
+const I: std::iter::Empty<u32> = std::iter::empty();
+
+fn main() {
+ for i in I {
+ panic!("magical value creation: {}", i);
+ }
+}
--- /dev/null
+// compile-pass
+
+struct Wrap<T>(T);
+unsafe impl<T> Send for Wrap<T> {}
+unsafe impl<T> Sync for Wrap<T> {}
+
+static FOO: Wrap<*const u32> = Wrap([42, 44, 46].as_ptr());
+static BAR: Wrap<*const u8> = Wrap("hello".as_ptr());
+
+fn main() {}
// 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
-// 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.
-
-// This test should fail since identity is not stable as a const fn yet.
-
-#![feature(convert_id)]
-
-fn main() {
- const _FOO: u8 = ::std::convert::identity(42u8);
-}
+++ /dev/null
-error: `std::convert::identity` is not yet stable as a const fn
- --> $DIR/convert-id-const-no-gate.rs:16:22
- |
-LL | const _FOO: u8 = ::std::convert::identity(42u8);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = help: in Nightly builds, add `#![feature(const_convert_id)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// This test should pass since we've opted into 'identity' as an
-// unstable const fn.
+// This test should pass since 'identity' is const fn.
// compile-pass
-#![feature(convert_id, const_convert_id)]
+#![feature(convert_id)]
fn main() {
const _FOO: u8 = ::std::convert::identity(42u8);
--- /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;
}