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:
bors 2018-11-23 18:42:20 +00:00
commit 1f57e48411
27 changed files with 606 additions and 96 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 doesnt 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
///
/// Lets 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 items 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()
}
}

View file

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

View file

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

View file

@ -19,6 +19,7 @@
#![feature(flt2dec)]
#![feature(fmt_internals)]
#![feature(hashmap_internals)]
#![feature(iter_unfold)]
#![feature(pattern)]
#![feature(range_is_empty)]
#![feature(raw)]

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

@ -0,0 +1,37 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build: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() { }

View 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