mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-11 06:24:24 +00:00
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
19
Cargo.lock
19
Cargo.lock
@ -2073,6 +2073,7 @@ dependencies = [
|
||||
name = "rustc-main"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_codegen_ssa 0.0.0",
|
||||
"rustc_driver 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)",
|
||||
"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_codegen_ssa 0.0.0",
|
||||
"rustc_llvm 0.0.0",
|
||||
]
|
||||
|
||||
@ -2177,10 +2177,27 @@ dependencies = [
|
||||
name = "rustc_codegen_ssa"
|
||||
version = "0.0.0"
|
||||
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)",
|
||||
"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)",
|
||||
"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_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]]
|
||||
|
@ -74,6 +74,14 @@ Cargo
|
||||
[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
|
||||
|
||||
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)
|
||||
==========================
|
||||
|
@ -55,6 +55,7 @@ function fetch_submodule {
|
||||
}
|
||||
|
||||
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=($modules)
|
||||
use_git=""
|
||||
|
@ -18,6 +18,8 @@ import debugger_pretty_printers_common as rustpp
|
||||
if sys.version_info[0] >= 3:
|
||||
xrange = range
|
||||
|
||||
rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string = True)
|
||||
|
||||
#===============================================================================
|
||||
# GDB Pretty Printing Module for Rust
|
||||
#===============================================================================
|
||||
@ -99,27 +101,9 @@ def rust_pretty_printer_lookup_function(gdb_val):
|
||||
val = GdbValue(gdb_val)
|
||||
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:
|
||||
return RustSlicePrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STR_SLICE:
|
||||
return RustStringSlicePrinter(val)
|
||||
|
||||
if type_kind == rustpp.TYPE_KIND_STD_VEC:
|
||||
return RustStdVecPrinter(val)
|
||||
|
||||
@ -138,6 +122,29 @@ def rust_pretty_printer_lookup_function(gdb_val):
|
||||
if type_kind == rustpp.TYPE_KIND_OS_STRING:
|
||||
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:
|
||||
return RustStructPrinter(val,
|
||||
omit_first_field = False,
|
||||
|
@ -112,10 +112,10 @@
|
||||
//!
|
||||
//! // next() is the only required method
|
||||
//! 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;
|
||||
//!
|
||||
//! // check to see if we've finished counting or not.
|
||||
//! // Check to see if we've finished counting or not.
|
||||
//! if self.count < 6 {
|
||||
//! Some(self.count)
|
||||
//! } else {
|
||||
@ -339,6 +339,8 @@ pub use self::sources::{RepeatWith, repeat_with};
|
||||
pub use self::sources::{Empty, empty};
|
||||
#[stable(feature = "iter_once", since = "1.2.0")]
|
||||
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")]
|
||||
pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend};
|
||||
|
@ -166,14 +166,14 @@ macro_rules! step_impl_no_between {
|
||||
}
|
||||
|
||||
step_impl_unsigned!(usize u8 u16);
|
||||
#[cfg(not(target_pointer_witdth = "16"))]
|
||||
#[cfg(not(target_pointer_width = "16"))]
|
||||
step_impl_unsigned!(u32);
|
||||
#[cfg(target_pointer_witdth = "16")]
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
step_impl_no_between!(u32);
|
||||
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]);
|
||||
#[cfg(target_pointer_witdth = "16")]
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
step_impl_no_between!(i32);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
step_impl_unsigned!(u64);
|
||||
|
@ -386,3 +386,164 @@ impl<T> FusedIterator for Once<T> {}
|
||||
pub fn once<T>(value: T) -> Once<T> {
|
||||
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
|
||||
}
|
||||
|
||||
/// Walks through `iter` checking that it's a valid UTF-8 sequence,
|
||||
/// returning `true` in that case, or, if it is invalid, `false` with
|
||||
/// `iter` reset such that it is pointing at the first byte in the
|
||||
/// invalid sequence.
|
||||
/// Walks through `v` checking that it's a valid UTF-8 sequence,
|
||||
/// returning `Ok(())` in that case, or, if it is invalid, `Err(err)`.
|
||||
#[inline]
|
||||
fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
|
||||
let mut index = 0;
|
||||
|
@ -1759,6 +1759,17 @@ fn test_repeat_with_take_collect() {
|
||||
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]
|
||||
fn test_fuse() {
|
||||
let mut it = 0..3;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#![feature(flt2dec)]
|
||||
#![feature(fmt_internals)]
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(iter_unfold)]
|
||||
#![feature(pattern)]
|
||||
#![feature(range_is_empty)]
|
||||
#![feature(raw)]
|
||||
|
@ -50,6 +50,7 @@ mod diagnostic;
|
||||
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
|
||||
pub use diagnostic::{Diagnostic, Level, MultiSpan};
|
||||
|
||||
use std::ops::{Bound, RangeBounds};
|
||||
use std::{ascii, fmt, iter};
|
||||
use std::path::PathBuf;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
@ -59,7 +60,7 @@ use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::parse::{self, token};
|
||||
use syntax::symbol::Symbol;
|
||||
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
|
||||
/// tokens, or, more specifically, a sequence of token trees.
|
||||
@ -1168,6 +1169,50 @@ impl Literal {
|
||||
pub fn set_span(&mut 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
|
||||
|
@ -93,16 +93,27 @@ macro_rules! define_categories {
|
||||
$(
|
||||
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!(
|
||||
"{{ \"category\": {}, \"time_ms\": {},
|
||||
\"query_count\": {}, \"query_hits\": {} }}",
|
||||
\"query_count\": {}, \"query_hits\": {} }},",
|
||||
stringify!($name),
|
||||
self.times.$name / 1_000_000,
|
||||
total,
|
||||
format!("{:.2}", (((hits as f32) / (total as f32)) * 100.0))
|
||||
format!("{:.2}", hit_percent)
|
||||
));
|
||||
)*
|
||||
|
||||
//remove the trailing ',' character
|
||||
json.pop();
|
||||
|
||||
json.push(']');
|
||||
|
||||
json
|
||||
|
@ -13,7 +13,6 @@ test = false
|
||||
cc = "1.0.1"
|
||||
num_cpus = "1.0"
|
||||
rustc-demangle = "0.1.4"
|
||||
rustc_codegen_ssa = { path = "../librustc_codegen_ssa" }
|
||||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
memmap = "0.6"
|
||||
|
||||
|
@ -19,7 +19,7 @@ use super::rpath::RPathConfig;
|
||||
use super::rpath;
|
||||
use metadata::METADATA_FILENAME;
|
||||
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::search_paths::PathKind;
|
||||
use rustc::session::Session;
|
||||
@ -491,6 +491,14 @@ fn link_natively(sess: &Session,
|
||||
}
|
||||
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 {
|
||||
&sess.target.target.options.pre_link_objects_exe
|
||||
} else {
|
||||
|
@ -6,10 +6,29 @@ version = "0.0.0"
|
||||
[lib]
|
||||
name = "rustc_codegen_ssa"
|
||||
path = "lib.rs"
|
||||
crate-type = ["dylib"]
|
||||
test = false
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0.4"
|
||||
cc = "1.0.1"
|
||||
num_cpus = "1.0"
|
||||
rustc-demangle = "0.1.4"
|
||||
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.
|
||||
// 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 {
|
||||
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) => {
|
||||
*a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true));
|
||||
*b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true));
|
||||
*a = to_immediate_or_cast(bx, *a, bx.cx()
|
||||
.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!()
|
||||
}
|
||||
|
@ -11,11 +11,12 @@
|
||||
/// A simple static assertion macro. The first argument should be a unique
|
||||
/// ALL_CAPS identifier that describes the condition.
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable]
|
||||
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];
|
||||
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(
|
||||
"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 {
|
||||
StackPopCleanup::Goto(block) => {
|
||||
self.goto_block(block)?;
|
||||
}
|
||||
StackPopCleanup::Goto(_) => {},
|
||||
StackPopCleanup::None { cleanup } => {
|
||||
if !cleanup {
|
||||
// Leak the locals. Also skip validation, this is only used by
|
||||
// static/const computation which does its own (stronger) final
|
||||
// validation.
|
||||
assert!(self.stack.is_empty(), "only the topmost frame should ever be leaked");
|
||||
// Leak the locals, skip validation.
|
||||
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 {
|
||||
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 M::enforce_validity(self) {
|
||||
// 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
|
||||
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...
|
||||
debug!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
|
@ -12,9 +12,11 @@ use spec::{LldFlavor, LinkArgs, LinkerFlavor, TargetOptions};
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut args = LinkArgs::new();
|
||||
args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec![
|
||||
"--build-id".to_string(), "--hash-style=gnu".to_string(),
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec![
|
||||
"--build-id".to_string(),
|
||||
"--eh-frame-hdr".to_string(),
|
||||
"--hash-style=gnu".to_string(),
|
||||
"-z".to_string(), "rodynamic".to_string(),
|
||||
]);
|
||||
|
||||
@ -24,9 +26,13 @@ pub fn opts() -> TargetOptions {
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
target_family: Some("unix".to_string()),
|
||||
is_like_fuchsia: true,
|
||||
linker_is_gnu: true,
|
||||
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,
|
||||
has_elf_tls: true,
|
||||
.. Default::default()
|
||||
|
@ -560,6 +560,8 @@ pub struct TargetOptions {
|
||||
/// Emscripten toolchain.
|
||||
/// Defaults to false.
|
||||
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.
|
||||
pub linker_is_gnu: bool,
|
||||
/// 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_emscripten: false,
|
||||
is_like_msvc: false,
|
||||
is_like_fuchsia: false,
|
||||
linker_is_gnu: false,
|
||||
allows_weak_linkage: true,
|
||||
has_rpath: false,
|
||||
@ -1028,6 +1031,7 @@ impl Target {
|
||||
key!(is_like_msvc, bool);
|
||||
key!(is_like_emscripten, bool);
|
||||
key!(is_like_android, bool);
|
||||
key!(is_like_fuchsia, bool);
|
||||
key!(linker_is_gnu, bool);
|
||||
key!(allows_weak_linkage, bool);
|
||||
key!(has_rpath, bool);
|
||||
@ -1238,6 +1242,7 @@ impl ToJson for Target {
|
||||
target_option_val!(is_like_msvc);
|
||||
target_option_val!(is_like_emscripten);
|
||||
target_option_val!(is_like_android);
|
||||
target_option_val!(is_like_fuchsia);
|
||||
target_option_val!(linker_is_gnu);
|
||||
target_option_val!(allows_weak_linkage);
|
||||
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
|
||||
/// acting erratically, with two keys randomly masking each other. Implementations
|
||||
/// 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> {
|
||||
self.reserve(1);
|
||||
RawEntryBuilderMut { map: self }
|
||||
@ -1592,7 +1592,7 @@ impl<K, V, S> HashMap<K, V, S>
|
||||
/// `get` should be preferred.
|
||||
///
|
||||
/// 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> {
|
||||
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
|
||||
|
||||
#[unstable(feature = "hash_raw_entry", issue = "54043")]
|
||||
#[unstable(feature = "hash_raw_entry", issue = "56167")]
|
||||
pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
|
||||
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
|
||||
/// [`Entry`]: enum.Entry.html
|
||||
/// [`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> {
|
||||
/// An occupied entry.
|
||||
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.
|
||||
///
|
||||
/// [`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> {
|
||||
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.
|
||||
///
|
||||
/// [`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> {
|
||||
elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
|
||||
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.
|
||||
///
|
||||
/// [`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> {
|
||||
map: &'a HashMap<K, V, S>,
|
||||
}
|
||||
@ -1900,7 +1900,7 @@ impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
|
||||
K: Eq + Hash,
|
||||
{
|
||||
/// 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>
|
||||
where K: Borrow<Q>,
|
||||
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.
|
||||
#[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>
|
||||
where K: Borrow<Q>,
|
||||
Q: Eq
|
||||
@ -1941,7 +1941,7 @@ impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
|
||||
}
|
||||
}
|
||||
/// 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>
|
||||
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
|
||||
/// one of them. There is no guarantee that all keys passed to `is_match` will have the provided
|
||||
/// 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>
|
||||
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,
|
||||
{
|
||||
/// 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)>
|
||||
where K: Borrow<Q>,
|
||||
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.
|
||||
#[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)>
|
||||
where K: Borrow<Q>,
|
||||
Q: Hash + Eq
|
||||
@ -1997,7 +1997,7 @@ impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
|
||||
}
|
||||
|
||||
/// 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)>
|
||||
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
|
||||
/// one of them. There is no guarantee that all keys passed to `is_match` will have the provided
|
||||
/// 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)>
|
||||
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;
|
||||
/// 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)
|
||||
where K: Hash,
|
||||
S: BuildHasher,
|
||||
@ -2061,7 +2061,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
|
||||
///
|
||||
/// 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)
|
||||
where F: FnOnce() -> (K, V),
|
||||
K: Hash,
|
||||
@ -2099,7 +2099,7 @@ impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
|
||||
/// .or_insert("poneyland", 0);
|
||||
/// 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
|
||||
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> {
|
||||
/// 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 {
|
||||
self.elem.read().0
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
self.elem.read_mut().0
|
||||
}
|
||||
|
||||
/// Converts the entry into a mutable reference to the key in the entry
|
||||
/// 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 {
|
||||
self.elem.into_mut_refs().0
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
self.elem.read().1
|
||||
}
|
||||
|
||||
/// Converts the OccupiedEntry into a mutable reference to the value in the entry
|
||||
/// 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 {
|
||||
self.elem.into_mut_refs().1
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
self.elem.read_mut().1
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
self.elem.read()
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
self.elem.read_mut()
|
||||
}
|
||||
|
||||
/// Converts the OccupiedEntry into a mutable reference to the key and value in the entry
|
||||
/// 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) {
|
||||
self.elem.into_mut_refs()
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
mem::replace(self.get_mut(), 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 {
|
||||
mem::replace(self.key_mut(), key)
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
pop_internal(self.elem).1
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
let (k, v, _) = pop_internal(self.elem);
|
||||
(k, v)
|
||||
@ -2203,7 +2203,7 @@ impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> {
|
||||
impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
|
||||
/// Sets the value of the entry with the VacantEntry's key,
|
||||
/// 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)
|
||||
where K: Hash,
|
||||
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,
|
||||
/// 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) {
|
||||
let hash = SafeHash::new(hash);
|
||||
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> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("RawEntryBuilder")
|
||||
|
@ -11,5 +11,9 @@ path = "rustc.rs"
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
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]
|
||||
jemalloc = ['rustc_driver/jemalloc-sys']
|
||||
|
@ -78,3 +78,9 @@ pub union CUnionU128{a:u128}
|
||||
#[no_mangle]
|
||||
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
|
||||
// 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-lldb
|
||||
// ignore-android: FIXME(#10381)
|
||||
// min-gdb-version: 7.11
|
||||
|
||||
// compile-flags:-g
|
||||
|
||||
// gdb-command: run
|
||||
|
||||
// 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-check:$2 = EmptyStruct
|
||||
// gdbg-check:$2 = EmptyStruct
|
||||
// gdbr-check:$2 = gdb_pretty_struct_and_enums::EmptyStruct
|
||||
|
||||
// gdb-command: print c_style_enum1
|
||||
// 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
|
||||
// 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
|
||||
// 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)]
|
||||
|
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…
Reference in New Issue
Block a user