From 86822eb9404382eb82404a2c7b9193980fdd5296 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 7 Dec 2018 13:51:03 -0500 Subject: [PATCH 01/17] Unconditionally emit the target-cpu LLVM attribute. --- src/librustc_codegen_llvm/attributes.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 38ab1302cfa7c..c919335cd4e1c 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -18,6 +18,7 @@ use rustc::session::config::Sanitizer; use rustc::ty::TyCtxt; 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; @@ -129,8 +130,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator { } 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, @@ -220,11 +220,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()) From 0bb075f5a512affd6f5bb6a573e8b0188e6c0132 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Sat, 8 Dec 2018 18:27:12 +0000 Subject: [PATCH 02/17] rustdoc: Fix local reexports of proc macros Filter out `ProcMacroStub`s to avoid an ICE during cleaning. Also add proc macros to `cache().paths` so it can generate links. --- src/librustdoc/html/render.rs | 3 ++- src/librustdoc/visit_ast.rs | 7 ++++--- src/test/rustdoc/proc-macro.rs | 13 +++++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 8d7942a14669c..6ce9ace587ad5 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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, diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 004be1cfe39c4..287984cc5fac5 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -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, _ => {} } diff --git a/src/test/rustdoc/proc-macro.rs b/src/test/rustdoc/proc-macro.rs index 23d0d00580731..05d64f82fbdb8 100644 --- a/src/test/rustdoc/proc-macro.rs +++ b/src/test/rustdoc/proc-macro.rs @@ -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; +} From 85b50d03120cf7bd1beb472a78ce9427c0d8d06e Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Sun, 9 Dec 2018 22:53:00 +0100 Subject: [PATCH 03/17] Add missing, non-panicking `maybe_new_parser_from_file` variant --- src/libsyntax/parse/mod.rs | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 866dba24dcb0a..0fda08db67d6a 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -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, Vec> { + 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) -> 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) + -> Result, 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) -> Lrc { - 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(); } } } From 771e8b82af5921c52f2f6074196002f8a951f596 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Mon, 10 Dec 2018 21:16:19 -0500 Subject: [PATCH 04/17] [self-profiler] Add column for percent of total time --- src/librustc/util/profiling.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index 1e648c4581733..c2bfa62cf9d06 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -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(); )* } From 799cadb2bd980d1bcdcc831c2d0e50ec3b27527b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 11 Dec 2018 10:32:39 +0100 Subject: [PATCH 05/17] Remove unnecessary feature gates from const fns --- src/libstd/io/lazy.rs | 1 - src/libstd/lib.rs | 1 + src/libstd/sys/sgx/condvar.rs | 1 - src/libstd/sys/sgx/mutex.rs | 2 -- src/libstd/sys/sgx/rwlock.rs | 1 - src/libstd/sys/sgx/waitqueue.rs | 3 --- src/libstd/sys_common/condvar.rs | 1 - src/libstd/sys_common/mutex.rs | 1 - src/libstd/sys_common/rwlock.rs | 1 - 9 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs index c2aaeb9890745..24965ff693184 100644 --- a/src/libstd/io/lazy.rs +++ b/src/libstd/io/lazy.rs @@ -26,7 +26,6 @@ const fn done() -> *mut Arc { 1_usize as *mut _ } unsafe impl Sync for Lazy {} impl Lazy { - #[unstable(feature = "sys_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Lazy { Lazy { lock: Mutex::new(), diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 90c8eaf0f7cbc..1feb6f268fa0f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -271,6 +271,7 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] +#![feature(min_const_unsafe_fn)] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs index d3e8165f3dfe7..940f50f25b81a 100644 --- a/src/libstd/sys/sgx/condvar.rs +++ b/src/libstd/sys/sgx/condvar.rs @@ -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(())) } } diff --git a/src/libstd/sys/sgx/mutex.rs b/src/libstd/sys/sgx/mutex.rs index 663361162bc6b..994cf91eea0cd 100644 --- a/src/libstd/sys/sgx/mutex.rs +++ b/src/libstd/sys/sgx/mutex.rs @@ -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 })) diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 7b6970b825f93..a1551dbb53b2d 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -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)), diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs index ec1135ba30c4b..ef0def13eee88 100644 --- a/src/libstd/sys/sgx/waitqueue.rs +++ b/src/libstd/sys/sgx/waitqueue.rs @@ -50,7 +50,6 @@ pub struct WaitVariable { } impl WaitVariable { - #[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 UnsafeList { - #[unstable(feature = "sgx_internals", issue = "0")] // FIXME: min_const_fn pub const fn new() -> Self { unsafe { UnsafeList { diff --git a/src/libstd/sys_common/condvar.rs b/src/libstd/sys_common/condvar.rs index 16bf0803a8dfe..b6f29dd5fc3d3 100644 --- a/src/libstd/sys_common/condvar.rs +++ b/src/libstd/sys_common/condvar.rs @@ -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. diff --git a/src/libstd/sys_common/mutex.rs b/src/libstd/sys_common/mutex.rs index 8768423763898..c6d531c7a1ac5 100644 --- a/src/libstd/sys_common/mutex.rs +++ b/src/libstd/sys_common/mutex.rs @@ -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. diff --git a/src/libstd/sys_common/rwlock.rs b/src/libstd/sys_common/rwlock.rs index a430c254d3c58..71a4f01ec4cab 100644 --- a/src/libstd/sys_common/rwlock.rs +++ b/src/libstd/sys_common/rwlock.rs @@ -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 From 134661917bf4b086b027a2c58219d50ba57a1453 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 11 Dec 2018 10:33:17 +0100 Subject: [PATCH 06/17] Remove some dead code from `sgx` --- src/libstd/sys/sgx/abi/mem.rs | 7 ------- src/libstd/sys/sgx/abi/usercalls/mod.rs | 8 -------- 2 files changed, 15 deletions(-) diff --git a/src/libstd/sys/sgx/abi/mem.rs b/src/libstd/sys/sgx/abi/mem.rs index 508f2ff4d4fa5..bf32c712216bc 100644 --- a/src/libstd/sys/sgx/abi/mem.rs +++ b/src/libstd/sys/sgx/abi/mem.rs @@ -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); diff --git a/src/libstd/sys/sgx/abi/usercalls/mod.rs b/src/libstd/sys/sgx/abi/usercalls/mod.rs index 2bc32c9fefbb7..d1d180e48251f 100644 --- a/src/libstd/sys/sgx/abi/usercalls/mod.rs +++ b/src/libstd/sys/sgx/abi/usercalls/mod.rs @@ -33,14 +33,6 @@ pub fn read(fd: Fd, buf: &mut [u8]) -> IoResult { } } -pub fn read_alloc(fd: Fd) -> IoResult> { - unsafe { - let mut userbuf = alloc::User::::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 { unsafe { let userbuf = alloc::User::new_from_enclave(buf); From 5457b19fe9ecc936129755005de439d44e27a4ec Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 11 Dec 2018 10:43:40 +0100 Subject: [PATCH 07/17] Properly stage new feature gates --- src/libstd/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 1feb6f268fa0f..a69ec76376aab 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -271,7 +271,7 @@ #![feature(libc)] #![feature(link_args)] #![feature(linkage)] -#![feature(min_const_unsafe_fn)] +#![cfg_attr(not(stage0), feature(min_const_unsafe_fn))] #![feature(needs_panic_runtime)] #![feature(never_type)] #![feature(nll)] From 510a9fffa2a03d7f4f589f3d43115f68506a657e Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 10 Dec 2018 23:28:54 +0000 Subject: [PATCH 08/17] Fix irrefutable matches on integer ranges --- src/librustc_mir/build/matches/simplify.rs | 34 ++++++++++++++++++- .../irrefutable-exhaustive-integer-binding.rs | 8 +++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index cfea357334fa8..328b330f762dc 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -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) } diff --git a/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs b/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs new file mode 100644 index 0000000000000..ff065882d96e2 --- /dev/null +++ b/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs @@ -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'; +} From 24031466b7f690c708c30164ab3b07bcc82b7f89 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Dec 2018 10:57:45 +0100 Subject: [PATCH 09/17] Remove unneeded extra chars to reduce search-index size --- src/librustdoc/html/markdown.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 00ca4fed2f4a0..2ffde297cc506 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -852,7 +852,11 @@ pub fn plain_summary_line(md: &str) -> String { s.push_str(&t); } } - s + if s.len() > 60 { + s.chars().take(60).collect::() + } else { + s + } } pub fn markdown_links(md: &str) -> Vec<(String, Option>)> { From 0f68749260d04b61dfe2b38dbc423aefe2914a58 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 11 Dec 2018 09:06:51 +1100 Subject: [PATCH 10/17] Use a `newtype_index!` within `Symbol`. This shrinks `Option` from 8 bytes to 4 bytes, which shrinks `Token` from 24 bytes to 16 bytes. This reduces instruction counts by up to 1% across a range of benchmarks. --- src/libsyntax/parse/token.rs | 4 +++ src/libsyntax_pos/lib.rs | 3 ++ src/libsyntax_pos/symbol.rs | 61 +++++++++++++++++++++++------------- 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 6b9cc2f9792e3..83763bd32d473 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -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::() == 16); + impl Token { pub fn interpolated(nt: Nonterminal) -> Token { Token::Interpolated(Lrc::new((nt, LazyTokenStream::new()))) diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index 8b7ffa499cd71..9aafb9fc549fc 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -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] diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 05c53878e7004..3d87134511e72 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -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 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> PartialEq 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] From cd7e891b15dbf65eec9cf32e854fa575d1b43950 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Wed, 12 Dec 2018 15:07:13 +0100 Subject: [PATCH 11/17] specialize: remove Boxes used by Children::insert --- .../traits/specialize/specialization_graph.rs | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 22221e0a3d93d..b0ca2f6cecc0b 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -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 + '_> { + fn iter(&mut self) -> impl Iterator + '_ { 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 + '_> { + fn filtered(&mut self, sty: SimplifiedType) -> impl Iterator + '_ { 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 + where I: Iterator, + J: Iterator +{ + Unfiltered(I), + Filtered(J) +} + +impl Iterator for PotentialSiblings + where I: Iterator, + J: Iterator +{ + type Item = DefId; + + fn next(&mut self) -> Option { + match *self { + PotentialSiblings::Unfiltered(ref mut iter) => iter.next(), + PotentialSiblings::Filtered(ref mut iter) => iter.next() + } } } From 8b67eb8116ead5e87a8f799ac3663c0697eb3194 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 6 Dec 2018 14:41:06 +0100 Subject: [PATCH 12/17] Increase required version for crates.io `libc` to get fix from PR rust-lang/libc#1057. Part of issue #55465 --- src/librustc_codegen_ssa/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 7b1c7cfb56f4c..50994497c2843 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -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" } From 78f20de075501126949c545a310fb921ab7b4c59 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 12 Dec 2018 08:37:56 -0800 Subject: [PATCH 13/17] x86: Add the `adx` target feature to whitelist Requested in rust-lang-nursery/stdsimd#322 this is hopefully the first step! --- src/librustc_codegen_llvm/llvm_util.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs index fdb6373bea1fe..12109ae1662ff 100644 --- a/src/librustc_codegen_llvm/llvm_util.rs +++ b/src/librustc_codegen_llvm/llvm_util.rs @@ -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), From 4007adfb6b9c5e7731dac188609784c3809c3713 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 12 Dec 2018 15:00:59 -0700 Subject: [PATCH 14/17] Disable btree pretty-printers on older gdbs gdb versions before 8.1 have a bug that prevents the BTreeSet and BTreeMap pretty-printers from working. This patch disables the test on those versions, and also disables the pretty-printers there as well. Closes #56730 --- src/etc/gdb_rust_pretty_printing.py | 15 +++++++++++++-- src/test/debuginfo/pretty-std-collections.rs | 6 +++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index a376c8593f4c0..f02c7d87590ac 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -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 @@ 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: diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index a51be370aa44b..350b30d2cc1cd 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -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 =================================================================================== From 987bf2ed29b591178ed4a520b295eb40e6328ba8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Dec 2018 22:29:40 +0100 Subject: [PATCH 15/17] Split on words instead --- src/librustdoc/html/markdown.rs | 18 ++++++++++++++++-- src/librustdoc/html/render.rs | 16 +++++++++++----- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 2ffde297cc506..536ea39d29805 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -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,8 +856,18 @@ pub fn plain_summary_line(md: &str) -> String { s.push_str(&t); } } - if s.len() > 60 { - s.chars().take(60).collect::() + 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::>() + .join(" "); + ret.push('…'); + ret } else { s } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 6158815fb9a51..00ef5e92aa885 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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(); @@ -1487,7 +1487,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), @@ -1679,7 +1679,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), @@ -2396,7 +2396,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 { From 5087aef79202e9f1411a0d0a0a74b0e63643a118 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 13 Dec 2018 12:50:42 -0800 Subject: [PATCH 16/17] rustc: Add an unstable `simd_select_bitmask` intrinsic This is going to be required for binding a number of AVX-512 intrinsics in the `stdsimd` repository, and this intrinsic is the same as `simd_select` except that it takes a bitmask as the first argument instead of a SIMD vector. This bitmask is then transmuted into a `` argument, depending on how many bits it is. cc rust-lang-nursery/stdsimd#310 --- src/librustc_codegen_llvm/intrinsic.rs | 21 +++++++++++++ src/librustc_typeck/check/intrinsic.rs | 3 +- .../codegen/simd-intrinsic-generic-select.rs | 12 ++++++++ .../simd/simd-intrinsic-generic-select.rs | 30 +++++++++++++++++++ .../simd-intrinsic-generic-select.rs | 10 +++++++ .../simd-intrinsic-generic-select.stderr | 26 +++++++++++++--- 6 files changed, 97 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 2b82ebe0bc25c..8b26ada157606 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -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]; diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 5c0eef5b1f332..a40e56d68ae8b 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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)), diff --git a/src/test/codegen/simd-intrinsic-generic-select.rs b/src/test/codegen/simd-intrinsic-generic-select.rs index 8a64d7437d84d..24a4b2b1b054f 100644 --- a/src/test/codegen/simd-intrinsic-generic-select.rs +++ b/src/test/codegen/simd-intrinsic-generic-select.rs @@ -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(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(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) +} diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs b/src/test/run-pass/simd/simd-intrinsic-generic-select.rs index 590a2990270dc..74b99ca495081 100644 --- a/src/test/run-pass/simd/simd-intrinsic-generic-select.rs +++ b/src/test/run-pass/simd/simd-intrinsic-generic-select.rs @@ -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(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(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); + } } diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs index d74d6815d5f5e..2a2d35e7bd922 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs @@ -33,6 +33,7 @@ struct b8x8(pub i8, pub i8, pub i8, pub i8, extern "platform-intrinsic" { fn simd_select(x: T, a: U, b: U) -> U; + fn simd_select_bitmask(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 } } diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr index 61e42027039dd..584f3d539213b 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr @@ -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`. From 6057147fde962f2369c61f8dbf74dd2b1b2ce239 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Wed, 12 Dec 2018 14:20:49 +0000 Subject: [PATCH 17/17] Update panic message to be clearer about env-vars Esteban Kuber requested that the panic message make it clear that `RUST_BACKTRACE=1` is an environment variable. This change makes that clear. Wording provided in part by David Tolnay. --- src/libstd/panicking.rs | 3 ++- src/test/run-make-fulldeps/libtest-json/output.json | 2 +- src/test/run-pass/multi-panic.rs | 3 ++- src/test/rustdoc-ui/failed-doctest-output.stdout | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 6b47ba6d1cb8f..b6180fbeb5068 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -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."); } } }; diff --git a/src/test/run-make-fulldeps/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output.json index 80e75c89bfc16..2b831ea2bdca4 100644 --- a/src/test/run-make-fulldeps/libtest-json/output.json +++ b/src/test/run-make-fulldeps/libtest-json/output.json @@ -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" } diff --git a/src/test/run-pass/multi-panic.rs b/src/test/run-pass/multi-panic.rs index 2e6e10935fa7a..03e58fc2387c7 100644 --- a/src/test/run-pass/multi-panic.rs +++ b/src/test/run-pass/multi-panic.rs @@ -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 '' 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); } diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index cd19099647c19..bd6fa1f84b468 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -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