Auto merge of #56186 - kennytm:rollup, r=kennytm
Rollup of 14 pull requests Successful merges: - #55767 (Disable some pretty-printers when gdb is rust-enabled) - #55838 (Fix #[cfg] for step impl on ranges) - #55869 (Add std::iter::unfold) - #55945 (Ensure that the argument to `static_assert` is a `bool`) - #56022 (When popping in CTFE, perform validation before jumping to next statement to have a better span for the error) - #56048 (Add rustc_codegen_ssa to sysroot) - #56091 (Fix json output in the self-profiler) - #56097 (Fix invalid bitcast taking bool out of a union represented as a scalar) - #56116 (ci: Download clang/lldb from tarballs) - #56120 (Add unstable Literal::subspan().) - #56154 (Pass additional linker flags when targeting Fuchsia) - #56162 (std::str Adapt documentation to reality) - #56163 ([master] Backport 1.30.1 release notes) - #56168 (Fix the tracking issue for hash_raw_entry) Failed merges: r? @ghost
This commit is contained in:
commit
1f57e48411
27 changed files with 606 additions and 96 deletions
19
Cargo.lock
19
Cargo.lock
|
|
@ -2073,6 +2073,7 @@ dependencies = [
|
||||||
name = "rustc-main"
|
name = "rustc-main"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"rustc_codegen_ssa 0.0.0",
|
||||||
"rustc_driver 0.0.0",
|
"rustc_driver 0.0.0",
|
||||||
"rustc_target 0.0.0",
|
"rustc_target 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
@ -2169,7 +2170,6 @@ dependencies = [
|
||||||
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc_codegen_ssa 0.0.0",
|
|
||||||
"rustc_llvm 0.0.0",
|
"rustc_llvm 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2177,10 +2177,27 @@ dependencies = [
|
||||||
name = "rustc_codegen_ssa"
|
name = "rustc_codegen_ssa"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc 0.0.0",
|
||||||
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc_allocator 0.0.0",
|
||||||
|
"rustc_apfloat 0.0.0",
|
||||||
|
"rustc_codegen_utils 0.0.0",
|
||||||
|
"rustc_data_structures 0.0.0",
|
||||||
|
"rustc_errors 0.0.0",
|
||||||
|
"rustc_fs_util 0.0.0",
|
||||||
|
"rustc_incremental 0.0.0",
|
||||||
|
"rustc_mir 0.0.0",
|
||||||
|
"rustc_target 0.0.0",
|
||||||
|
"serialize 0.0.0",
|
||||||
|
"syntax 0.0.0",
|
||||||
|
"syntax_pos 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,14 @@ Cargo
|
||||||
[cargo-rename-reference]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml
|
[cargo-rename-reference]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml
|
||||||
[const-reference]: https://doc.rust-lang.org/reference/items/functions.html#const-functions
|
[const-reference]: https://doc.rust-lang.org/reference/items/functions.html#const-functions
|
||||||
|
|
||||||
|
Version 1.30.1 (2018-11-08)
|
||||||
|
===========================
|
||||||
|
|
||||||
|
- [Fixed overflow ICE in rustdoc][54199]
|
||||||
|
- [Cap Cargo progress bar width at 60 in MSYS terminals][cargo/6122]
|
||||||
|
|
||||||
|
[54199]: https://github.com/rust-lang/rust/pull/54199
|
||||||
|
[cargo/6122]: https://github.com/rust-lang/cargo/pull/6122
|
||||||
|
|
||||||
Version 1.30.0 (2018-10-25)
|
Version 1.30.0 (2018-10-25)
|
||||||
==========================
|
==========================
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ function fetch_submodule {
|
||||||
}
|
}
|
||||||
|
|
||||||
included="src/llvm src/llvm-emscripten src/doc/book src/doc/rust-by-example"
|
included="src/llvm src/llvm-emscripten src/doc/book src/doc/rust-by-example"
|
||||||
|
included="$included src/tools/lld src/tools/clang src/tools/lldb"
|
||||||
modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
|
modules="$(git config --file .gitmodules --get-regexp '\.path$' | cut -d' ' -f2)"
|
||||||
modules=($modules)
|
modules=($modules)
|
||||||
use_git=""
|
use_git=""
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import debugger_pretty_printers_common as rustpp
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
xrange = range
|
xrange = range
|
||||||
|
|
||||||
|
rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string = True)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# GDB Pretty Printing Module for Rust
|
# GDB Pretty Printing Module for Rust
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
|
|
@ -99,27 +101,9 @@ def rust_pretty_printer_lookup_function(gdb_val):
|
||||||
val = GdbValue(gdb_val)
|
val = GdbValue(gdb_val)
|
||||||
type_kind = val.type.get_type_kind()
|
type_kind = val.type.get_type_kind()
|
||||||
|
|
||||||
if type_kind == rustpp.TYPE_KIND_EMPTY:
|
|
||||||
return RustEmptyPrinter(val)
|
|
||||||
|
|
||||||
if type_kind == rustpp.TYPE_KIND_REGULAR_STRUCT:
|
|
||||||
return RustStructPrinter(val,
|
|
||||||
omit_first_field = False,
|
|
||||||
omit_type_name = False,
|
|
||||||
is_tuple_like = False)
|
|
||||||
|
|
||||||
if type_kind == rustpp.TYPE_KIND_STRUCT_VARIANT:
|
|
||||||
return RustStructPrinter(val,
|
|
||||||
omit_first_field = True,
|
|
||||||
omit_type_name = False,
|
|
||||||
is_tuple_like = False)
|
|
||||||
|
|
||||||
if type_kind == rustpp.TYPE_KIND_SLICE:
|
if type_kind == rustpp.TYPE_KIND_SLICE:
|
||||||
return RustSlicePrinter(val)
|
return RustSlicePrinter(val)
|
||||||
|
|
||||||
if type_kind == rustpp.TYPE_KIND_STR_SLICE:
|
|
||||||
return RustStringSlicePrinter(val)
|
|
||||||
|
|
||||||
if type_kind == rustpp.TYPE_KIND_STD_VEC:
|
if type_kind == rustpp.TYPE_KIND_STD_VEC:
|
||||||
return RustStdVecPrinter(val)
|
return RustStdVecPrinter(val)
|
||||||
|
|
||||||
|
|
@ -138,6 +122,29 @@ def rust_pretty_printer_lookup_function(gdb_val):
|
||||||
if type_kind == rustpp.TYPE_KIND_OS_STRING:
|
if type_kind == rustpp.TYPE_KIND_OS_STRING:
|
||||||
return RustOsStringPrinter(val)
|
return RustOsStringPrinter(val)
|
||||||
|
|
||||||
|
# Checks after this point should only be for "compiler" types --
|
||||||
|
# things that gdb's Rust language support knows about.
|
||||||
|
if rust_enabled:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if type_kind == rustpp.TYPE_KIND_EMPTY:
|
||||||
|
return RustEmptyPrinter(val)
|
||||||
|
|
||||||
|
if type_kind == rustpp.TYPE_KIND_REGULAR_STRUCT:
|
||||||
|
return RustStructPrinter(val,
|
||||||
|
omit_first_field = False,
|
||||||
|
omit_type_name = False,
|
||||||
|
is_tuple_like = False)
|
||||||
|
|
||||||
|
if type_kind == rustpp.TYPE_KIND_STRUCT_VARIANT:
|
||||||
|
return RustStructPrinter(val,
|
||||||
|
omit_first_field = True,
|
||||||
|
omit_type_name = False,
|
||||||
|
is_tuple_like = False)
|
||||||
|
|
||||||
|
if type_kind == rustpp.TYPE_KIND_STR_SLICE:
|
||||||
|
return RustStringSlicePrinter(val)
|
||||||
|
|
||||||
if type_kind == rustpp.TYPE_KIND_TUPLE:
|
if type_kind == rustpp.TYPE_KIND_TUPLE:
|
||||||
return RustStructPrinter(val,
|
return RustStructPrinter(val,
|
||||||
omit_first_field = False,
|
omit_first_field = False,
|
||||||
|
|
|
||||||
|
|
@ -112,10 +112,10 @@
|
||||||
//!
|
//!
|
||||||
//! // next() is the only required method
|
//! // next() is the only required method
|
||||||
//! fn next(&mut self) -> Option<usize> {
|
//! fn next(&mut self) -> Option<usize> {
|
||||||
//! // increment our count. This is why we started at zero.
|
//! // Increment our count. This is why we started at zero.
|
||||||
//! self.count += 1;
|
//! self.count += 1;
|
||||||
//!
|
//!
|
||||||
//! // check to see if we've finished counting or not.
|
//! // Check to see if we've finished counting or not.
|
||||||
//! if self.count < 6 {
|
//! if self.count < 6 {
|
||||||
//! Some(self.count)
|
//! Some(self.count)
|
||||||
//! } else {
|
//! } else {
|
||||||
|
|
@ -339,6 +339,8 @@ pub use self::sources::{RepeatWith, repeat_with};
|
||||||
pub use self::sources::{Empty, empty};
|
pub use self::sources::{Empty, empty};
|
||||||
#[stable(feature = "iter_once", since = "1.2.0")]
|
#[stable(feature = "iter_once", since = "1.2.0")]
|
||||||
pub use self::sources::{Once, once};
|
pub use self::sources::{Once, once};
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
pub use self::sources::{Unfold, unfold, Successors, successors};
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};
|
pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};
|
||||||
|
|
|
||||||
|
|
@ -166,14 +166,14 @@ macro_rules! step_impl_no_between {
|
||||||
}
|
}
|
||||||
|
|
||||||
step_impl_unsigned!(usize u8 u16);
|
step_impl_unsigned!(usize u8 u16);
|
||||||
#[cfg(not(target_pointer_witdth = "16"))]
|
#[cfg(not(target_pointer_width = "16"))]
|
||||||
step_impl_unsigned!(u32);
|
step_impl_unsigned!(u32);
|
||||||
#[cfg(target_pointer_witdth = "16")]
|
#[cfg(target_pointer_width = "16")]
|
||||||
step_impl_no_between!(u32);
|
step_impl_no_between!(u32);
|
||||||
step_impl_signed!([isize: usize] [i8: u8] [i16: u16]);
|
step_impl_signed!([isize: usize] [i8: u8] [i16: u16]);
|
||||||
#[cfg(not(target_pointer_witdth = "16"))]
|
#[cfg(not(target_pointer_width = "16"))]
|
||||||
step_impl_signed!([i32: u32]);
|
step_impl_signed!([i32: u32]);
|
||||||
#[cfg(target_pointer_witdth = "16")]
|
#[cfg(target_pointer_width = "16")]
|
||||||
step_impl_no_between!(i32);
|
step_impl_no_between!(i32);
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
step_impl_unsigned!(u64);
|
step_impl_unsigned!(u64);
|
||||||
|
|
|
||||||
|
|
@ -386,3 +386,164 @@ impl<T> FusedIterator for Once<T> {}
|
||||||
pub fn once<T>(value: T) -> Once<T> {
|
pub fn once<T>(value: T) -> Once<T> {
|
||||||
Once { inner: Some(value).into_iter() }
|
Once { inner: Some(value).into_iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new iterator where each iteration calls the provided closure
|
||||||
|
/// `F: FnMut(&mut St) -> Option<T>`.
|
||||||
|
///
|
||||||
|
/// This allows creating a custom iterator with any behavior
|
||||||
|
/// without using the more verbose syntax of creating a dedicated type
|
||||||
|
/// and implementing the `Iterator` trait for it.
|
||||||
|
///
|
||||||
|
/// In addition to its captures and environment,
|
||||||
|
/// the closure is given a mutable reference to some state
|
||||||
|
/// that is preserved across iterations.
|
||||||
|
/// That state starts as the given `initial_state` value.
|
||||||
|
///
|
||||||
|
/// Note that the `Unfold` iterator doesn’t make assumptions about the behavior of the closure,
|
||||||
|
/// and therefore conservatively does not implement [`FusedIterator`],
|
||||||
|
/// or override [`Iterator::size_hint`] from its default `(0, None)`.
|
||||||
|
///
|
||||||
|
/// [`FusedIterator`]: trait.FusedIterator.html
|
||||||
|
/// [`Iterator::size_hint`]: trait.Iterator.html#method.size_hint
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Let’s re-implement the counter iterator from [module-level documentation]:
|
||||||
|
///
|
||||||
|
/// [module-level documentation]: index.html
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(iter_unfold)]
|
||||||
|
/// let counter = std::iter::unfold(0, |count| {
|
||||||
|
/// // Increment our count. This is why we started at zero.
|
||||||
|
/// *count += 1;
|
||||||
|
///
|
||||||
|
/// // Check to see if we've finished counting or not.
|
||||||
|
/// if *count < 6 {
|
||||||
|
/// Some(*count)
|
||||||
|
/// } else {
|
||||||
|
/// None
|
||||||
|
/// }
|
||||||
|
/// });
|
||||||
|
/// assert_eq!(counter.collect::<Vec<_>>(), &[1, 2, 3, 4, 5]);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
pub fn unfold<St, T, F>(initial_state: St, f: F) -> Unfold<St, F>
|
||||||
|
where F: FnMut(&mut St) -> Option<T>
|
||||||
|
{
|
||||||
|
Unfold {
|
||||||
|
state: initial_state,
|
||||||
|
f,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An iterator where each iteration calls the provided closure `F: FnMut(&mut St) -> Option<T>`.
|
||||||
|
///
|
||||||
|
/// This `struct` is created by the [`unfold`] function.
|
||||||
|
/// See its documentation for more.
|
||||||
|
///
|
||||||
|
/// [`unfold`]: fn.unfold.html
|
||||||
|
#[derive(Clone)]
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
pub struct Unfold<St, F> {
|
||||||
|
state: St,
|
||||||
|
f: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
impl<St, T, F> Iterator for Unfold<St, F>
|
||||||
|
where F: FnMut(&mut St) -> Option<T>
|
||||||
|
{
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
(self.f)(&mut self.state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
impl<St: fmt::Debug, F> fmt::Debug for Unfold<St, F> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("Unfold")
|
||||||
|
.field("state", &self.state)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new iterator where each successive item is computed based on the preceding one.
|
||||||
|
///
|
||||||
|
/// The iterator starts with the given first item (if any)
|
||||||
|
/// and calls the given `FnMut(&T) -> Option<T>` closure to compute each item’s successor.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// #![feature(iter_unfold)]
|
||||||
|
/// use std::iter::successors;
|
||||||
|
///
|
||||||
|
/// let powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
|
||||||
|
/// assert_eq!(powers_of_10.collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
|
||||||
|
/// ```
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
pub fn successors<T, F>(first: Option<T>, succ: F) -> Successors<T, F>
|
||||||
|
where F: FnMut(&T) -> Option<T>
|
||||||
|
{
|
||||||
|
// If this function returned `impl Iterator<Item=T>`
|
||||||
|
// it could be based on `unfold` and not need a dedicated type.
|
||||||
|
// However having a named `Successors<T, F>` type allows it to be `Clone` when `T` and `F` are.
|
||||||
|
Successors {
|
||||||
|
next: first,
|
||||||
|
succ,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An new iterator where each successive item is computed based on the preceding one.
|
||||||
|
///
|
||||||
|
/// This `struct` is created by the [`successors`] function.
|
||||||
|
/// See its documentation for more.
|
||||||
|
///
|
||||||
|
/// [`successors`]: fn.successors.html
|
||||||
|
#[derive(Clone)]
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
pub struct Successors<T, F> {
|
||||||
|
next: Option<T>,
|
||||||
|
succ: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
impl<T, F> Iterator for Successors<T, F>
|
||||||
|
where F: FnMut(&T) -> Option<T>
|
||||||
|
{
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.next.take().map(|item| {
|
||||||
|
self.next = (self.succ)(&item);
|
||||||
|
item
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
if self.next.is_some() {
|
||||||
|
(1, None)
|
||||||
|
} else {
|
||||||
|
(0, Some(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
impl<T, F> FusedIterator for Successors<T, F>
|
||||||
|
where F: FnMut(&T) -> Option<T>
|
||||||
|
{}
|
||||||
|
|
||||||
|
#[unstable(feature = "iter_unfold", issue = "55977")]
|
||||||
|
impl<T: fmt::Debug, F> fmt::Debug for Successors<T, F> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("Successors")
|
||||||
|
.field("next", &self.next)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1424,10 +1424,8 @@ fn contains_nonascii(x: usize) -> bool {
|
||||||
(x & NONASCII_MASK) != 0
|
(x & NONASCII_MASK) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Walks through `iter` checking that it's a valid UTF-8 sequence,
|
/// Walks through `v` checking that it's a valid UTF-8 sequence,
|
||||||
/// returning `true` in that case, or, if it is invalid, `false` with
|
/// returning `Ok(())` in that case, or, if it is invalid, `Err(err)`.
|
||||||
/// `iter` reset such that it is pointing at the first byte in the
|
|
||||||
/// invalid sequence.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
|
fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
|
||||||
|
|
@ -1759,6 +1759,17 @@ fn test_repeat_with_take_collect() {
|
||||||
assert_eq!(v, vec![1, 2, 4, 8, 16]);
|
assert_eq!(v, vec![1, 2, 4, 8, 16]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_successors() {
|
||||||
|
let mut powers_of_10 = successors(Some(1_u16), |n| n.checked_mul(10));
|
||||||
|
assert_eq!(powers_of_10.by_ref().collect::<Vec<_>>(), &[1, 10, 100, 1_000, 10_000]);
|
||||||
|
assert_eq!(powers_of_10.next(), None);
|
||||||
|
|
||||||
|
let mut empty = successors(None::<u32>, |_| unimplemented!());
|
||||||
|
assert_eq!(empty.next(), None);
|
||||||
|
assert_eq!(empty.next(), None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fuse() {
|
fn test_fuse() {
|
||||||
let mut it = 0..3;
|
let mut it = 0..3;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#![feature(flt2dec)]
|
#![feature(flt2dec)]
|
||||||
#![feature(fmt_internals)]
|
#![feature(fmt_internals)]
|
||||||
#![feature(hashmap_internals)]
|
#![feature(hashmap_internals)]
|
||||||
|
#![feature(iter_unfold)]
|
||||||
#![feature(pattern)]
|
#![feature(pattern)]
|
||||||
#![feature(range_is_empty)]
|
#![feature(range_is_empty)]
|
||||||
#![feature(raw)]
|
#![feature(raw)]
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ mod diagnostic;
|
||||||
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
|
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
|
||||||
pub use diagnostic::{Diagnostic, Level, MultiSpan};
|
pub use diagnostic::{Diagnostic, Level, MultiSpan};
|
||||||
|
|
||||||
|
use std::ops::{Bound, RangeBounds};
|
||||||
use std::{ascii, fmt, iter};
|
use std::{ascii, fmt, iter};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
|
@ -59,7 +60,7 @@ use syntax::errors::DiagnosticBuilder;
|
||||||
use syntax::parse::{self, token};
|
use syntax::parse::{self, token};
|
||||||
use syntax::symbol::Symbol;
|
use syntax::symbol::Symbol;
|
||||||
use syntax::tokenstream::{self, DelimSpan};
|
use syntax::tokenstream::{self, DelimSpan};
|
||||||
use syntax_pos::{Pos, FileName};
|
use syntax_pos::{Pos, FileName, BytePos};
|
||||||
|
|
||||||
/// The main type provided by this crate, representing an abstract stream of
|
/// The main type provided by this crate, representing an abstract stream of
|
||||||
/// tokens, or, more specifically, a sequence of token trees.
|
/// tokens, or, more specifically, a sequence of token trees.
|
||||||
|
|
@ -1168,6 +1169,50 @@ impl Literal {
|
||||||
pub fn set_span(&mut self, span: Span) {
|
pub fn set_span(&mut self, span: Span) {
|
||||||
self.span = span;
|
self.span = span;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a `Span` that is a subset of `self.span()` containing only the
|
||||||
|
/// source bytes in range `range`. Returns `None` if the would-be trimmed
|
||||||
|
/// span is outside the bounds of `self`.
|
||||||
|
// FIXME(SergioBenitez): check that the byte range starts and ends at a
|
||||||
|
// UTF-8 boundary of the source. otherwise, it's likely that a panic will
|
||||||
|
// occur elsewhere when the source text is printed.
|
||||||
|
// FIXME(SergioBenitez): there is no way for the user to know what
|
||||||
|
// `self.span()` actually maps to, so this method can currently only be
|
||||||
|
// called blindly. For example, `to_string()` for the character 'c' returns
|
||||||
|
// "'\u{63}'"; there is no way for the user to know whether the source text
|
||||||
|
// was 'c' or whether it was '\u{63}'.
|
||||||
|
#[unstable(feature = "proc_macro_span", issue = "54725")]
|
||||||
|
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
|
||||||
|
let inner = self.span().0;
|
||||||
|
let length = inner.hi().to_usize() - inner.lo().to_usize();
|
||||||
|
|
||||||
|
let start = match range.start_bound() {
|
||||||
|
Bound::Included(&lo) => lo,
|
||||||
|
Bound::Excluded(&lo) => lo + 1,
|
||||||
|
Bound::Unbounded => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let end = match range.end_bound() {
|
||||||
|
Bound::Included(&hi) => hi + 1,
|
||||||
|
Bound::Excluded(&hi) => hi,
|
||||||
|
Bound::Unbounded => length,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Bounds check the values, preventing addition overflow and OOB spans.
|
||||||
|
if start > u32::max_value() as usize
|
||||||
|
|| end > u32::max_value() as usize
|
||||||
|
|| (u32::max_value() - start as u32) < inner.lo().to_u32()
|
||||||
|
|| (u32::max_value() - end as u32) < inner.lo().to_u32()
|
||||||
|
|| start >= end
|
||||||
|
|| end > length
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_lo = inner.lo() + BytePos::from_usize(start);
|
||||||
|
let new_hi = inner.lo() + BytePos::from_usize(end);
|
||||||
|
Some(Span(inner.with_lo(new_lo).with_hi(new_hi)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints the literal as a string that should be losslessly convertible
|
/// Prints the literal as a string that should be losslessly convertible
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,27 @@ macro_rules! define_categories {
|
||||||
$(
|
$(
|
||||||
let (hits, total) = self.query_counts.$name;
|
let (hits, total) = self.query_counts.$name;
|
||||||
|
|
||||||
|
//normalize hits to 0%
|
||||||
|
let hit_percent =
|
||||||
|
if total > 0 {
|
||||||
|
((hits as f32) / (total as f32)) * 100.0
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
|
||||||
json.push_str(&format!(
|
json.push_str(&format!(
|
||||||
"{{ \"category\": {}, \"time_ms\": {},
|
"{{ \"category\": {}, \"time_ms\": {},
|
||||||
\"query_count\": {}, \"query_hits\": {} }}",
|
\"query_count\": {}, \"query_hits\": {} }},",
|
||||||
stringify!($name),
|
stringify!($name),
|
||||||
self.times.$name / 1_000_000,
|
self.times.$name / 1_000_000,
|
||||||
total,
|
total,
|
||||||
format!("{:.2}", (((hits as f32) / (total as f32)) * 100.0))
|
format!("{:.2}", hit_percent)
|
||||||
));
|
));
|
||||||
)*
|
)*
|
||||||
|
|
||||||
|
//remove the trailing ',' character
|
||||||
|
json.pop();
|
||||||
|
|
||||||
json.push(']');
|
json.push(']');
|
||||||
|
|
||||||
json
|
json
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ test = false
|
||||||
cc = "1.0.1"
|
cc = "1.0.1"
|
||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
rustc-demangle = "0.1.4"
|
rustc-demangle = "0.1.4"
|
||||||
rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
|
|
||||||
rustc_llvm = { path = "../librustc_llvm" }
|
rustc_llvm = { path = "../librustc_llvm" }
|
||||||
memmap = "0.6"
|
memmap = "0.6"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ use super::rpath::RPathConfig;
|
||||||
use super::rpath;
|
use super::rpath;
|
||||||
use metadata::METADATA_FILENAME;
|
use metadata::METADATA_FILENAME;
|
||||||
use rustc::session::config::{self, DebugInfo, OutputFilenames, OutputType, PrintRequest};
|
use rustc::session::config::{self, DebugInfo, OutputFilenames, OutputType, PrintRequest};
|
||||||
use rustc::session::config::{RUST_CGU_EXT, Lto};
|
use rustc::session::config::{RUST_CGU_EXT, Lto, Sanitizer};
|
||||||
use rustc::session::filesearch;
|
use rustc::session::filesearch;
|
||||||
use rustc::session::search_paths::PathKind;
|
use rustc::session::search_paths::PathKind;
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
|
|
@ -491,6 +491,14 @@ fn link_natively(sess: &Session,
|
||||||
}
|
}
|
||||||
cmd.args(&sess.opts.debugging_opts.pre_link_arg);
|
cmd.args(&sess.opts.debugging_opts.pre_link_arg);
|
||||||
|
|
||||||
|
if sess.target.target.options.is_like_fuchsia {
|
||||||
|
let prefix = match sess.opts.debugging_opts.sanitizer {
|
||||||
|
Some(Sanitizer::Address) => "asan/",
|
||||||
|
_ => "",
|
||||||
|
};
|
||||||
|
cmd.arg(format!("--dynamic-linker={}ld.so.1", prefix));
|
||||||
|
}
|
||||||
|
|
||||||
let pre_link_objects = if crate_type == config::CrateType::Executable {
|
let pre_link_objects = if crate_type == config::CrateType::Executable {
|
||||||
&sess.target.target.options.pre_link_objects_exe
|
&sess.target.target.options.pre_link_objects_exe
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,29 @@ version = "0.0.0"
|
||||||
[lib]
|
[lib]
|
||||||
name = "rustc_codegen_ssa"
|
name = "rustc_codegen_ssa"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
crate-type = ["dylib"]
|
||||||
test = false
|
test = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bitflags = "1.0.4"
|
||||||
cc = "1.0.1"
|
cc = "1.0.1"
|
||||||
num_cpus = "1.0"
|
num_cpus = "1.0"
|
||||||
rustc-demangle = "0.1.4"
|
rustc-demangle = "0.1.4"
|
||||||
memmap = "0.6"
|
memmap = "0.6"
|
||||||
|
log = "0.4.5"
|
||||||
|
libc = "0.2.43"
|
||||||
|
jobserver = "0.1.11"
|
||||||
|
|
||||||
|
serialize = { path = "../libserialize" }
|
||||||
|
syntax = { path = "../libsyntax" }
|
||||||
|
syntax_pos = { path = "../libsyntax_pos" }
|
||||||
|
rustc = { path = "../librustc" }
|
||||||
|
rustc_allocator = { path = "../librustc_allocator" }
|
||||||
|
rustc_apfloat = { path = "../librustc_apfloat" }
|
||||||
|
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
|
||||||
|
rustc_data_structures = { path = "../librustc_data_structures"}
|
||||||
|
rustc_errors = { path = "../librustc_errors" }
|
||||||
|
rustc_fs_util = { path = "../librustc_fs_util" }
|
||||||
|
rustc_incremental = { path = "../librustc_incremental" }
|
||||||
|
rustc_mir = { path = "../librustc_mir" }
|
||||||
|
rustc_target = { path = "../librustc_target" }
|
||||||
|
|
|
||||||
|
|
@ -244,13 +244,24 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
|
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
|
||||||
|
// Bools in union fields needs to be truncated.
|
||||||
|
let to_immediate_or_cast = |bx: &mut Bx, val, ty| {
|
||||||
|
if ty == bx.cx().type_i1() {
|
||||||
|
bx.trunc(val, ty)
|
||||||
|
} else {
|
||||||
|
bx.bitcast(val, ty)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
match val {
|
match val {
|
||||||
OperandValue::Immediate(ref mut llval) => {
|
OperandValue::Immediate(ref mut llval) => {
|
||||||
*llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field));
|
*llval = to_immediate_or_cast(bx, *llval, bx.cx().immediate_backend_type(field));
|
||||||
}
|
}
|
||||||
OperandValue::Pair(ref mut a, ref mut b) => {
|
OperandValue::Pair(ref mut a, ref mut b) => {
|
||||||
*a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true));
|
*a = to_immediate_or_cast(bx, *a, bx.cx()
|
||||||
*b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true));
|
.scalar_pair_element_backend_type(field, 0, true));
|
||||||
|
*b = to_immediate_or_cast(bx, *b, bx.cx()
|
||||||
|
.scalar_pair_element_backend_type(field, 1, true));
|
||||||
}
|
}
|
||||||
OperandValue::Ref(..) => bug!()
|
OperandValue::Ref(..) => bug!()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,12 @@
|
||||||
/// A simple static assertion macro. The first argument should be a unique
|
/// A simple static assertion macro. The first argument should be a unique
|
||||||
/// ALL_CAPS identifier that describes the condition.
|
/// ALL_CAPS identifier that describes the condition.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
#[allow_internal_unstable]
|
||||||
macro_rules! static_assert {
|
macro_rules! static_assert {
|
||||||
($name:ident: $test:expr) => {
|
($name:ident: $test:expr) => {
|
||||||
// Use the bool to access an array such that if the bool is false, the access
|
// Use the bool to access an array such that if the bool is false, the access
|
||||||
// is out-of-bounds.
|
// is out-of-bounds.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
static $name: () = [()][!$test as usize];
|
static $name: () = [()][!($test: bool) as usize];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -504,15 +504,14 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||||
let frame = self.stack.pop().expect(
|
let frame = self.stack.pop().expect(
|
||||||
"tried to pop a stack frame, but there were none",
|
"tried to pop a stack frame, but there were none",
|
||||||
);
|
);
|
||||||
|
// Abort early if we do not want to clean up: We also avoid validation in that case,
|
||||||
|
// because this is CTFE and the final value will be thoroughly validated anyway.
|
||||||
match frame.return_to_block {
|
match frame.return_to_block {
|
||||||
StackPopCleanup::Goto(block) => {
|
StackPopCleanup::Goto(_) => {},
|
||||||
self.goto_block(block)?;
|
|
||||||
}
|
|
||||||
StackPopCleanup::None { cleanup } => {
|
StackPopCleanup::None { cleanup } => {
|
||||||
if !cleanup {
|
if !cleanup {
|
||||||
// Leak the locals. Also skip validation, this is only used by
|
assert!(self.stack.is_empty(), "only the topmost frame should ever be leaked");
|
||||||
// static/const computation which does its own (stronger) final
|
// Leak the locals, skip validation.
|
||||||
// validation.
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +520,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||||
for local in frame.locals {
|
for local in frame.locals {
|
||||||
self.deallocate_local(local)?;
|
self.deallocate_local(local)?;
|
||||||
}
|
}
|
||||||
// Validate the return value.
|
// Validate the return value. Do this after deallocating so that we catch dangling
|
||||||
|
// references.
|
||||||
if let Some(return_place) = frame.return_place {
|
if let Some(return_place) = frame.return_place {
|
||||||
if M::enforce_validity(self) {
|
if M::enforce_validity(self) {
|
||||||
// Data got changed, better make sure it matches the type!
|
// Data got changed, better make sure it matches the type!
|
||||||
|
|
@ -542,6 +542,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||||
// Uh, that shouldn't happen... the function did not intend to return
|
// Uh, that shouldn't happen... the function did not intend to return
|
||||||
return err!(Unreachable);
|
return err!(Unreachable);
|
||||||
}
|
}
|
||||||
|
// Jump to new block -- *after* validation so that the spans make more sense.
|
||||||
|
match frame.return_to_block {
|
||||||
|
StackPopCleanup::Goto(block) => {
|
||||||
|
self.goto_block(block)?;
|
||||||
|
}
|
||||||
|
StackPopCleanup::None { .. } => {}
|
||||||
|
}
|
||||||
|
|
||||||
if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
|
if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
|
||||||
debug!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
|
debug!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,11 @@ use spec::{LldFlavor, LinkArgs, LinkerFlavor, TargetOptions};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
|
||||||
pub fn opts() -> TargetOptions {
|
pub fn opts() -> TargetOptions {
|
||||||
let mut args = LinkArgs::new();
|
let mut pre_link_args = LinkArgs::new();
|
||||||
args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec![
|
pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec![
|
||||||
"--build-id".to_string(), "--hash-style=gnu".to_string(),
|
"--build-id".to_string(),
|
||||||
|
"--eh-frame-hdr".to_string(),
|
||||||
|
"--hash-style=gnu".to_string(),
|
||||||
"-z".to_string(), "rodynamic".to_string(),
|
"-z".to_string(), "rodynamic".to_string(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -24,9 +26,13 @@ pub fn opts() -> TargetOptions {
|
||||||
dynamic_linking: true,
|
dynamic_linking: true,
|
||||||
executables: true,
|
executables: true,
|
||||||
target_family: Some("unix".to_string()),
|
target_family: Some("unix".to_string()),
|
||||||
|
is_like_fuchsia: true,
|
||||||
linker_is_gnu: true,
|
linker_is_gnu: true,
|
||||||
has_rpath: false,
|
has_rpath: false,
|
||||||
pre_link_args: args,
|
pre_link_args: pre_link_args,
|
||||||
|
pre_link_objects_exe: vec![
|
||||||
|
"Scrt1.o".to_string()
|
||||||
|
],
|
||||||
position_independent_executables: true,
|
position_independent_executables: true,
|
||||||
has_elf_tls: true,
|
has_elf_tls: true,
|
||||||
.. Default::default()
|
.. Default::default()
|
||||||
|
|
|
||||||
|
|
@ -560,6 +560,8 @@ pub struct TargetOptions {
|
||||||
/// Emscripten toolchain.
|
/// Emscripten toolchain.
|
||||||
/// Defaults to false.
|
/// Defaults to false.
|
||||||
pub is_like_emscripten: bool,
|
pub is_like_emscripten: bool,
|
||||||
|
/// Whether the target toolchain is like Fuchsia's.
|
||||||
|
pub is_like_fuchsia: bool,
|
||||||
/// Whether the linker support GNU-like arguments such as -O. Defaults to false.
|
/// Whether the linker support GNU-like arguments such as -O. Defaults to false.
|
||||||
pub linker_is_gnu: bool,
|
pub linker_is_gnu: bool,
|
||||||
/// The MinGW toolchain has a known issue that prevents it from correctly
|
/// The MinGW toolchain has a known issue that prevents it from correctly
|
||||||
|
|
@ -729,6 +731,7 @@ impl Default for TargetOptions {
|
||||||
is_like_android: false,
|
is_like_android: false,
|
||||||
is_like_emscripten: false,
|
is_like_emscripten: false,
|
||||||
is_like_msvc: false,
|
is_like_msvc: false,
|
||||||
|
is_like_fuchsia: false,
|
||||||
linker_is_gnu: false,
|
linker_is_gnu: false,
|
||||||
allows_weak_linkage: true,
|
allows_weak_linkage: true,
|
||||||
has_rpath: false,
|
has_rpath: false,
|
||||||
|
|
@ -1028,6 +1031,7 @@ impl Target {
|
||||||
key!(is_like_msvc, bool);
|
key!(is_like_msvc, bool);
|
||||||
key!(is_like_emscripten, bool);
|
key!(is_like_emscripten, bool);
|
||||||
key!(is_like_android, bool);
|
key!(is_like_android, bool);
|
||||||
|
key!(is_like_fuchsia, bool);
|
||||||
key!(linker_is_gnu, bool);
|
key!(linker_is_gnu, bool);
|
||||||
key!(allows_weak_linkage, bool);
|
key!(allows_weak_linkage, bool);
|
||||||
key!(has_rpath, bool);
|
key!(has_rpath, bool);
|
||||||
|
|
@ -1238,6 +1242,7 @@ impl ToJson for Target {
|
||||||
target_option_val!(is_like_msvc);
|
target_option_val!(is_like_msvc);
|
||||||
target_option_val!(is_like_emscripten);
|
target_option_val!(is_like_emscripten);
|
||||||
target_option_val!(is_like_android);
|
target_option_val!(is_like_android);
|
||||||
|
target_option_val!(is_like_fuchsia);
|
||||||
target_option_val!(linker_is_gnu);
|
target_option_val!(linker_is_gnu);
|
||||||
target_option_val!(allows_weak_linkage);
|
target_option_val!(allows_weak_linkage);
|
||||||
target_option_val!(has_rpath);
|
target_option_val!(has_rpath);
|
||||||
|
|
|
||||||
|
|
@ -1571,7 +1571,7 @@ impl<K, V, S> HashMap<K, V, S>
|
||||||
/// so that the map now contains keys which compare equal, search may start
|
/// so that the map now contains keys which compare equal, search may start
|
||||||
/// acting erratically, with two keys randomly masking each other. Implementations
|
/// acting erratically, with two keys randomly masking each other. Implementations
|
||||||
/// are free to assume this doesn't happen (within the limits of memory-safety).
|
/// are free to assume this doesn't happen (within the limits of memory-safety).
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<K, V, S> {
|
pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<K, V, S> {
|
||||||
self.reserve(1);
|
self.reserve(1);
|
||||||
RawEntryBuilderMut { map: self }
|
RawEntryBuilderMut { map: self }
|
||||||
|
|
@ -1592,7 +1592,7 @@ impl<K, V, S> HashMap<K, V, S>
|
||||||
/// `get` should be preferred.
|
/// `get` should be preferred.
|
||||||
///
|
///
|
||||||
/// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`.
|
/// Immutable raw entries have very limited use; you might instead want `raw_entry_mut`.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn raw_entry(&self) -> RawEntryBuilder<K, V, S> {
|
pub fn raw_entry(&self) -> RawEntryBuilder<K, V, S> {
|
||||||
RawEntryBuilder { map: self }
|
RawEntryBuilder { map: self }
|
||||||
}
|
}
|
||||||
|
|
@ -1844,7 +1844,7 @@ impl<'a, K, V> InternalEntry<K, V, &'a mut RawTable<K, V>> {
|
||||||
///
|
///
|
||||||
/// [`HashMap::raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
|
/// [`HashMap::raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
|
||||||
|
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
|
pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
|
||||||
map: &'a mut HashMap<K, V, S>,
|
map: &'a mut HashMap<K, V, S>,
|
||||||
}
|
}
|
||||||
|
|
@ -1858,7 +1858,7 @@ pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
|
||||||
/// [`HashMap`]: struct.HashMap.html
|
/// [`HashMap`]: struct.HashMap.html
|
||||||
/// [`Entry`]: enum.Entry.html
|
/// [`Entry`]: enum.Entry.html
|
||||||
/// [`raw_entry`]: struct.HashMap.html#method.raw_entry
|
/// [`raw_entry`]: struct.HashMap.html#method.raw_entry
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub enum RawEntryMut<'a, K: 'a, V: 'a, S: 'a> {
|
pub enum RawEntryMut<'a, K: 'a, V: 'a, S: 'a> {
|
||||||
/// An occupied entry.
|
/// An occupied entry.
|
||||||
Occupied(RawOccupiedEntryMut<'a, K, V>),
|
Occupied(RawOccupiedEntryMut<'a, K, V>),
|
||||||
|
|
@ -1870,7 +1870,7 @@ pub enum RawEntryMut<'a, K: 'a, V: 'a, S: 'a> {
|
||||||
/// It is part of the [`RawEntryMut`] enum.
|
/// It is part of the [`RawEntryMut`] enum.
|
||||||
///
|
///
|
||||||
/// [`RawEntryMut`]: enum.RawEntryMut.html
|
/// [`RawEntryMut`]: enum.RawEntryMut.html
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub struct RawOccupiedEntryMut<'a, K: 'a, V: 'a> {
|
pub struct RawOccupiedEntryMut<'a, K: 'a, V: 'a> {
|
||||||
elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
|
elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
|
||||||
}
|
}
|
||||||
|
|
@ -1879,7 +1879,7 @@ pub struct RawOccupiedEntryMut<'a, K: 'a, V: 'a> {
|
||||||
/// It is part of the [`RawEntryMut`] enum.
|
/// It is part of the [`RawEntryMut`] enum.
|
||||||
///
|
///
|
||||||
/// [`RawEntryMut`]: enum.RawEntryMut.html
|
/// [`RawEntryMut`]: enum.RawEntryMut.html
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub struct RawVacantEntryMut<'a, K: 'a, V: 'a, S: 'a> {
|
pub struct RawVacantEntryMut<'a, K: 'a, V: 'a, S: 'a> {
|
||||||
elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
|
elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
|
||||||
hash_builder: &'a S,
|
hash_builder: &'a S,
|
||||||
|
|
@ -1890,7 +1890,7 @@ pub struct RawVacantEntryMut<'a, K: 'a, V: 'a, S: 'a> {
|
||||||
/// See the [`HashMap::raw_entry`] docs for usage examples.
|
/// See the [`HashMap::raw_entry`] docs for usage examples.
|
||||||
///
|
///
|
||||||
/// [`HashMap::raw_entry`]: struct.HashMap.html#method.raw_entry
|
/// [`HashMap::raw_entry`]: struct.HashMap.html#method.raw_entry
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub struct RawEntryBuilder<'a, K: 'a, V: 'a, S: 'a> {
|
pub struct RawEntryBuilder<'a, K: 'a, V: 'a, S: 'a> {
|
||||||
map: &'a HashMap<K, V, S>,
|
map: &'a HashMap<K, V, S>,
|
||||||
}
|
}
|
||||||
|
|
@ -1900,7 +1900,7 @@ impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
|
||||||
K: Eq + Hash,
|
K: Eq + Hash,
|
||||||
{
|
{
|
||||||
/// Create a `RawEntryMut` from the given key.
|
/// Create a `RawEntryMut` from the given key.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn from_key<Q: ?Sized>(self, k: &Q) -> RawEntryMut<'a, K, V, S>
|
pub fn from_key<Q: ?Sized>(self, k: &Q) -> RawEntryMut<'a, K, V, S>
|
||||||
where K: Borrow<Q>,
|
where K: Borrow<Q>,
|
||||||
Q: Hash + Eq
|
Q: Hash + Eq
|
||||||
|
|
@ -1911,7 +1911,7 @@ impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a `RawEntryMut` from the given key and its hash.
|
/// Create a `RawEntryMut` from the given key and its hash.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S>
|
pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S>
|
||||||
where K: Borrow<Q>,
|
where K: Borrow<Q>,
|
||||||
Q: Eq
|
Q: Eq
|
||||||
|
|
@ -1941,7 +1941,7 @@ impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Create a `RawEntryMut` from the given hash.
|
/// Create a `RawEntryMut` from the given hash.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
|
pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
|
||||||
where for<'b> F: FnMut(&'b K) -> bool,
|
where for<'b> F: FnMut(&'b K) -> bool,
|
||||||
{
|
{
|
||||||
|
|
@ -1951,7 +1951,7 @@ impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
|
||||||
/// Search possible locations for an element with hash `hash` until `is_match` returns true for
|
/// Search possible locations for an element with hash `hash` until `is_match` returns true for
|
||||||
/// one of them. There is no guarantee that all keys passed to `is_match` will have the provided
|
/// one of them. There is no guarantee that all keys passed to `is_match` will have the provided
|
||||||
/// hash.
|
/// hash.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn search_bucket<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
|
pub fn search_bucket<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
|
||||||
where for<'b> F: FnMut(&'b K) -> bool,
|
where for<'b> F: FnMut(&'b K) -> bool,
|
||||||
{
|
{
|
||||||
|
|
@ -1963,7 +1963,7 @@ impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
|
||||||
where S: BuildHasher,
|
where S: BuildHasher,
|
||||||
{
|
{
|
||||||
/// Access an entry by key.
|
/// Access an entry by key.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn from_key<Q: ?Sized>(self, k: &Q) -> Option<(&'a K, &'a V)>
|
pub fn from_key<Q: ?Sized>(self, k: &Q) -> Option<(&'a K, &'a V)>
|
||||||
where K: Borrow<Q>,
|
where K: Borrow<Q>,
|
||||||
Q: Hash + Eq
|
Q: Hash + Eq
|
||||||
|
|
@ -1974,7 +1974,7 @@ impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access an entry by a key and its hash.
|
/// Access an entry by a key and its hash.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
|
pub fn from_key_hashed_nocheck<Q: ?Sized>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
|
||||||
where K: Borrow<Q>,
|
where K: Borrow<Q>,
|
||||||
Q: Hash + Eq
|
Q: Hash + Eq
|
||||||
|
|
@ -1997,7 +1997,7 @@ impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access an entry by hash.
|
/// Access an entry by hash.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
|
pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
|
||||||
where F: FnMut(&K) -> bool
|
where F: FnMut(&K) -> bool
|
||||||
{
|
{
|
||||||
|
|
@ -2007,7 +2007,7 @@ impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
|
||||||
/// Search possible locations for an element with hash `hash` until `is_match` returns true for
|
/// Search possible locations for an element with hash `hash` until `is_match` returns true for
|
||||||
/// one of them. There is no guarantee that all keys passed to `is_match` will have the provided
|
/// one of them. There is no guarantee that all keys passed to `is_match` will have the provided
|
||||||
/// hash.
|
/// hash.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn search_bucket<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
|
pub fn search_bucket<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
|
||||||
where F: FnMut(&K) -> bool
|
where F: FnMut(&K) -> bool
|
||||||
{
|
{
|
||||||
|
|
@ -2033,7 +2033,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
|
||||||
/// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2;
|
/// *map.raw_entry_mut().from_key("poneyland").or_insert("poneyland", 10).1 *= 2;
|
||||||
/// assert_eq!(map["poneyland"], 6);
|
/// assert_eq!(map["poneyland"], 6);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V)
|
pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V)
|
||||||
where K: Hash,
|
where K: Hash,
|
||||||
S: BuildHasher,
|
S: BuildHasher,
|
||||||
|
|
@ -2061,7 +2061,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
|
||||||
///
|
///
|
||||||
/// assert_eq!(map["poneyland"], "hoho".to_string());
|
/// assert_eq!(map["poneyland"], "hoho".to_string());
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn or_insert_with<F>(self, default: F) -> (&'a mut K, &'a mut V)
|
pub fn or_insert_with<F>(self, default: F) -> (&'a mut K, &'a mut V)
|
||||||
where F: FnOnce() -> (K, V),
|
where F: FnOnce() -> (K, V),
|
||||||
K: Hash,
|
K: Hash,
|
||||||
|
|
@ -2099,7 +2099,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
|
||||||
/// .or_insert("poneyland", 0);
|
/// .or_insert("poneyland", 0);
|
||||||
/// assert_eq!(map["poneyland"], 43);
|
/// assert_eq!(map["poneyland"], 43);
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn and_modify<F>(self, f: F) -> Self
|
pub fn and_modify<F>(self, f: F) -> Self
|
||||||
where F: FnOnce(&mut K, &mut V)
|
where F: FnOnce(&mut K, &mut V)
|
||||||
{
|
{
|
||||||
|
|
@ -2118,82 +2118,82 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
|
||||||
|
|
||||||
impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> {
|
impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> {
|
||||||
/// Gets a reference to the key in the entry.
|
/// Gets a reference to the key in the entry.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn key(&self) -> &K {
|
pub fn key(&self) -> &K {
|
||||||
self.elem.read().0
|
self.elem.read().0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a mutable reference to the key in the entry.
|
/// Gets a mutable reference to the key in the entry.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn key_mut(&mut self) -> &mut K {
|
pub fn key_mut(&mut self) -> &mut K {
|
||||||
self.elem.read_mut().0
|
self.elem.read_mut().0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the entry into a mutable reference to the key in the entry
|
/// Converts the entry into a mutable reference to the key in the entry
|
||||||
/// with a lifetime bound to the map itself.
|
/// with a lifetime bound to the map itself.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn into_key(self) -> &'a mut K {
|
pub fn into_key(self) -> &'a mut K {
|
||||||
self.elem.into_mut_refs().0
|
self.elem.into_mut_refs().0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a reference to the value in the entry.
|
/// Gets a reference to the value in the entry.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn get(&self) -> &V {
|
pub fn get(&self) -> &V {
|
||||||
self.elem.read().1
|
self.elem.read().1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the OccupiedEntry into a mutable reference to the value in the entry
|
/// Converts the OccupiedEntry into a mutable reference to the value in the entry
|
||||||
/// with a lifetime bound to the map itself.
|
/// with a lifetime bound to the map itself.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn into_mut(self) -> &'a mut V {
|
pub fn into_mut(self) -> &'a mut V {
|
||||||
self.elem.into_mut_refs().1
|
self.elem.into_mut_refs().1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a mutable reference to the value in the entry.
|
/// Gets a mutable reference to the value in the entry.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn get_mut(&mut self) -> &mut V {
|
pub fn get_mut(&mut self) -> &mut V {
|
||||||
self.elem.read_mut().1
|
self.elem.read_mut().1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a reference to the key and value in the entry.
|
/// Gets a reference to the key and value in the entry.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn get_key_value(&mut self) -> (&K, &V) {
|
pub fn get_key_value(&mut self) -> (&K, &V) {
|
||||||
self.elem.read()
|
self.elem.read()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a mutable reference to the key and value in the entry.
|
/// Gets a mutable reference to the key and value in the entry.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
|
pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
|
||||||
self.elem.read_mut()
|
self.elem.read_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the OccupiedEntry into a mutable reference to the key and value in the entry
|
/// Converts the OccupiedEntry into a mutable reference to the key and value in the entry
|
||||||
/// with a lifetime bound to the map itself.
|
/// with a lifetime bound to the map itself.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
|
pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
|
||||||
self.elem.into_mut_refs()
|
self.elem.into_mut_refs()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the value of the entry, and returns the entry's old value.
|
/// Sets the value of the entry, and returns the entry's old value.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn insert(&mut self, value: V) -> V {
|
pub fn insert(&mut self, value: V) -> V {
|
||||||
mem::replace(self.get_mut(), value)
|
mem::replace(self.get_mut(), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the value of the entry, and returns the entry's old value.
|
/// Sets the value of the entry, and returns the entry's old value.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn insert_key(&mut self, key: K) -> K {
|
pub fn insert_key(&mut self, key: K) -> K {
|
||||||
mem::replace(self.key_mut(), key)
|
mem::replace(self.key_mut(), key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes the value out of the entry, and returns it.
|
/// Takes the value out of the entry, and returns it.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn remove(self) -> V {
|
pub fn remove(self) -> V {
|
||||||
pop_internal(self.elem).1
|
pop_internal(self.elem).1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take the ownership of the key and value from the map.
|
/// Take the ownership of the key and value from the map.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn remove_entry(self) -> (K, V) {
|
pub fn remove_entry(self) -> (K, V) {
|
||||||
let (k, v, _) = pop_internal(self.elem);
|
let (k, v, _) = pop_internal(self.elem);
|
||||||
(k, v)
|
(k, v)
|
||||||
|
|
@ -2203,7 +2203,7 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> {
|
||||||
impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
|
impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
|
||||||
/// Sets the value of the entry with the VacantEntry's key,
|
/// Sets the value of the entry with the VacantEntry's key,
|
||||||
/// and returns a mutable reference to it.
|
/// and returns a mutable reference to it.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
|
pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
|
||||||
where K: Hash,
|
where K: Hash,
|
||||||
S: BuildHasher,
|
S: BuildHasher,
|
||||||
|
|
@ -2215,7 +2215,7 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
|
||||||
|
|
||||||
/// Sets the value of the entry with the VacantEntry's key,
|
/// Sets the value of the entry with the VacantEntry's key,
|
||||||
/// and returns a mutable reference to it.
|
/// and returns a mutable reference to it.
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) {
|
pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) {
|
||||||
let hash = SafeHash::new(hash);
|
let hash = SafeHash::new(hash);
|
||||||
let b = match self.elem {
|
let b = match self.elem {
|
||||||
|
|
@ -2236,7 +2236,7 @@ impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
impl<'a, K, V, S> Debug for RawEntryBuilderMut<'a, K, V, S> {
|
impl<'a, K, V, S> Debug for RawEntryBuilderMut<'a, K, V, S> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("RawEntryBuilder")
|
f.debug_struct("RawEntryBuilder")
|
||||||
|
|
@ -2244,7 +2244,7 @@ impl<'a, K, V, S> Debug for RawEntryBuilderMut<'a, K, V, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
impl<'a, K: Debug, V: Debug, S> Debug for RawEntryMut<'a, K, V, S> {
|
impl<'a, K: Debug, V: Debug, S> Debug for RawEntryMut<'a, K, V, S> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
@ -2262,7 +2262,7 @@ impl<'a, K: Debug, V: Debug, S> Debug for RawEntryMut<'a, K, V, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
impl<'a, K: Debug, V: Debug> Debug for RawOccupiedEntryMut<'a, K, V> {
|
impl<'a, K: Debug, V: Debug> Debug for RawOccupiedEntryMut<'a, K, V> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("RawOccupiedEntryMut")
|
f.debug_struct("RawOccupiedEntryMut")
|
||||||
|
|
@ -2272,7 +2272,7 @@ impl<'a, K: Debug, V: Debug> Debug for RawOccupiedEntryMut<'a, K, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
impl<'a, K, V, S> Debug for RawVacantEntryMut<'a, K, V, S> {
|
impl<'a, K, V, S> Debug for RawVacantEntryMut<'a, K, V, S> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("RawVacantEntryMut")
|
f.debug_struct("RawVacantEntryMut")
|
||||||
|
|
@ -2280,7 +2280,7 @@ impl<'a, K, V, S> Debug for RawVacantEntryMut<'a, K, V, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||||
impl<'a, K, V, S> Debug for RawEntryBuilder<'a, K, V, S> {
|
impl<'a, K, V, S> Debug for RawEntryBuilder<'a, K, V, S> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("RawEntryBuilder")
|
f.debug_struct("RawEntryBuilder")
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,9 @@ path = "rustc.rs"
|
||||||
rustc_target = { path = "../librustc_target" }
|
rustc_target = { path = "../librustc_target" }
|
||||||
rustc_driver = { path = "../librustc_driver" }
|
rustc_driver = { path = "../librustc_driver" }
|
||||||
|
|
||||||
|
# Make sure rustc_codegen_ssa ends up in the sysroot, because this
|
||||||
|
# crate is intended to be used by codegen backends, which may not be in-tree.
|
||||||
|
rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
jemalloc = ['rustc_driver/jemalloc-sys']
|
jemalloc = ['rustc_driver/jemalloc-sys']
|
||||||
|
|
|
||||||
|
|
@ -78,3 +78,9 @@ pub union CUnionU128{a:u128}
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn test_CUnionU128(_: CUnionU128) { loop {} }
|
pub fn test_CUnionU128(_: CUnionU128) { loop {} }
|
||||||
|
|
||||||
|
pub union UnionBool { b:bool }
|
||||||
|
// CHECK: define zeroext i1 @test_UnionBool(i8 %b)
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } }
|
||||||
|
// CHECK: %0 = trunc i8 %b to i1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,34 +8,34 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// ignore-bitrig
|
|
||||||
// ignore-solaris
|
|
||||||
// ignore-windows failing on win32 bot
|
|
||||||
// ignore-freebsd: gdb package too new
|
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
// ignore-lldb
|
// ignore-lldb
|
||||||
// ignore-android: FIXME(#10381)
|
// ignore-android: FIXME(#10381)
|
||||||
|
// min-gdb-version: 7.11
|
||||||
|
|
||||||
// compile-flags:-g
|
// compile-flags:-g
|
||||||
|
|
||||||
// gdb-command: run
|
// gdb-command: run
|
||||||
|
|
||||||
// gdb-command: print regular_struct
|
// gdb-command: print regular_struct
|
||||||
// gdb-check:$1 = RegularStruct = {the_first_field = 101, the_second_field = 102.5, the_third_field = false}
|
// gdbg-check:$1 = RegularStruct = {the_first_field = 101, the_second_field = 102.5, the_third_field = false}
|
||||||
|
// gdbr-check:$1 = gdb_pretty_struct_and_enums::RegularStruct {the_first_field: 101, the_second_field: 102.5, the_third_field: false}
|
||||||
|
|
||||||
// gdb-command: print empty_struct
|
// gdb-command: print empty_struct
|
||||||
// gdb-check:$2 = EmptyStruct
|
// gdbg-check:$2 = EmptyStruct
|
||||||
|
// gdbr-check:$2 = gdb_pretty_struct_and_enums::EmptyStruct
|
||||||
|
|
||||||
// gdb-command: print c_style_enum1
|
// gdb-command: print c_style_enum1
|
||||||
// gdbg-check:$3 = CStyleEnumVar1
|
// gdbg-check:$3 = CStyleEnumVar1
|
||||||
// gdbr-check:$3 = gdb_pretty_struct_and_enums_pre_gdb_7_7::CStyleEnum::CStyleEnumVar1
|
// gdbr-check:$3 = gdb_pretty_struct_and_enums::CStyleEnum::CStyleEnumVar1
|
||||||
|
|
||||||
// gdb-command: print c_style_enum2
|
// gdb-command: print c_style_enum2
|
||||||
// gdbg-check:$4 = CStyleEnumVar2
|
// gdbg-check:$4 = CStyleEnumVar2
|
||||||
// gdbr-check:$4 = gdb_pretty_struct_and_enums_pre_gdb_7_7::CStyleEnum::CStyleEnumVar2
|
// gdbr-check:$4 = gdb_pretty_struct_and_enums::CStyleEnum::CStyleEnumVar2
|
||||||
|
|
||||||
// gdb-command: print c_style_enum3
|
// gdb-command: print c_style_enum3
|
||||||
// gdbg-check:$5 = CStyleEnumVar3
|
// gdbg-check:$5 = CStyleEnumVar3
|
||||||
// gdbr-check:$5 = gdb_pretty_struct_and_enums_pre_gdb_7_7::CStyleEnum::CStyleEnumVar3
|
// gdbr-check:$5 = gdb_pretty_struct_and_enums::CStyleEnum::CStyleEnumVar3
|
||||||
|
|
||||||
#![allow(dead_code, unused_variables)]
|
#![allow(dead_code, unused_variables)]
|
||||||
|
|
||||||
47
src/test/ui-fulldeps/auxiliary/subspan.rs
Normal file
47
src/test/ui-fulldeps/auxiliary/subspan.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// no-prefer-dynamic
|
||||||
|
|
||||||
|
#![crate_type = "proc-macro"]
|
||||||
|
#![feature(proc_macro_diagnostic, proc_macro_span)]
|
||||||
|
|
||||||
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
use proc_macro::{TokenStream, TokenTree, Span, Diagnostic};
|
||||||
|
|
||||||
|
fn parse(input: TokenStream) -> Result<(), Diagnostic> {
|
||||||
|
if let Some(TokenTree::Literal(lit)) = input.into_iter().next() {
|
||||||
|
let mut spans = vec![];
|
||||||
|
let string = lit.to_string();
|
||||||
|
for hi in string.matches("hi") {
|
||||||
|
let index = hi.as_ptr() as usize - string.as_ptr() as usize;
|
||||||
|
let subspan = lit.subspan(index..(index + hi.len())).unwrap();
|
||||||
|
spans.push(subspan);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !spans.is_empty() {
|
||||||
|
Err(Span::call_site().error("found 'hi's").span_note(spans, "here"))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(Span::call_site().error("invalid input: expected string literal"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn subspan(input: TokenStream) -> TokenStream {
|
||||||
|
if let Err(diag) = parse(input) {
|
||||||
|
diag.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenStream::new()
|
||||||
|
}
|
||||||
37
src/test/ui-fulldeps/subspan.rs
Normal file
37
src/test/ui-fulldeps/subspan.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:subspan.rs
|
||||||
|
// ignore-stage1
|
||||||
|
|
||||||
|
extern crate subspan;
|
||||||
|
|
||||||
|
use subspan::subspan;
|
||||||
|
|
||||||
|
// This one emits no error.
|
||||||
|
subspan!("");
|
||||||
|
|
||||||
|
// Exactly one 'hi'.
|
||||||
|
subspan!("hi"); //~ ERROR found 'hi's
|
||||||
|
|
||||||
|
// Now two, back to back.
|
||||||
|
subspan!("hihi"); //~ ERROR found 'hi's
|
||||||
|
|
||||||
|
// Now three, back to back.
|
||||||
|
subspan!("hihihi"); //~ ERROR found 'hi's
|
||||||
|
|
||||||
|
// Now several, with spacing.
|
||||||
|
subspan!("why I hide? hi!"); //~ ERROR found 'hi's
|
||||||
|
subspan!("hey, hi, hidy, hidy, hi hi"); //~ ERROR found 'hi's
|
||||||
|
subspan!("this is a hi, and this is another hi"); //~ ERROR found 'hi's
|
||||||
|
subspan!("how are you this evening"); //~ ERROR found 'hi's
|
||||||
|
subspan!("this is highly eradic"); //~ ERROR found 'hi's
|
||||||
|
|
||||||
|
fn main() { }
|
||||||
98
src/test/ui-fulldeps/subspan.stderr
Normal file
98
src/test/ui-fulldeps/subspan.stderr
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:22:1
|
||||||
|
|
|
||||||
|
LL | subspan!("hi"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:22:11
|
||||||
|
|
|
||||||
|
LL | subspan!("hi"); //~ ERROR found 'hi's
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:25:1
|
||||||
|
|
|
||||||
|
LL | subspan!("hihi"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:25:11
|
||||||
|
|
|
||||||
|
LL | subspan!("hihi"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:28:1
|
||||||
|
|
|
||||||
|
LL | subspan!("hihihi"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:28:11
|
||||||
|
|
|
||||||
|
LL | subspan!("hihihi"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | subspan!("why I hide? hi!"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:31:17
|
||||||
|
|
|
||||||
|
LL | subspan!("why I hide? hi!"); //~ ERROR found 'hi's
|
||||||
|
| ^^ ^^
|
||||||
|
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:32:1
|
||||||
|
|
|
||||||
|
LL | subspan!("hey, hi, hidy, hidy, hi hi"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:32:16
|
||||||
|
|
|
||||||
|
LL | subspan!("hey, hi, hidy, hidy, hi hi"); //~ ERROR found 'hi's
|
||||||
|
| ^^ ^^ ^^ ^^ ^^
|
||||||
|
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:33:1
|
||||||
|
|
|
||||||
|
LL | subspan!("this is a hi, and this is another hi"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:33:12
|
||||||
|
|
|
||||||
|
LL | subspan!("this is a hi, and this is another hi"); //~ ERROR found 'hi's
|
||||||
|
| ^^ ^^ ^^ ^^
|
||||||
|
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:34:1
|
||||||
|
|
|
||||||
|
LL | subspan!("how are you this evening"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:34:24
|
||||||
|
|
|
||||||
|
LL | subspan!("how are you this evening"); //~ ERROR found 'hi's
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: found 'hi's
|
||||||
|
--> $DIR/subspan.rs:35:1
|
||||||
|
|
|
||||||
|
LL | subspan!("this is highly eradic"); //~ ERROR found 'hi's
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: here
|
||||||
|
--> $DIR/subspan.rs:35:12
|
||||||
|
|
|
||||||
|
LL | subspan!("this is highly eradic"); //~ ERROR found 'hi's
|
||||||
|
| ^^ ^^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue