Auto merge of #56818 - kennytm:rollup-2, r=kennytm

Rollup of 14 pull requests (first batch)

Successful merges:

 - #56562 (Update libc version required by rustc)
 - #56609 (Unconditionally emit the target-cpu LLVM attribute.)
 - #56637 (rustdoc: Fix local reexports of proc macros)
 - #56658 (Add non-panicking `maybe_new_parser_from_file` variant)
 - #56695 (Fix irrefutable matches on integer ranges)
 - #56699 (Use a `newtype_index!` within `Symbol`.)
 - #56702 ([self-profiler] Add column for percent of total time)
 - #56708 (Remove some unnecessary feature gates)
 - #56709 (Remove unneeded extra chars to reduce search-index size)
 - #56744 (specialize: remove Boxes used by Children::insert)
 - #56748 (Update panic message to be clearer about env-vars)
 - #56749 (x86: Add the `adx` target feature to whitelist)
 - #56756 (Disable btree pretty-printers on older gdbs)
 - #56789 (rustc: Add an unstable `simd_select_bitmask` intrinsic)

r? @ghost
This commit is contained in:
bors 2018-12-14 16:15:20 +00:00
commit 1897657ef0
38 changed files with 335 additions and 100 deletions

View File

@ -9,6 +9,7 @@
# except according to those terms.
import gdb
import re
import sys
import debugger_pretty_printers_common as rustpp
@ -20,6 +21,16 @@ if sys.version_info[0] >= 3:
rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string = True)
# The btree pretty-printers fail in a confusing way unless
# https://sourceware.org/bugzilla/show_bug.cgi?id=21763 is fixed.
# This fix went in 8.1, so check for that.
# See https://github.com/rust-lang/rust/issues/56730
gdb_81 = False
_match = re.match('([0-9]+)\\.([0-9]+)', gdb.VERSION)
if _match:
if int(_match.group(1)) > 8 or (int(_match.group(1)) == 8 and int(_match.group(2)) >= 1):
gdb_81 = True
#===============================================================================
# GDB Pretty Printing Module for Rust
#===============================================================================
@ -110,10 +121,10 @@ def rust_pretty_printer_lookup_function(gdb_val):
if type_kind == rustpp.TYPE_KIND_STD_VECDEQUE:
return RustStdVecDequePrinter(val)
if type_kind == rustpp.TYPE_KIND_STD_BTREESET:
if type_kind == rustpp.TYPE_KIND_STD_BTREESET and gdb_81:
return RustStdBTreeSetPrinter(val)
if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP:
if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP and gdb_81:
return RustStdBTreeMapPrinter(val)
if type_kind == rustpp.TYPE_KIND_STD_STRING:

View File

@ -132,10 +132,12 @@ impl<'a, 'gcx, 'tcx> Children {
simplified_self,
);
for possible_sibling in match simplified_self {
Some(sty) => self.filtered(sty),
None => self.iter(),
} {
let possible_siblings = match simplified_self {
Some(sty) => PotentialSiblings::Filtered(self.filtered(sty)),
None => PotentialSiblings::Unfiltered(self.iter()),
};
for possible_sibling in possible_siblings {
debug!(
"insert: impl_def_id={:?}, simplified_self={:?}, possible_sibling={:?}",
impl_def_id,
@ -222,14 +224,37 @@ impl<'a, 'gcx, 'tcx> Children {
Ok(Inserted::BecameNewSibling(last_lint))
}
fn iter(&mut self) -> Box<dyn Iterator<Item = DefId> + '_> {
fn iter(&mut self) -> impl Iterator<Item = DefId> + '_ {
let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter());
Box::new(self.blanket_impls.iter().chain(nonblanket).cloned())
self.blanket_impls.iter().chain(nonblanket).cloned()
}
fn filtered(&mut self, sty: SimplifiedType) -> Box<dyn Iterator<Item = DefId> + '_> {
fn filtered(&mut self, sty: SimplifiedType) -> impl Iterator<Item = DefId> + '_ {
let nonblanket = self.nonblanket_impls.entry(sty).or_default().iter();
Box::new(self.blanket_impls.iter().chain(nonblanket).cloned())
self.blanket_impls.iter().chain(nonblanket).cloned()
}
}
// A custom iterator used by Children::insert
enum PotentialSiblings<I, J>
where I: Iterator<Item = DefId>,
J: Iterator<Item = DefId>
{
Unfiltered(I),
Filtered(J)
}
impl<I, J> Iterator for PotentialSiblings<I, J>
where I: Iterator<Item = DefId>,
J: Iterator<Item = DefId>
{
type Item = DefId;
fn next(&mut self) -> Option<Self::Item> {
match *self {
PotentialSiblings::Unfiltered(ref mut iter) => iter.next(),
PotentialSiblings::Filtered(ref mut iter) => iter.next()
}
}
}

View File

@ -62,11 +62,15 @@ macro_rules! define_categories {
}
fn print(&self, lock: &mut StderrLock<'_>) {
writeln!(lock, "| Phase | Time (ms) | Queries | Hits (%) |")
writeln!(lock, "| Phase | Time (ms) \
| Time (%) | Queries | Hits (%)")
.unwrap();
writeln!(lock, "| ---------------- | -------------- | -------------- | -------- |")
writeln!(lock, "| ---------------- | -------------- \
| -------- | -------------- | --------")
.unwrap();
let total_time = ($(self.times.$name + )* 0) as f32;
$(
let (hits, total) = self.query_counts.$name;
let (hits, total) = if total > 0 {
@ -78,11 +82,12 @@ macro_rules! define_categories {
writeln!(
lock,
"| {0: <16} | {1: <14} | {2: <14} | {3: <8} |",
"| {0: <16} | {1: <14} | {2: <8.2} | {3: <14} | {4: <8}",
stringify!($name),
self.times.$name / 1_000_000,
((self.times.$name as f32) / total_time) * 100.0,
total,
hits
hits,
).unwrap();
)*
}

View File

@ -18,6 +18,7 @@ use rustc::session::config::Sanitizer;
use rustc::ty::{self, TyCtxt, PolyFnSig};
use rustc::ty::layout::HasTyCtxt;
use rustc::ty::query::Providers;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::fx::FxHashMap;
use rustc_target::spec::PanicStrategy;
@ -130,8 +131,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
}
pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
let cpu = llvm_util::target_cpu(cx.tcx.sess);
let target_cpu = CString::new(cpu).unwrap();
let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess));
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
@ -231,11 +231,7 @@ pub fn from_fn_attrs(
// Always annotate functions with the target-cpu they are compiled for.
// Without this, ThinLTO won't inline Rust functions into Clang generated
// functions (because Clang annotates functions this way too).
// NOTE: For now we just apply this if -Zcross-lang-lto is specified, since
// it introduce a little overhead and isn't really necessary otherwise.
if cx.tcx.sess.opts.debugging_opts.cross_lang_lto.enabled() {
apply_target_cpu_attr(cx, llfn);
}
apply_target_cpu_attr(cx, llfn);
let features = llvm_target_features(cx.tcx.sess)
.map(|s| s.to_string())

View File

@ -1171,6 +1171,27 @@ fn generic_simd_intrinsic(
);
let arg_tys = sig.inputs();
if name == "simd_select_bitmask" {
let in_ty = arg_tys[0];
let m_len = match in_ty.sty {
// Note that this `.unwrap()` crashes for isize/usize, that's sort
// of intentional as there's not currently a use case for that.
ty::Int(i) => i.bit_width().unwrap(),
ty::Uint(i) => i.bit_width().unwrap(),
_ => return_error!("`{}` is not an integral type", in_ty),
};
require_simd!(arg_tys[1], "argument");
let v_len = arg_tys[1].simd_size(tcx);
require!(m_len == v_len,
"mismatched lengths: mask length `{}` != other vector length `{}`",
m_len, v_len
);
let i1 = bx.type_i1();
let i1xn = bx.type_vector(i1, m_len as u64);
let m_i1s = bx.bitcast(args[0].immediate(), i1xn);
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
}
// every intrinsic takes a SIMD vector as its first argument
require_simd!(arg_tys[0], "input");
let in_ty = arg_tys[0];

View File

@ -124,6 +124,7 @@ const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[
];
const X86_WHITELIST: &[(&str, Option<&str>)] = &[
("adx", Some("adx_target_feature")),
("aes", None),
("avx", None),
("avx2", None),

View File

@ -16,7 +16,7 @@ num_cpus = "1.0"
rustc-demangle = "0.1.4"
memmap = "0.6"
log = "0.4.5"
libc = "0.2.43"
libc = "0.2.44"
jobserver = "0.1.11"
serialize = { path = "../libserialize" }

View File

@ -26,6 +26,10 @@ use build::{BlockAnd, BlockAndExtension, Builder};
use build::matches::{Ascription, Binding, MatchPair, Candidate};
use hair::*;
use rustc::mir::*;
use rustc::ty;
use rustc::ty::layout::{Integer, IntegerExt, Size};
use syntax::attr::{SignedInt, UnsignedInt};
use rustc::hir::RangeEnd;
use std::mem;
@ -62,6 +66,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
match_pair: MatchPair<'pat, 'tcx>,
candidate: &mut Candidate<'pat, 'tcx>)
-> Result<(), MatchPair<'pat, 'tcx>> {
let tcx = self.hir.tcx();
match *match_pair.pattern.kind {
PatternKind::AscribeUserType { ref subpattern, ref user_ty, user_ty_span } => {
candidate.ascriptions.push(Ascription {
@ -104,7 +109,34 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
Err(match_pair)
}
PatternKind::Range { .. } => {
PatternKind::Range { lo, hi, ty, end } => {
let range = match ty.sty {
ty::Char => {
Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32)))
}
ty::Int(ity) => {
// FIXME(49937): refactor these bit manipulations into interpret.
let size = Integer::from_attr(&tcx, SignedInt(ity)).size();
let min = 1u128 << (size.bits() - 1);
let max = (1u128 << (size.bits() - 1)) - 1;
Some((min, max, size))
}
ty::Uint(uty) => {
// FIXME(49937): refactor these bit manipulations into interpret.
let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size();
let max = !0u128 >> (128 - size.bits());
Some((0, max, size))
}
_ => None,
};
if let Some((min, max, sz)) = range {
if let (Some(lo), Some(hi)) = (lo.val.try_to_bits(sz), hi.val.try_to_bits(sz)) {
if lo <= min && (hi > max || hi == max && end == RangeEnd::Included) {
// Irrefutable pattern match.
return Ok(());
}
}
}
Err(match_pair)
}

View File

@ -435,7 +435,8 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
"simd_insert" => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
"simd_extract" => (2, vec![param(0), tcx.types.u32], param(1)),
"simd_cast" => (2, vec![param(0)], param(1)),
"simd_select" => (2, vec![param(0), param(1), param(1)], param(1)),
"simd_select" |
"simd_select_bitmask" => (2, vec![param(0), param(1), param(1)], param(1)),
"simd_reduce_all" | "simd_reduce_any" => (1, vec![param(0)], tcx.types.bool),
"simd_reduce_add_ordered" | "simd_reduce_mul_ordered"
=> (2, vec![param(0), param(1)], param(1)),

View File

@ -806,6 +806,10 @@ impl<'a> fmt::Display for MarkdownSummaryLine<'a> {
}
pub fn plain_summary_line(md: &str) -> String {
plain_summary_line_full(md, false)
}
pub fn plain_summary_line_full(md: &str, limit_length: bool) -> String {
struct ParserWrapper<'a> {
inner: Parser<'a>,
is_in: isize,
@ -852,7 +856,21 @@ pub fn plain_summary_line(md: &str) -> String {
s.push_str(&t);
}
}
s
if limit_length && s.chars().count() > 60 {
let mut len = 0;
let mut ret = s.split_whitespace()
.take_while(|p| {
// + 1 for the added character after the word.
len += p.chars().count() + 1;
len < 60
})
.collect::<Vec<_>>()
.join(" ");
ret.push('…');
ret
} else {
s
}
}
pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {

View File

@ -698,7 +698,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
ty: item.type_(),
name: item.name.clone().unwrap(),
path: fqp[..fqp.len() - 1].join("::"),
desc: plain_summary_line(item.doc_value()),
desc: plain_summary_line_short(item.doc_value()),
parent: Some(did),
parent_idx: None,
search_type: get_index_search_type(&item),
@ -736,7 +736,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
}
let crate_doc = krate.module.as_ref().map(|module| {
plain_summary_line(module.doc_value())
plain_summary_line_short(module.doc_value())
}).unwrap_or(String::new());
let mut crate_data = BTreeMap::new();
@ -1481,7 +1481,7 @@ impl DocFolder for Cache {
ty: item.type_(),
name: s.to_string(),
path: path.join("::"),
desc: plain_summary_line(item.doc_value()),
desc: plain_summary_line_short(item.doc_value()),
parent,
parent_idx: None,
search_type: get_index_search_type(&item),
@ -1512,7 +1512,8 @@ impl DocFolder for Cache {
clean::FunctionItem(..) | clean::ModuleItem(..) |
clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
clean::ConstantItem(..) | clean::StaticItem(..) |
clean::UnionItem(..) | clean::ForeignTypeItem | clean::MacroItem(..)
clean::UnionItem(..) | clean::ForeignTypeItem |
clean::MacroItem(..) | clean::ProcMacroItem(..)
if !self.stripped_mod => {
// Re-exported items mean that the same id can show up twice
// in the rustdoc ast that we're looking at. We know,
@ -1673,7 +1674,7 @@ impl<'a> Cache {
ty: item.type_(),
name: item_name.to_string(),
path: path.clone(),
desc: plain_summary_line(item.doc_value()),
desc: plain_summary_line_short(item.doc_value()),
parent: None,
parent_idx: None,
search_type: get_index_search_type(&item),
@ -2388,7 +2389,13 @@ fn shorter<'a>(s: Option<&'a str>) -> String {
#[inline]
fn plain_summary_line(s: Option<&str>) -> String {
let line = shorter(s).replace("\n", " ");
markdown::plain_summary_line(&line[..])
markdown::plain_summary_line_full(&line[..], false)
}
#[inline]
fn plain_summary_line_short(s: Option<&str>) -> String {
let line = shorter(s).replace("\n", " ");
markdown::plain_summary_line_full(&line[..], true)
}
fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result {

View File

@ -424,10 +424,11 @@ impl<'a, 'tcx, 'rcx, 'cstore> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> {
hir::ItemKind::Use(ref path, kind) => {
let is_glob = kind == hir::UseKind::Glob;
// Struct and variant constructors always show up alongside their definitions, we've
// already processed them so just discard these.
// Struct and variant constructors and proc macro stubs always show up alongside
// their definitions, we've already processed them so just discard these.
match path.def {
Def::StructCtor(..) | Def::VariantCtor(..) | Def::SelfCtor(..) => return,
Def::StructCtor(..) | Def::VariantCtor(..) | Def::SelfCtor(..) |
Def::Macro(_, MacroKind::ProcMacroStub) => return,
_ => {}
}

View File

@ -26,7 +26,6 @@ const fn done<T>() -> *mut Arc<T> { 1_usize as *mut _ }
unsafe impl<T> Sync for Lazy<T> {}
impl<T> Lazy<T> {
#[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> Lazy<T> {
Lazy {
lock: Mutex::new(),

View File

@ -271,6 +271,7 @@
#![feature(libc)]
#![feature(link_args)]
#![feature(linkage)]
#![cfg_attr(not(stage0), feature(min_const_unsafe_fn))]
#![feature(needs_panic_runtime)]
#![feature(never_type)]
#![feature(nll)]

View File

@ -209,7 +209,8 @@ fn default_hook(info: &PanicInfo) {
if let Some(format) = log_backtrace {
let _ = backtrace::print(err, format);
} else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` for a backtrace.");
let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` \
environment variable to display a backtrace.");
}
}
};

View File

@ -34,13 +34,6 @@ fn image_base() -> u64 {
base
}
pub fn is_enclave_range(p: *const u8, len: usize) -> bool {
let start=p as u64;
let end=start + (len as u64);
start >= image_base() &&
end <= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant
}
pub fn is_user_range(p: *const u8, len: usize) -> bool {
let start=p as u64;
let end=start + (len as u64);

View File

@ -33,14 +33,6 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult<usize> {
}
}
pub fn read_alloc(fd: Fd) -> IoResult<Vec<u8>> {
unsafe {
let mut userbuf = alloc::User::<ByteBuffer>::uninitialized();
raw::read_alloc(fd, userbuf.as_raw_mut_ptr()).from_sgx_result()?;
Ok(copy_user_buffer(&userbuf))
}
}
pub fn write(fd: Fd, buf: &[u8]) -> IoResult<usize> {
unsafe {
let userbuf = alloc::User::new_from_enclave(buf);

View File

@ -18,7 +18,6 @@ pub struct Condvar {
}
impl Condvar {
#[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> Condvar {
Condvar { inner: SpinMutex::new(WaitVariable::new(())) }
}

View File

@ -20,7 +20,6 @@ pub struct Mutex {
// Implementation according to “Operating Systems: Three Easy Pieces”, chapter 28
impl Mutex {
#[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> Mutex {
Mutex { inner: SpinMutex::new(WaitVariable::new(false)) }
}
@ -79,7 +78,6 @@ pub struct ReentrantMutex {
}
impl ReentrantMutex {
#[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn
pub const fn uninitialized() -> ReentrantMutex {
ReentrantMutex {
inner: SpinMutex::new(WaitVariable::new(ReentrantLock { owner: None, count: 0 }))

View File

@ -21,7 +21,6 @@ pub struct RWLock {
//unsafe impl Sync for RWLock {} // FIXME
impl RWLock {
#[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> RWLock {
RWLock {
readers: SpinMutex::new(WaitVariable::new(None)),

View File

@ -50,7 +50,6 @@ pub struct WaitVariable<T> {
}
impl<T> WaitVariable<T> {
#[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new(var: T) -> Self {
WaitVariable {
queue: WaitQueue::new(),
@ -137,7 +136,6 @@ impl<'a, T> Drop for WaitGuard<'a, T> {
}
impl WaitQueue {
#[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> Self {
WaitQueue {
inner: UnsafeList::new()
@ -255,7 +253,6 @@ mod unsafe_list {
}
impl<T> UnsafeList<T> {
#[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> Self {
unsafe {
UnsafeList {

View File

@ -25,7 +25,6 @@ impl Condvar {
///
/// Behavior is undefined if the condition variable is moved after it is
/// first used with any of the functions below.
#[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> Condvar { Condvar(imp::Condvar::new()) }
/// Prepares the condition variable for use.

View File

@ -27,7 +27,6 @@ impl Mutex {
/// Also, until `init` is called, behavior is undefined if this
/// mutex is ever used reentrantly, i.e., `raw_lock` or `try_lock`
/// are called by the thread currently holding the lock.
#[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> Mutex { Mutex(imp::Mutex::new()) }
/// Prepare the mutex for use.

View File

@ -22,7 +22,6 @@ impl RWLock {
///
/// Behavior is undefined if the reader-writer lock is moved after it is
/// first used with any of the functions below.
#[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn
pub const fn new() -> RWLock { RWLock(imp::RWLock::new()) }
/// Acquires shared access to the underlying lock, blocking the current

View File

@ -15,7 +15,7 @@ use ast::{self, CrateConfig, NodeId};
use early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
use source_map::{SourceMap, FilePathMapping};
use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
use errors::{Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
use feature_gate::UnstableFeatures;
use parse::parser::Parser;
use ptr::P;
@ -192,6 +192,14 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a>
source_file_to_parser(sess, file_to_source_file(sess, path, None))
}
/// Create a new parser, returning buffered diagnostics if the file doesn't
/// exist or from lexing the initial token stream.
pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path)
-> Result<Parser<'a>, Vec<Diagnostic>> {
let file = try_file_to_source_file(sess, path, None).map_err(|db| vec![db])?;
maybe_source_file_to_parser(sess, file)
}
/// Given a session, a crate config, a path, and a span, add
/// the file at the given path to the source_map, and return a parser.
/// On an error, use the given span as the source of the problem.
@ -236,18 +244,31 @@ pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec<TokenTree>) -> Parser {
// base abstractions
/// Given a session and a path and an optional span (for error reporting),
/// add the path to the session's source_map and return the new source_file or
/// error when a file can't be read.
fn try_file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
-> Result<Lrc<SourceFile>, Diagnostic> {
sess.source_map().load_file(path)
.map_err(|e| {
let msg = format!("couldn't read {}: {}", path.display(), e);
let mut diag = Diagnostic::new(Level::Fatal, &msg);
if let Some(sp) = spanopt {
diag.set_span(sp);
}
diag
})
}
/// Given a session and a path and an optional span (for error reporting),
/// add the path to the session's source_map and return the new source_file.
fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
-> Lrc<SourceFile> {
match sess.source_map().load_file(path) {
match try_file_to_source_file(sess, path, spanopt) {
Ok(source_file) => source_file,
Err(e) => {
let msg = format!("couldn't read {}: {}", path.display(), e);
match spanopt {
Some(sp) => sess.span_diagnostic.span_fatal(sp, &msg).raise(),
None => sess.span_diagnostic.fatal(&msg).raise()
}
Err(d) => {
DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, d).emit();
FatalError.raise();
}
}
}

View File

@ -207,6 +207,10 @@ pub enum Token {
Eof,
}
// `Token` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert!(MEM_SIZE_OF_STATEMENT: mem::size_of::<Token>() == 16);
impl Token {
pub fn interpolated(nt: Nonterminal) -> Token {
Token::Interpolated(Lrc::new((nt, LazyTokenStream::new())))

View File

@ -24,10 +24,13 @@
#![feature(nll)]
#![feature(non_exhaustive)]
#![feature(optin_builtin_traits)]
#![feature(rustc_attrs)]
#![feature(specialization)]
#![feature(step_trait)]
#![cfg_attr(not(stage0), feature(stdsimd))]
extern crate arena;
#[macro_use]
extern crate rustc_data_structures;
#[macro_use]

View File

@ -14,6 +14,7 @@
use arena::DroplessArena;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fmt;
@ -143,9 +144,18 @@ impl Decodable for Ident {
}
}
/// A symbol is an interned or gensymed string.
/// A symbol is an interned or gensymed string. The use of newtype_index! means
/// that Option<Symbol> only takes up 4 bytes, because newtype_index! reserves
/// the last 256 values for tagging purposes.
///
/// Note that Symbol cannot be a newtype_index! directly because it implements
/// fmt::Debug, Encodable, and Decodable in special ways.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Symbol(u32);
pub struct Symbol(SymbolIndex);
newtype_index! {
pub struct SymbolIndex { .. }
}
// The interner is pointed to by a thread local value which is only set on the main thread
// with parallelization is disabled. So we don't allow `Symbol` to transfer between threads
@ -156,6 +166,10 @@ impl !Send for Symbol { }
impl !Sync for Symbol { }
impl Symbol {
const fn new(n: u32) -> Self {
Symbol(SymbolIndex::from_u32_const(n))
}
/// Maps a string to its interned representation.
pub fn intern(string: &str) -> Self {
with_interner(|interner| interner.intern(string))
@ -189,7 +203,7 @@ impl Symbol {
}
pub fn as_u32(self) -> u32 {
self.0
self.0.as_u32()
}
}
@ -197,7 +211,7 @@ impl fmt::Debug for Symbol {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let is_gensymed = with_interner(|interner| interner.is_gensymed(*self));
if is_gensymed {
write!(f, "{}({})", self, self.0)
write!(f, "{}({:?})", self, self.0)
} else {
write!(f, "{}", self)
}
@ -229,6 +243,9 @@ impl<T: ::std::ops::Deref<Target=str>> PartialEq<T> for Symbol {
}
// The `&'static str`s in this type actually point into the arena.
//
// Note that normal symbols are indexed upward from 0, and gensyms are indexed
// downward from SymbolIndex::MAX_AS_U32.
#[derive(Default)]
pub struct Interner {
arena: DroplessArena,
@ -243,7 +260,7 @@ impl Interner {
for &string in init {
if string == "" {
// We can't allocate empty strings in the arena, so handle this here.
let name = Symbol(this.strings.len() as u32);
let name = Symbol::new(this.strings.len() as u32);
this.names.insert("", name);
this.strings.push("");
} else {
@ -258,7 +275,7 @@ impl Interner {
return name;
}
let name = Symbol(self.strings.len() as u32);
let name = Symbol::new(self.strings.len() as u32);
// `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
// UTF-8.
@ -276,10 +293,10 @@ impl Interner {
}
pub fn interned(&self, symbol: Symbol) -> Symbol {
if (symbol.0 as usize) < self.strings.len() {
if (symbol.0.as_usize()) < self.strings.len() {
symbol
} else {
self.interned(self.gensyms[(!0 - symbol.0) as usize])
self.interned(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize])
}
}
@ -290,17 +307,17 @@ impl Interner {
fn gensymed(&mut self, symbol: Symbol) -> Symbol {
self.gensyms.push(symbol);
Symbol(!0 - self.gensyms.len() as u32 + 1)
Symbol::new(SymbolIndex::MAX_AS_U32 - self.gensyms.len() as u32 + 1)
}
fn is_gensymed(&mut self, symbol: Symbol) -> bool {
symbol.0 as usize >= self.strings.len()
symbol.0.as_usize() >= self.strings.len()
}
pub fn get(&self, symbol: Symbol) -> &str {
match self.strings.get(symbol.0 as usize) {
match self.strings.get(symbol.0.as_usize()) {
Some(string) => string,
None => self.get(self.gensyms[(!0 - symbol.0) as usize]),
None => self.get(self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]),
}
}
}
@ -324,7 +341,7 @@ macro_rules! declare_keywords {(
$(
#[allow(non_upper_case_globals)]
pub const $konst: Keyword = Keyword {
ident: Ident::with_empty_ctxt(super::Symbol($index))
ident: Ident::with_empty_ctxt(super::Symbol::new($index))
};
)*
@ -709,19 +726,19 @@ mod tests {
fn interner_tests() {
let mut i: Interner = Interner::default();
// first one is zero:
assert_eq!(i.intern("dog"), Symbol(0));
assert_eq!(i.intern("dog"), Symbol::new(0));
// re-use gets the same entry:
assert_eq!(i.intern("dog"), Symbol(0));
assert_eq!(i.intern("dog"), Symbol::new(0));
// different string gets a different #:
assert_eq!(i.intern("cat"), Symbol(1));
assert_eq!(i.intern("cat"), Symbol(1));
assert_eq!(i.intern("cat"), Symbol::new(1));
assert_eq!(i.intern("cat"), Symbol::new(1));
// dog is still at zero
assert_eq!(i.intern("dog"), Symbol(0));
assert_eq!(i.gensym("zebra"), Symbol(4294967295));
// gensym of same string gets new number :
assert_eq!(i.gensym("zebra"), Symbol(4294967294));
assert_eq!(i.intern("dog"), Symbol::new(0));
assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32));
// gensym of same string gets new number:
assert_eq!(i.gensym("zebra"), Symbol::new(SymbolIndex::MAX_AS_U32 - 1));
// gensym of *existing* string gets new number:
assert_eq!(i.gensym("dog"), Symbol(4294967293));
assert_eq!(i.gensym("dog"), Symbol::new(SymbolIndex::MAX_AS_U32 - 2));
}
#[test]

View File

@ -19,12 +19,17 @@
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
#[repr(simd)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
#[repr(simd)]
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct b8x4(pub i8, pub i8, pub i8, pub i8);
extern "platform-intrinsic" {
fn simd_select<T, U>(x: T, a: U, b: U) -> U;
fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
}
// CHECK-LABEL: @select
@ -33,3 +38,10 @@ pub unsafe fn select(m: b8x4, a: f32x4, b: f32x4) -> f32x4 {
// CHECK: select <4 x i1>
simd_select(m, a, b)
}
// CHECK-LABEL: @select_bitmask
#[no_mangle]
pub unsafe fn select_bitmask(m: i8, a: f32x8, b: f32x8) -> f32x8 {
// CHECK: select <8 x i1>
simd_select_bitmask(m, a, b)
}

View File

@ -13,7 +13,11 @@
// ignore-freebsd: gdb package too new
// ignore-android: FIXME(#10381)
// compile-flags:-g
// min-gdb-version 7.7
// The pretty printers being tested here require the patch from
// https://sourceware.org/bugzilla/show_bug.cgi?id=21763
// min-gdb-version 8.1
// min-lldb-version: 310
// === GDB TESTS ===================================================================================

View File

@ -2,7 +2,7 @@
{ "type": "test", "event": "started", "name": "a" }
{ "type": "test", "name": "a", "event": "ok" }
{ "type": "test", "event": "started", "name": "b" }
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:18:5\nnote: Run with `RUST_BACKTRACE=1` for a backtrace.\n" }
{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:18:5\nnote: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
{ "type": "test", "event": "started", "name": "c" }
{ "type": "test", "name": "c", "event": "ok" }
{ "type": "test", "event": "started", "name": "d" }

View File

@ -17,7 +17,8 @@ fn check_for_no_backtrace(test: std::process::Output) {
let mut it = err.lines();
assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked at")), Some(true));
assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` for a backtrace."));
assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` \
environment variable to display a backtrace."));
assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true));
assert_eq!(it.next(), None);
}

View File

@ -26,6 +26,10 @@ struct i32x4(pub i32, pub i32, pub i32, pub i32);
#[derive(Copy, Clone, PartialEq, Debug)]
struct u32x4(pub u32, pub u32, pub u32, pub u32);
#[repr(simd)]
#[derive(Copy, Clone, PartialEq, Debug)]
struct u32x8(u32, u32, u32, u32, u32, u32, u32, u32);
#[repr(simd)]
#[derive(Copy, Clone, PartialEq, Debug)]
struct f32x4(pub f32, pub f32, pub f32, pub f32);
@ -36,6 +40,7 @@ struct b8x4(pub i8, pub i8, pub i8, pub i8);
extern "platform-intrinsic" {
fn simd_select<T, U>(x: T, a: U, b: U) -> U;
fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
}
fn main() {
@ -146,4 +151,29 @@ fn main() {
let e = b8x4(t, f, t, t);
assert_eq!(r, e);
}
unsafe {
let a = u32x8(0, 1, 2, 3, 4, 5, 6, 7);
let b = u32x8(8, 9, 10, 11, 12, 13, 14, 15);
let r: u32x8 = simd_select_bitmask(0u8, a, b);
let e = b;
assert_eq!(r, e);
let r: u32x8 = simd_select_bitmask(0xffu8, a, b);
let e = a;
assert_eq!(r, e);
let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b);
let e = u32x8(0, 9, 2, 11, 4, 13, 6, 15);
assert_eq!(r, e);
let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b);
let e = u32x8(8, 1, 10, 3, 12, 5, 14, 7);
assert_eq!(r, e);
let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b);
let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7);
assert_eq!(r, e);
}
}

View File

@ -13,13 +13,13 @@ error[E0425]: cannot find value `no` in this scope
| ^^ not found in this scope
thread '$DIR/failed-doctest-output.rs - OtherStruct (line 27)' panicked at 'couldn't compile the test', src/librustdoc/test.rs:326:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
---- $DIR/failed-doctest-output.rs - SomeStruct (line 21) stdout ----
thread '$DIR/failed-doctest-output.rs - SomeStruct (line 21)' panicked at 'test executable failed:
thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
', src/librustdoc/test.rs:361:17

View File

@ -61,3 +61,16 @@ pub fn some_proc_attr(_attr: TokenStream, item: TokenStream) -> TokenStream {
pub fn some_derive(_item: TokenStream) -> TokenStream {
TokenStream::new()
}
// @has some_macros/foo/index.html
pub mod foo {
// @has - '//code' 'pub use some_proc_macro;'
// @has - '//a/@href' '../../some_macros/macro.some_proc_macro.html'
pub use some_proc_macro;
// @has - '//code' 'pub use some_proc_attr;'
// @has - '//a/@href' '../../some_macros/attr.some_proc_attr.html'
pub use some_proc_attr;
// @has - '//code' 'pub use some_derive;'
// @has - '//a/@href' '../../some_macros/derive.SomeDerive.html'
pub use some_derive;
}

View File

@ -0,0 +1,8 @@
// run-pass
fn main() {
let -2147483648..=2147483647 = 1;
let 0..=255 = 0u8;
let -128..=127 = 0i8;
let '\u{0000}'..='\u{10FFFF}' = 'v';
}

View File

@ -33,6 +33,7 @@ struct b8x8(pub i8, pub i8, pub i8, pub i8,
extern "platform-intrinsic" {
fn simd_select<T, U>(x: T, a: U, b: U) -> U;
fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
}
fn main() {
@ -52,5 +53,14 @@ fn main() {
simd_select(z, z, z);
//~^ ERROR mask element type is `f32`, expected `i_`
simd_select_bitmask(0u8, x, x);
//~^ ERROR mask length `8` != other vector length `4`
simd_select_bitmask(0.0f32, x, x);
//~^ ERROR `f32` is not an integral type
simd_select_bitmask("x", x, x);
//~^ ERROR `&str` is not an integral type
}
}

View File

@ -1,21 +1,39 @@
error[E0511]: invalid monomorphization of `simd_select` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
--> $DIR/simd-intrinsic-generic-select.rs:47:9
--> $DIR/simd-intrinsic-generic-select.rs:48:9
|
LL | simd_select(m8, x, x);
| ^^^^^^^^^^^^^^^^^^^^^
error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `u32`, expected `i_`
--> $DIR/simd-intrinsic-generic-select.rs:50:9
--> $DIR/simd-intrinsic-generic-select.rs:51:9
|
LL | simd_select(x, x, x);
| ^^^^^^^^^^^^^^^^^^^^
error[E0511]: invalid monomorphization of `simd_select` intrinsic: mask element type is `f32`, expected `i_`
--> $DIR/simd-intrinsic-generic-select.rs:53:9
--> $DIR/simd-intrinsic-generic-select.rs:54:9
|
LL | simd_select(z, z, z);
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `8` != other vector length `4`
--> $DIR/simd-intrinsic-generic-select.rs:57:9
|
LL | simd_select_bitmask(0u8, x, x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `f32` is not an integral type
--> $DIR/simd-intrinsic-generic-select.rs:60:9
|
LL | simd_select_bitmask(0.0f32, x, x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: `&str` is not an integral type
--> $DIR/simd-intrinsic-generic-select.rs:63:9
|
LL | simd_select_bitmask("x", x, x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0511`.