From 3f5f54cd8bf73e7a271955582834fda9e707429d Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 28 Apr 2021 17:54:44 +0100 Subject: [PATCH 01/26] Update list of allowed aarch64 features These features were recently added to std_detect. Features not supported by LLVM 9, the current minimum version for Rust, are commented. --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 6 ++ .../rustc_codegen_ssa/src/target_features.rs | 77 ++++++++++++++++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index b44553e4f6d3..f0a2c91c0185 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -152,6 +152,12 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { ("x86", "avx512vpclmulqdq") => "vpclmulqdq", ("aarch64", "fp") => "fp-armv8", ("aarch64", "fp16") => "fullfp16", + ("aarch64", "fhm") => "fp16fml", + ("aarch64", "lse2") => "outline-atomics", + ("aarch64", "rcpc2") => "rcpc-immo", + ("aarch64", "dpb") => "ccpp", + ("aarch64", "dpb2") => "ccdp", + ("aarch64", "fcma") => "complxnum", (_, s) => s, } } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 4e987908b4ea..aa415754dadb 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -33,22 +33,95 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("thumb-mode", Some(sym::arm_target_feature)), ]; +// Commented features are not available in LLVM 9.0, or have since been renamed const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("fp", Some(sym::aarch64_target_feature)), + // FEAT_AdvSimd ("neon", Some(sym::aarch64_target_feature)), + // FEAT_FP + ("fp", Some(sym::aarch64_target_feature)), + // FEAT_FP16 + ("fp16", Some(sym::aarch64_target_feature)), + // FEAT_SVE ("sve", Some(sym::aarch64_target_feature)), + // FEAT_CRC ("crc", Some(sym::aarch64_target_feature)), + // Cryptographic extension ("crypto", Some(sym::aarch64_target_feature)), + // FEAT_RAS ("ras", Some(sym::aarch64_target_feature)), + // FEAT_LSE ("lse", Some(sym::aarch64_target_feature)), + // FEAT_LSE2 + // ("lse2", Some(sym::aarch64_target_feature)), + // FEAT_RDM ("rdm", Some(sym::aarch64_target_feature)), - ("fp16", Some(sym::aarch64_target_feature)), + // FEAT_RCPC ("rcpc", Some(sym::aarch64_target_feature)), + // FEAT_RCPC2 + ("rcpc2", Some(sym::aarch64_target_feature)), + // FEAT_DotProd ("dotprod", Some(sym::aarch64_target_feature)), + // FEAT_TME ("tme", Some(sym::aarch64_target_feature)), + // FEAT_FHM + ("fhm", Some(sym::aarch64_target_feature)), + // FEAT_DIT + ("dit", Some(sym::aarch64_target_feature)), + // FEAT_FLAGM + // ("flagm", Some(sym::aarch64_target_feature)), + // FEAT_SSBS + ("ssbs", Some(sym::aarch64_target_feature)), + // FEAT_SB + ("sb", Some(sym::aarch64_target_feature)), + // FEAT_PAUTH + // ("pauth", Some(sym::aarch64_target_feature)), + // FEAT_DPB + ("dpb", Some(sym::aarch64_target_feature)), + // FEAT_DPB2 + ("dpb2", Some(sym::aarch64_target_feature)), + // FEAT_SVE2 + ("sve2", Some(sym::aarch64_target_feature)), + // FEAT_SVE2_AES + ("sve2-aes", Some(sym::aarch64_target_feature)), + // FEAT_SVE2_SM4 + ("sve2-sm4", Some(sym::aarch64_target_feature)), + // FEAT_SVE2_SHA3 + ("sve2-sha3", Some(sym::aarch64_target_feature)), + // FEAT_SVE2_BitPerm + ("sve2-bitperm", Some(sym::aarch64_target_feature)), + // FEAT_FRINTTS + ("fptoint", Some(sym::aarch64_target_feature)), + // FEAT_I8MM + // ("i8mm", Some(sym::aarch64_target_feature)), + // FEAT_F32MM + // ("f32mm", Some(sym::aarch64_target_feature)), + // FEAT_F64MM + // ("f64mm", Some(sym::aarch64_target_feature)), + // FEAT_BF16 + // ("bf16", Some(sym::aarch64_target_feature)), + // FEAT_RAND + ("rand", Some(sym::aarch64_target_feature)), + // FEAT_BTI + ("bti", Some(sym::aarch64_target_feature)), + // FEAT_MTE + ("mte", Some(sym::aarch64_target_feature)), + // FEAT_JSCVT + ("jsconv", Some(sym::aarch64_target_feature)), + // FEAT_FCMA + ("fcma", Some(sym::aarch64_target_feature)), + // FEAT_SHA1 & FEAT_SHA256 + ("sha2", Some(sym::aarch64_target_feature)), + // FEAT_SHA512 & FEAT_SHA3 + ("sha3", Some(sym::aarch64_target_feature)), + // FEAT_SM3 & FEAT_SM4 + ("sm4", Some(sym::aarch64_target_feature)), ("v8.1a", Some(sym::aarch64_target_feature)), ("v8.2a", Some(sym::aarch64_target_feature)), ("v8.3a", Some(sym::aarch64_target_feature)), + ("v8.4a", Some(sym::aarch64_target_feature)), + ("v8.5a", Some(sym::aarch64_target_feature)), + // ("v8.6a", Some(sym::aarch64_target_feature)), + // ("v8.7a", Some(sym::aarch64_target_feature)), ]; const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[ From 5353c5c3fb7ebc4fb12ca3488c555ee3006c8325 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Fri, 14 May 2021 03:54:46 +0200 Subject: [PATCH 02/26] Move `std::memchr` to `sys_common` --- library/std/src/ffi/c_str.rs | 2 +- library/std/src/io/buffered/linewritershim.rs | 2 +- library/std/src/io/mod.rs | 2 +- library/std/src/lib.rs | 1 - library/std/src/sys/hermit/os.rs | 2 +- library/std/src/sys/unix/os.rs | 2 +- library/std/src/{ => sys_common}/memchr.rs | 6 ++++-- library/std/src/{ => sys_common}/memchr/tests.rs | 0 library/std/src/sys_common/mod.rs | 1 + 9 files changed, 10 insertions(+), 8 deletions(-) rename library/std/src/{ => sys_common}/memchr.rs (92%) rename library/std/src/{ => sys_common}/memchr/tests.rs (100%) diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 2f9845d7536c..a828a57fc8fb 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -10,7 +10,6 @@ use crate::error::Error; use crate::fmt::{self, Write}; use crate::io; use crate::mem; -use crate::memchr; use crate::num::NonZeroU8; use crate::ops; use crate::os::raw::c_char; @@ -20,6 +19,7 @@ use crate::slice; use crate::str::{self, Utf8Error}; use crate::sync::Arc; use crate::sys; +use crate::sys_common::memchr; /// A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the /// middle. diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs index d0c859d2e0c8..0175d2693e89 100644 --- a/library/std/src/io/buffered/linewritershim.rs +++ b/library/std/src/io/buffered/linewritershim.rs @@ -1,5 +1,5 @@ use crate::io::{self, BufWriter, IoSlice, Write}; -use crate::memchr; +use crate::sys_common::memchr; /// Private helper struct for implementing the line-buffered writing logic. /// This shim temporarily wraps a BufWriter, and uses its internals to diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 9f43379aff78..47a414fad391 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -253,12 +253,12 @@ mod tests; use crate::cmp; use crate::fmt; -use crate::memchr; use crate::ops::{Deref, DerefMut}; use crate::ptr; use crate::slice; use crate::str; use crate::sys; +use crate::sys_common::memchr; #[stable(feature = "rust1", since = "1.0.0")] pub use self::buffered::IntoInnerError; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 5f89ac059fd2..3b86025cbba3 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -530,7 +530,6 @@ mod sys; pub mod alloc; // Private support modules -mod memchr; mod panicking; // The runtime entry point and a few unstable public functions used by the diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index 81cd68a74e66..40bd393098f5 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -4,11 +4,11 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt; use crate::io; use crate::marker::PhantomData; -use crate::memchr; use crate::path::{self, PathBuf}; use crate::str; use crate::sync::Mutex; use crate::sys::hermit::abi; +use crate::sys::memchr; use crate::sys::unsupported; use crate::sys_common::os_str_bytes::*; use crate::vec; diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 51c3e5d175cc..bbc4691d963c 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -13,13 +13,13 @@ use crate::fmt; use crate::io; use crate::iter; use crate::mem; -use crate::memchr; use crate::path::{self, PathBuf}; use crate::ptr; use crate::slice; use crate::str; use crate::sys::cvt; use crate::sys::fd; +use crate::sys::memchr; use crate::sys::rwlock::{RWLockReadGuard, StaticRWLock}; use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard}; use crate::vec; diff --git a/library/std/src/memchr.rs b/library/std/src/sys_common/memchr.rs similarity index 92% rename from library/std/src/memchr.rs rename to library/std/src/sys_common/memchr.rs index 86a08f75a8d4..b219e8789126 100644 --- a/library/std/src/memchr.rs +++ b/library/std/src/sys_common/memchr.rs @@ -1,6 +1,8 @@ // Original implementation taken from rust-memchr. // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch +use crate::sys::memchr as sys; + #[cfg(test)] mod tests; @@ -25,7 +27,7 @@ mod tests; /// ``` #[inline] pub fn memchr(needle: u8, haystack: &[u8]) -> Option { - crate::sys::memchr::memchr(needle, haystack) + sys::memchr(needle, haystack) } /// A safe interface to `memrchr`. @@ -45,5 +47,5 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option { /// ``` #[inline] pub fn memrchr(needle: u8, haystack: &[u8]) -> Option { - crate::sys::memchr::memrchr(needle, haystack) + sys::memrchr(needle, haystack) } diff --git a/library/std/src/memchr/tests.rs b/library/std/src/sys_common/memchr/tests.rs similarity index 100% rename from library/std/src/memchr/tests.rs rename to library/std/src/sys_common/memchr/tests.rs diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 7fa6977f2af2..5d2136ae7448 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -25,6 +25,7 @@ pub mod bytestring; pub mod condvar; pub mod fs; pub mod io; +pub mod memchr; pub mod mutex; // `doc` is required because `sys/mod.rs` imports `unix/ext/mod.rs` on Windows // when generating documentation. From 67e8f1230745785bc08ec4d3d882f61b1d3516af Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 14 May 2021 13:28:56 +0100 Subject: [PATCH 03/26] Expose `Concurrent` (private type in public i'face) --- library/test/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 9adc099aaa56..bda5ed888d7e 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -49,7 +49,7 @@ pub mod test { cli::{parse_opts, TestOpts}, filter_tests, helpers::metrics::{Metric, MetricMap}, - options::{Options, RunIgnored, RunStrategy, ShouldPanic}, + options::{Concurrent, Options, RunIgnored, RunStrategy, ShouldPanic}, run_test, test_main, test_main_static, test_result::{TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk}, time::{TestExecTime, TestTimeOptions}, From f054ce394695ae8dc9cfa6db426bf1dbed483c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Mon, 17 May 2021 09:56:57 +0300 Subject: [PATCH 04/26] :arrow_up: rust-analyzer --- src/tools/rust-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index fd109fb58790..b82458818d44 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit fd109fb587904cfecc1149e068814bfd38feb83c +Subproject commit b82458818d44dfe5b4b5db38d8113e3f3194506e From 445658ba6d00ae8fbbd7705ec1b1cf19b92d1ad2 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Mon, 17 May 2021 14:12:38 -0400 Subject: [PATCH 05/26] PassWrapper: update for LLVM change D102093 In https://reviews.llvm.org/D102093 lots of things stopped taking the DebugLogging boolean parameter. Mercifully we appear to always set DebugPassManager to false, so I don't think we're losing anything by not passing this parameter. --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 65a988629c3b..3cbdd9598cc2 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -789,16 +789,23 @@ LLVMRustOptimizeWithNewPassManager( PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse); } -#if LLVM_VERSION_GE(12, 0) +#if LLVM_VERSION_GE(12, 0) && !LLVM_VERSION_GE(13,0) PassBuilder PB(DebugPassManager, TM, PTO, PGOOpt, &PIC); #else PassBuilder PB(TM, PTO, PGOOpt, &PIC); #endif +#if LLVM_VERSION_GE(13, 0) + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; +#else LoopAnalysisManager LAM(DebugPassManager); FunctionAnalysisManager FAM(DebugPassManager); CGSCCAnalysisManager CGAM(DebugPassManager); ModuleAnalysisManager MAM(DebugPassManager); +#endif FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); }); @@ -935,7 +942,11 @@ LLVMRustOptimizeWithNewPassManager( } } +#if LLVM_VERSION_GE(13, 0) + ModulePassManager MPM; +#else ModulePassManager MPM(DebugPassManager); +#endif bool NeedThinLTOBufferPasses = UseThinLTOBuffers; if (!NoPrepopulatePasses) { if (OptLevel == PassBuilder::OptimizationLevel::O0) { From d730cc66460c1cad2f7c5d1951a06666bb8b78de Mon Sep 17 00:00:00 2001 From: Mateusz Gacek <96mateusz.gacek@gmail.com> Date: Tue, 18 May 2021 15:33:38 +0200 Subject: [PATCH 06/26] Add diagnostic item to `CStr` --- compiler/rustc_span/src/symbol.rs | 1 + library/std/src/ffi/c_str.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 03a8f2be1561..a5dc67854883 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -131,6 +131,7 @@ symbols! { BinaryHeap, Borrow, C, + CStr, CString, Center, Clone, diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 2f9845d7536c..302f12af6a0f 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -185,6 +185,7 @@ pub struct CString { /// /// [`&str`]: prim@str #[derive(Hash)] +#[cfg_attr(not(test), rustc_diagnostic_item = "CStr")] #[stable(feature = "rust1", since = "1.0.0")] // FIXME: // `fn from` in `impl From<&CStr> for Box` current implementation relies From 24480ded58c9867439cfabba4198e1877c1fd166 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Mon, 10 May 2021 16:41:41 -0700 Subject: [PATCH 07/26] Add method-toggle to
for methods. The makes the code for handling "auto-hide" settings more consistent. --- src/librustdoc/html/render/mod.rs | 9 ++++++--- src/librustdoc/html/static/main.js | 16 ++++------------ 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index a288b43722ad..318e1b44f868 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1352,8 +1352,11 @@ fn render_impl( } let w = if short_documented && trait_.is_some() { interesting } else { boring }; - if !doc_buffer.is_empty() { - w.write_str("
"); + let toggled = !doc_buffer.is_empty(); + if toggled { + let method_toggle_class = + if item_type == ItemType::Method { " method-toggle" } else { "" }; + write!(w, "
", method_toggle_class); } match *item.kind { clean::MethodItem(..) | clean::TyMethodItem(_) => { @@ -1453,7 +1456,7 @@ fn render_impl( } w.push_buffer(info_buffer); - if !doc_buffer.is_empty() { + if toggled { w.write_str(""); w.push_buffer(doc_buffer); w.push_str("
"); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 307ce9ac3752..83e6a529b0aa 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -924,24 +924,16 @@ function hideThemeButtonState() { }); } - if (hideMethodDocs) { - onEachLazy(document.getElementsByClassName("method"), function(e) { - var toggle = e.parentNode; - if (toggle) { - toggle = toggle.parentNode; - } - if (toggle && toggle.tagName === "DETAILS") { - toggle.open = false; - } - }); - } - onEachLazy(document.getElementsByTagName("details"), function (e) { var showLargeItem = !hideLargeItemContents && hasClass(e, "type-contents-toggle"); var showImplementor = !hideImplementors && hasClass(e, "implementors-toggle"); if (showLargeItem || showImplementor) { e.open = true; } + if (hideMethodDocs && hasClass(e, "method-toggle")) { + e.open = false; + } + }); var currentType = document.getElementsByClassName("type-decl")[0]; From f9752b493086fd3063c9aef83d2622d322bbc51c Mon Sep 17 00:00:00 2001 From: Frank Steffahn Date: Wed, 19 May 2021 12:33:10 +0200 Subject: [PATCH 08/26] Fix UB in documented example for `ptr::swap` --- library/core/src/ptr/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 2c324b15a1a1..214d7c8bc156 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -342,10 +342,12 @@ pub const fn slice_from_raw_parts_mut(data: *mut T, len: usize) -> *mut [T] { /// ``` /// use std::ptr; /// -/// let mut array = [0, 1, 2, 3]; +/// let mut array: [i32; 4] = [0, 1, 2, 3]; +/// +/// let array_ptr: *mut i32 = array.as_mut_ptr(); /// -/// let x = array[0..].as_mut_ptr() as *mut [u32; 3]; // this is `array[0..3]` -/// let y = array[1..].as_mut_ptr() as *mut [u32; 3]; // this is `array[1..4]` +/// let x = array_ptr as *mut [i32; 3]; // this is `array[0..3]` +/// let y = unsafe { array_ptr.add(1) } as *mut [i32; 3]; // this is `array[1..4]` /// /// unsafe { /// ptr::swap(x, y); From 5b0908587e5e549051bcc6294b034049421de4f8 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Thu, 29 Apr 2021 15:57:05 +0200 Subject: [PATCH 09/26] Introduce `sys_common::rt::rterr!` --- library/std/src/sys_common/rt.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys_common/rt.rs b/library/std/src/sys_common/rt.rs index c70f2ecc04e3..9ce6aa7c3696 100644 --- a/library/std/src/sys_common/rt.rs +++ b/library/std/src/sys_common/rt.rs @@ -1,4 +1,5 @@ #![deny(unsafe_op_in_unsafe_fn)] +#![allow(unused_macros)] use crate::sync::Once; use crate::sys; @@ -38,6 +39,14 @@ pub fn cleanup() { }); } +macro_rules! rterr { + ($($t:tt)*) => { + if let Some(mut out) = crate::sys::stdio::panic_output() { + let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*)); + } + } +} + macro_rules! rtabort { ($($t:tt)*) => (crate::sys_common::util::abort(format_args!($($t)*))) } @@ -50,7 +59,6 @@ macro_rules! rtassert { }; } -#[allow(unused_macros)] // not used on all platforms macro_rules! rtunwrap { ($ok:ident, $e:expr) => { match $e { From b987f74f05b3fbeb81eed27c43678dc71cdab8cf Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Thu, 29 Apr 2021 15:59:05 +0200 Subject: [PATCH 10/26] Remove `sys_common::util::abort` --- library/std/src/sys_common/rt.rs | 7 ++++++- library/std/src/sys_common/util.rs | 10 ---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/library/std/src/sys_common/rt.rs b/library/std/src/sys_common/rt.rs index 9ce6aa7c3696..e4c9b60594ef 100644 --- a/library/std/src/sys_common/rt.rs +++ b/library/std/src/sys_common/rt.rs @@ -48,7 +48,12 @@ macro_rules! rterr { } macro_rules! rtabort { - ($($t:tt)*) => (crate::sys_common::util::abort(format_args!($($t)*))) + ($($t:tt)*) => { + { + rterr!("fatal runtime error: {}\n", format_args!($($t)*)); + crate::sys::abort_internal(); + } + } } macro_rules! rtassert { diff --git a/library/std/src/sys_common/util.rs b/library/std/src/sys_common/util.rs index 9f7c3bd87952..b8cae26d04c5 100644 --- a/library/std/src/sys_common/util.rs +++ b/library/std/src/sys_common/util.rs @@ -9,16 +9,6 @@ pub fn dumb_print(args: fmt::Arguments<'_>) { } } -// Other platforms should use the appropriate platform-specific mechanism for -// aborting the process. If no platform-specific mechanism is available, -// crate::intrinsics::abort() may be used instead. The above implementations cover -// all targets currently supported by libstd. - -pub fn abort(args: fmt::Arguments<'_>) -> ! { - dumb_print(format_args!("fatal runtime error: {}\n", args)); - crate::sys::abort_internal(); -} - #[allow(dead_code)] // stack overflow detection not enabled on all platforms pub unsafe fn report_overflow() { dumb_print(format_args!( From 236705f3c30905623f97dc8887c83db520eb27c1 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Thu, 29 Apr 2021 16:05:10 +0200 Subject: [PATCH 11/26] Replace `sys_common::util::report_overflow` with `rterr!` --- library/std/src/sys/unix/stack_overflow.rs | 8 +++++--- library/std/src/sys/windows/stack_overflow.rs | 7 +++++-- library/std/src/sys_common/util.rs | 9 --------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs index 2a487fff54ae..72fd48278bc1 100644 --- a/library/std/src/sys/unix/stack_overflow.rs +++ b/library/std/src/sys/unix/stack_overflow.rs @@ -42,6 +42,7 @@ mod imp { use crate::io; use crate::mem; use crate::ptr; + use crate::thread; use libc::MAP_FAILED; use libc::{mmap, munmap}; @@ -95,15 +96,16 @@ mod imp { info: *mut libc::siginfo_t, _data: *mut libc::c_void, ) { - use crate::sys_common::util::report_overflow; - let guard = thread_info::stack_guard().unwrap_or(0..0); let addr = siginfo_si_addr(info); // If the faulting address is within the guard page, then we print a // message saying so and abort. if guard.start <= addr && addr < guard.end { - report_overflow(); + rterr!( + "\nthread '{}' has overflowed its stack\n", + thread::current().name().unwrap_or("") + ); rtabort!("stack overflow"); } else { // Unregister ourselves by reverting back to the default behavior. diff --git a/library/std/src/sys/windows/stack_overflow.rs b/library/std/src/sys/windows/stack_overflow.rs index 39efb778207f..24ba35ad17e6 100644 --- a/library/std/src/sys/windows/stack_overflow.rs +++ b/library/std/src/sys/windows/stack_overflow.rs @@ -1,7 +1,7 @@ #![cfg_attr(test, allow(dead_code))] use crate::sys::c; -use crate::sys_common::util::report_overflow; +use crate::thread; pub struct Handler; @@ -24,7 +24,10 @@ extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) - let code = rec.ExceptionCode; if code == c::EXCEPTION_STACK_OVERFLOW { - report_overflow(); + rterr!( + "\nthread '{}' has overflowed its stack\n", + thread::current().name().unwrap_or("") + ); } c::EXCEPTION_CONTINUE_SEARCH } diff --git a/library/std/src/sys_common/util.rs b/library/std/src/sys_common/util.rs index b8cae26d04c5..f7072cc50110 100644 --- a/library/std/src/sys_common/util.rs +++ b/library/std/src/sys_common/util.rs @@ -1,18 +1,9 @@ use crate::fmt; use crate::io::prelude::*; use crate::sys::stdio::panic_output; -use crate::thread; pub fn dumb_print(args: fmt::Arguments<'_>) { if let Some(mut out) = panic_output() { let _ = out.write_fmt(args); } } - -#[allow(dead_code)] // stack overflow detection not enabled on all platforms -pub unsafe fn report_overflow() { - dumb_print(format_args!( - "\nthread '{}' has overflowed its stack\n", - thread::current().name().unwrap_or("") - )); -} From 6145051eeebeba030cef3aa01a99683b84ff24fc Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Thu, 29 Apr 2021 16:10:32 +0200 Subject: [PATCH 12/26] Replace `sys_common::util::dumb_print` with `rterr!` --- library/std/src/alloc.rs | 4 +--- library/std/src/panicking.rs | 10 +++++----- library/std/src/sys_common/mod.rs | 1 - library/std/src/sys_common/util.rs | 9 --------- 4 files changed, 6 insertions(+), 18 deletions(-) delete mode 100644 library/std/src/sys_common/util.rs diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 843ef09a5842..9e9052ff92e1 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -63,8 +63,6 @@ use core::ptr::NonNull; use core::sync::atomic::{AtomicPtr, Ordering}; use core::{mem, ptr}; -use crate::sys_common::util::dumb_print; - #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] pub use alloc_crate::alloc::*; @@ -317,7 +315,7 @@ pub fn take_alloc_error_hook() -> fn(Layout) { } fn default_alloc_error_hook(layout: Layout) { - dumb_print(format_args!("memory allocation of {} bytes failed\n", layout.size())); + rterr!("memory allocation of {} bytes failed\n", layout.size()); } #[cfg(not(test))] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a8410bea7342..909115151857 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -20,7 +20,7 @@ use crate::sync::atomic::{AtomicBool, Ordering}; use crate::sys::stdio::panic_output; use crate::sys_common::backtrace::{self, RustBacktrace}; use crate::sys_common::rwlock::RWLock; -use crate::sys_common::{thread_info, util}; +use crate::sys_common::thread_info; use crate::thread; #[cfg(not(test))] @@ -596,15 +596,15 @@ fn rust_panic_with_hook( if panics > 2 { // Don't try to print the message in this case // - perhaps that is causing the recursive panics. - util::dumb_print(format_args!("thread panicked while processing panic. aborting.\n")); + rterr!("thread panicked while processing panic. aborting.\n"); } else { // Unfortunately, this does not print a backtrace, because creating // a `Backtrace` will allocate, which we must to avoid here. let panicinfo = PanicInfo::internal_constructor(message, location); - util::dumb_print(format_args!( + rterr!( "{}\npanicked after panic::always_abort(), aborting.\n", panicinfo - )); + ); } intrinsics::abort() } @@ -637,7 +637,7 @@ fn rust_panic_with_hook( // have limited options. Currently our preference is to // just abort. In the future we may consider resuming // unwinding or otherwise exiting the thread cleanly. - util::dumb_print(format_args!("thread panicked while panicking. aborting.\n")); + rterr!("thread panicked while panicking. aborting.\n"); intrinsics::abort() } diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 7fa6977f2af2..4ef0e72adf02 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -40,7 +40,6 @@ pub mod thread_info; pub mod thread_local_dtor; pub mod thread_local_key; pub mod thread_parker; -pub mod util; pub mod wtf8; cfg_if::cfg_if! { diff --git a/library/std/src/sys_common/util.rs b/library/std/src/sys_common/util.rs deleted file mode 100644 index f7072cc50110..000000000000 --- a/library/std/src/sys_common/util.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::fmt; -use crate::io::prelude::*; -use crate::sys::stdio::panic_output; - -pub fn dumb_print(args: fmt::Arguments<'_>) { - if let Some(mut out) = panic_output() { - let _ = out.write_fmt(args); - } -} From ec32bcf3fdb4fd3e36a48a5e9c11df0f3f7cd222 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 19 May 2021 15:37:10 +0200 Subject: [PATCH 13/26] Fix invalid CSS rules for a:hover --- src/librustdoc/html/static/themes/ayu.css | 7 ++----- src/librustdoc/html/static/themes/dark.css | 4 ++-- src/librustdoc/html/static/themes/light.css | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index 989ea7140c58..e59909ffdf05 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -151,17 +151,14 @@ pre, .rustdoc.source .example-wrap { color: #c5c5c5; } -.content a:hover { +.search-results a:hover { background-color: #777; } -.content a:focus { +.search-results a:focus { color: #000 !important; background-color: #c6afb3; } -.content a:focus { - color: #000 !important; -} .search-results a { color: #0096cf; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index e6bd16ddd11b..a2bcb43f44e6 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -109,11 +109,11 @@ pre, .rustdoc.source .example-wrap { color: #ddd; } -.content a:hover { +.search-results a:hover { background-color: #777; } -.content a:focus { +.search-results a:focus { color: #eee !important; background-color: #616161; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index 5481b348aa26..2ad3551d900e 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -109,11 +109,11 @@ pre, .rustdoc.source .example-wrap { color: #4E4C4C; } -.content a:hover { +.search-results a:hover { background-color: #ddd; } -.content a:focus { +.search-results a:focus { color: #000 !important; background-color: #ccc; } From 4ff5ab52966203b8ad8da96f897566e4a218308a Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Thu, 6 May 2021 14:03:50 +0200 Subject: [PATCH 14/26] Rename `rterr` to `rtprintpanic` --- library/std/src/alloc.rs | 2 +- library/std/src/panicking.rs | 9 +++------ library/std/src/sys/unix/stack_overflow.rs | 2 +- library/std/src/sys/windows/stack_overflow.rs | 2 +- library/std/src/sys_common/rt.rs | 8 ++++++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 9e9052ff92e1..8ee55234cea4 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -315,7 +315,7 @@ pub fn take_alloc_error_hook() -> fn(Layout) { } fn default_alloc_error_hook(layout: Layout) { - rterr!("memory allocation of {} bytes failed\n", layout.size()); + rtprintpanic!("memory allocation of {} bytes failed\n", layout.size()); } #[cfg(not(test))] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 909115151857..02957e75a740 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -596,15 +596,12 @@ fn rust_panic_with_hook( if panics > 2 { // Don't try to print the message in this case // - perhaps that is causing the recursive panics. - rterr!("thread panicked while processing panic. aborting.\n"); + rtprintpanic!("thread panicked while processing panic. aborting.\n"); } else { // Unfortunately, this does not print a backtrace, because creating // a `Backtrace` will allocate, which we must to avoid here. let panicinfo = PanicInfo::internal_constructor(message, location); - rterr!( - "{}\npanicked after panic::always_abort(), aborting.\n", - panicinfo - ); + rtprintpanic!("{}\npanicked after panic::always_abort(), aborting.\n", panicinfo); } intrinsics::abort() } @@ -637,7 +634,7 @@ fn rust_panic_with_hook( // have limited options. Currently our preference is to // just abort. In the future we may consider resuming // unwinding or otherwise exiting the thread cleanly. - rterr!("thread panicked while panicking. aborting.\n"); + rtprintpanic!("thread panicked while panicking. aborting.\n"); intrinsics::abort() } diff --git a/library/std/src/sys/unix/stack_overflow.rs b/library/std/src/sys/unix/stack_overflow.rs index 72fd48278bc1..81f47a779d33 100644 --- a/library/std/src/sys/unix/stack_overflow.rs +++ b/library/std/src/sys/unix/stack_overflow.rs @@ -102,7 +102,7 @@ mod imp { // If the faulting address is within the guard page, then we print a // message saying so and abort. if guard.start <= addr && addr < guard.end { - rterr!( + rtprintpanic!( "\nthread '{}' has overflowed its stack\n", thread::current().name().unwrap_or("") ); diff --git a/library/std/src/sys/windows/stack_overflow.rs b/library/std/src/sys/windows/stack_overflow.rs index 24ba35ad17e6..755dc0a6c8b4 100644 --- a/library/std/src/sys/windows/stack_overflow.rs +++ b/library/std/src/sys/windows/stack_overflow.rs @@ -24,7 +24,7 @@ extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) - let code = rec.ExceptionCode; if code == c::EXCEPTION_STACK_OVERFLOW { - rterr!( + rtprintpanic!( "\nthread '{}' has overflowed its stack\n", thread::current().name().unwrap_or("") ); diff --git a/library/std/src/sys_common/rt.rs b/library/std/src/sys_common/rt.rs index e4c9b60594ef..02013ecc4ced 100644 --- a/library/std/src/sys_common/rt.rs +++ b/library/std/src/sys_common/rt.rs @@ -39,7 +39,11 @@ pub fn cleanup() { }); } -macro_rules! rterr { +// Prints to the "panic output", depending on the platform this may be: +// - the standard error output +// - some dedicated platform specific output +// - nothing (so this macro is a no-op) +macro_rules! rtprintpanic { ($($t:tt)*) => { if let Some(mut out) = crate::sys::stdio::panic_output() { let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*)); @@ -50,7 +54,7 @@ macro_rules! rterr { macro_rules! rtabort { ($($t:tt)*) => { { - rterr!("fatal runtime error: {}\n", format_args!($($t)*)); + rtprintpanic!("fatal runtime error: {}\n", format_args!($($t)*)); crate::sys::abort_internal(); } } From 50a9f008f266bc7e81926309e3a0a2e36860a305 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 19 May 2021 16:37:17 +0200 Subject: [PATCH 15/26] CTFE Machine: do not expose Allocation --- compiler/rustc_mir/src/interpret/machine.rs | 7 ++++--- compiler/rustc_mir/src/interpret/memory.rs | 13 +++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir/src/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs index e6b3b1daf5a7..e7d7c38cc8ff 100644 --- a/compiler/rustc_mir/src/interpret/machine.rs +++ b/compiler/rustc_mir/src/interpret/machine.rs @@ -313,7 +313,7 @@ pub trait Machine<'mir, 'tcx>: Sized { #[inline(always)] fn memory_read( _memory_extra: &Self::MemoryExtra, - _alloc: &Allocation, + _alloc_extra: &Self::AllocExtra, _ptr: Pointer, _size: Size, ) -> InterpResult<'tcx> { @@ -324,7 +324,7 @@ pub trait Machine<'mir, 'tcx>: Sized { #[inline(always)] fn memory_written( _memory_extra: &mut Self::MemoryExtra, - _alloc: &mut Allocation, + _alloc_extra: &mut Self::AllocExtra, _ptr: Pointer, _size: Size, ) -> InterpResult<'tcx> { @@ -335,8 +335,9 @@ pub trait Machine<'mir, 'tcx>: Sized { #[inline(always)] fn memory_deallocated( _memory_extra: &mut Self::MemoryExtra, - _alloc: &mut Allocation, + _alloc_extra: &mut Self::AllocExtra, _ptr: Pointer, + _size: Size, ) -> InterpResult<'tcx> { Ok(()) } diff --git a/compiler/rustc_mir/src/interpret/memory.rs b/compiler/rustc_mir/src/interpret/memory.rs index 37aaa834aff1..7fb7c51b0b5b 100644 --- a/compiler/rustc_mir/src/interpret/memory.rs +++ b/compiler/rustc_mir/src/interpret/memory.rs @@ -343,10 +343,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } // Let the machine take some extra action - M::memory_deallocated(&mut self.extra, &mut alloc, ptr)?; + let size = alloc.size(); + M::memory_deallocated(&mut self.extra, &mut alloc.extra, ptr, size)?; // Don't forget to remember size and align of this now-dead allocation - let old = self.dead_alloc_map.insert(ptr.alloc_id, (alloc.size(), alloc.align)); + let old = self.dead_alloc_map.insert(ptr.alloc_id, (size, alloc.align)); if old.is_some() { bug!("Nothing can be deallocated twice"); } @@ -591,7 +592,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { }, )?; if let Some((ptr, alloc)) = ptr_and_alloc { - M::memory_read(&self.extra, alloc, ptr, size)?; + M::memory_read(&self.extra, &alloc.extra, ptr, size)?; let range = alloc_range(ptr.offset, size); Ok(Some(AllocRef { alloc, range, tcx: self.tcx, alloc_id: ptr.alloc_id })) } else { @@ -660,7 +661,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // FIXME: can we somehow avoid looking up the allocation twice here? // We cannot call `get_raw_mut` inside `check_and_deref_ptr` as that would duplicate `&mut self`. let (alloc, extra) = self.get_raw_mut(ptr.alloc_id)?; - M::memory_written(extra, alloc, ptr, size)?; + M::memory_written(extra, &mut alloc.extra, ptr, size)?; let range = alloc_range(ptr.offset, size); Ok(Some(AllocRefMut { alloc, range, tcx, alloc_id: ptr.alloc_id })) } else { @@ -1029,7 +1030,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(src_ptr) => src_ptr, }; let src_alloc = self.get_raw(src.alloc_id)?; - M::memory_read(&self.extra, src_alloc, src, size)?; + M::memory_read(&self.extra, &src_alloc.extra, src, size)?; // We need the `dest` ptr for the next operation, so we get it now. // We already did the source checks and called the hooks so we are good to return early. let dest = match dest { @@ -1058,7 +1059,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Destination alloc preparations and access hooks. let (dest_alloc, extra) = self.get_raw_mut(dest.alloc_id)?; - M::memory_written(extra, dest_alloc, dest, size * num_copies)?; + M::memory_written(extra, &mut dest_alloc.extra, dest, size * num_copies)?; let dest_bytes = dest_alloc .get_bytes_mut_ptr(&tcx, alloc_range(dest.offset, size * num_copies)) .as_mut_ptr(); From 523b4d149966a284101cc823167e637b6be9a10a Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 19 May 2021 16:11:11 +0100 Subject: [PATCH 16/26] Remove LSE2 --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 1 - compiler/rustc_codegen_ssa/src/target_features.rs | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index f0a2c91c0185..c734d3e0af93 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -153,7 +153,6 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { ("aarch64", "fp") => "fp-armv8", ("aarch64", "fp16") => "fullfp16", ("aarch64", "fhm") => "fp16fml", - ("aarch64", "lse2") => "outline-atomics", ("aarch64", "rcpc2") => "rcpc-immo", ("aarch64", "dpb") => "ccpp", ("aarch64", "dpb2") => "ccdp", diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index aa415754dadb..5a8f0b6d6dba 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -33,7 +33,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("thumb-mode", Some(sym::arm_target_feature)), ]; -// Commented features are not available in LLVM 9.0, or have since been renamed +// Commented features are not available in LLVM 10.0, or have since been renamed const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ // FEAT_AdvSimd ("neon", Some(sym::aarch64_target_feature)), @@ -51,8 +51,6 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("ras", Some(sym::aarch64_target_feature)), // FEAT_LSE ("lse", Some(sym::aarch64_target_feature)), - // FEAT_LSE2 - // ("lse2", Some(sym::aarch64_target_feature)), // FEAT_RDM ("rdm", Some(sym::aarch64_target_feature)), // FEAT_RCPC From c71e58d432447d29cbcb99b19b48e43a9913dcc1 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 19 May 2021 16:12:30 +0100 Subject: [PATCH 17/26] Rename fptoint to frintts --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 1 + compiler/rustc_codegen_ssa/src/target_features.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index c734d3e0af93..6394f15f6a92 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -156,6 +156,7 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str { ("aarch64", "rcpc2") => "rcpc-immo", ("aarch64", "dpb") => "ccpp", ("aarch64", "dpb2") => "ccdp", + ("aarch64", "frintts") => "fptoint", ("aarch64", "fcma") => "complxnum", (_, s) => s, } diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 5a8f0b6d6dba..646f21fa10fb 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -88,7 +88,7 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ // FEAT_SVE2_BitPerm ("sve2-bitperm", Some(sym::aarch64_target_feature)), // FEAT_FRINTTS - ("fptoint", Some(sym::aarch64_target_feature)), + ("frintts", Some(sym::aarch64_target_feature)), // FEAT_I8MM // ("i8mm", Some(sym::aarch64_target_feature)), // FEAT_F32MM From 904467a926f20d189203d119af57ae3861d2b56c Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 19 May 2021 16:13:23 +0100 Subject: [PATCH 18/26] Ensure all crypto components (AES, PMULL, SHA1/2) are available on arm/aarch64 --- compiler/rustc_codegen_ssa/src/target_features.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 646f21fa10fb..98d550d732fe 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -17,6 +17,8 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("neon", Some(sym::arm_target_feature)), ("crc", Some(sym::arm_target_feature)), ("crypto", Some(sym::arm_target_feature)), + ("aes", Some(sym::arm_target_feature)), + ("sha2", Some(sym::arm_target_feature)), ("v5te", Some(sym::arm_target_feature)), ("v6", Some(sym::arm_target_feature)), ("v6k", Some(sym::arm_target_feature)), @@ -107,6 +109,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("jsconv", Some(sym::aarch64_target_feature)), // FEAT_FCMA ("fcma", Some(sym::aarch64_target_feature)), + // FEAT_AES + ("aes", Some(sym::aarch64_target_feature)), // FEAT_SHA1 & FEAT_SHA256 ("sha2", Some(sym::aarch64_target_feature)), // FEAT_SHA512 & FEAT_SHA3 From d3737a66074945f65858086609cd51377c14559b Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Wed, 19 May 2021 16:13:52 +0100 Subject: [PATCH 19/26] Remove test for crypto feature ahead of its removal --- library/std/tests/run-time-detect.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/std/tests/run-time-detect.rs b/library/std/tests/run-time-detect.rs index 61a04c467224..c7107b5d0a3e 100644 --- a/library/std/tests/run-time-detect.rs +++ b/library/std/tests/run-time-detect.rs @@ -27,7 +27,6 @@ fn aarch64_linux() { println!("asimd: {}", is_aarch64_feature_detected!("asimd")); println!("sve: {}", is_aarch64_feature_detected!("sve")); println!("crc: {}", is_aarch64_feature_detected!("crc")); - println!("crypto: {}", is_aarch64_feature_detected!("crypto")); println!("lse: {}", is_aarch64_feature_detected!("lse")); println!("rdm: {}", is_aarch64_feature_detected!("rdm")); println!("rcpc: {}", is_aarch64_feature_detected!("rcpc")); From f06126506077ba535bc36f73bb531651c284c154 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 17 Mar 2021 03:52:02 +0000 Subject: [PATCH 20/26] Move the implementation of `Path::exists` to `sys_common::fs` so platforms can specialize it --- library/std/src/fs.rs | 26 ++++++++++++++++++++++++++ library/std/src/path.rs | 6 +----- library/std/src/sys/hermit/fs.rs | 2 +- library/std/src/sys/unix/fs.rs | 2 +- library/std/src/sys/unsupported/fs.rs | 4 ++++ library/std/src/sys/wasi/fs.rs | 2 +- library/std/src/sys/windows/fs.rs | 1 + library/std/src/sys_common/fs.rs | 8 ++++++++ 8 files changed, 43 insertions(+), 8 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index e6120b8ee31c..a1636e2f604c 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -2208,3 +2208,29 @@ impl AsInnerMut for DirBuilder { &mut self.inner } } + +/// Returns `Ok(true)` if the path points at an existing entity. +/// +/// This function will traverse symbolic links to query information about the +/// destination file. In case of broken symbolic links this will return `Ok(false)`. +/// +/// As opposed to the `exists()` method, this one doesn't silently ignore errors +/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission +/// denied on some of the parent directories.) +/// +/// # Examples +/// +/// ```no_run +/// #![feature(path_try_exists)] +/// use std::fs; +/// +/// assert!(!fs::try_exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt")); +/// assert!(fs::try_exists("/root/secret_file.txt").is_err()); +/// ``` +// FIXME: stabilization should modify documentation of `exists()` to recommend this method +// instead. +#[unstable(feature = "path_try_exists", issue = "83186")] +#[inline] +pub fn try_exists>(path: P) -> io::Result { + fs_imp::try_exists(path.as_ref()) +} diff --git a/library/std/src/path.rs b/library/std/src/path.rs index cbe14767bd3e..9c5615f58c43 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2507,11 +2507,7 @@ impl Path { #[unstable(feature = "path_try_exists", issue = "83186")] #[inline] pub fn try_exists(&self) -> io::Result { - match fs::metadata(self) { - Ok(_) => Ok(true), - Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(false), - Err(error) => Err(error), - } + fs::try_exists(self) } /// Returns `true` if the path exists on disk and is pointing at a regular file. diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs index 5b3f2fa4e827..76ea70d997f5 100644 --- a/library/std/src/sys/hermit/fs.rs +++ b/library/std/src/sys/hermit/fs.rs @@ -12,7 +12,7 @@ use crate::sys::time::SystemTime; use crate::sys::unsupported; use crate::sys_common::os_str_bytes::OsStrExt; -pub use crate::sys_common::fs::copy; +pub use crate::sys_common::fs::{copy, try_exists}; //pub use crate::sys_common::fs::remove_dir_all; fn cstr(path: &Path) -> io::Result { diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 79617aa77b7b..ef14865fbcd3 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -48,7 +48,7 @@ use libc::{ dirent64, fstat64, ftruncate64, lseek64, lstat64, off64_t, open64, readdir64_r, stat64, }; -pub use crate::sys_common::fs::remove_dir_all; +pub use crate::sys_common::fs::{remove_dir_all, try_exists}; pub struct File(FileDesc); diff --git a/library/std/src/sys/unsupported/fs.rs b/library/std/src/sys/unsupported/fs.rs index cd533761e373..1ec16a1acb37 100644 --- a/library/std/src/sys/unsupported/fs.rs +++ b/library/std/src/sys/unsupported/fs.rs @@ -275,6 +275,10 @@ pub fn remove_dir_all(_path: &Path) -> io::Result<()> { unsupported() } +pub fn try_exists(_path: &Path) -> io::Result<()> { + unsupported() +} + pub fn readlink(_p: &Path) -> io::Result { unsupported() } diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index ed0f03e4b710..45e38f68b8c3 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -14,7 +14,7 @@ use crate::sys::time::SystemTime; use crate::sys::unsupported; use crate::sys_common::FromInner; -pub use crate::sys_common::fs::remove_dir_all; +pub use crate::sys_common::fs::{remove_dir_all, try_exists}; pub struct File { fd: WasiFd, diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 8e6bd76f85f0..36b395507b12 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -11,6 +11,7 @@ use crate::sync::Arc; use crate::sys::handle::Handle; use crate::sys::time::SystemTime; use crate::sys::{c, cvt}; +pub use crate::sys_common::fs::try_exists; use crate::sys_common::FromInner; use super::to_u16s; diff --git a/library/std/src/sys_common/fs.rs b/library/std/src/sys_common/fs.rs index 30908824dd66..309f5483874e 100644 --- a/library/std/src/sys_common/fs.rs +++ b/library/std/src/sys_common/fs.rs @@ -41,3 +41,11 @@ fn remove_dir_all_recursive(path: &Path) -> io::Result<()> { } fs::remove_dir(path) } + +pub fn try_exists(path: &Path) -> io::Result { + match fs::metadata(path) { + Ok(_) => Ok(true), + Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(false), + Err(error) => Err(error), + } +} From 5d7c75a19f5bed05e565979f35d5fa5a09471217 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Tue, 18 May 2021 04:18:46 +0100 Subject: [PATCH 21/26] Windows implementation of `fs::try_exists` --- library/std/src/sys/windows/c.rs | 1 + library/std/src/sys/windows/fs.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index e91c489361ea..50d6e8cf27a4 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -173,6 +173,7 @@ pub const ERROR_INVALID_HANDLE: DWORD = 6; pub const ERROR_NOT_ENOUGH_MEMORY: DWORD = 8; pub const ERROR_OUTOFMEMORY: DWORD = 14; pub const ERROR_NO_MORE_FILES: DWORD = 18; +pub const ERROR_SHARING_VIOLATION: u32 = 32; pub const ERROR_HANDLE_EOF: DWORD = 38; pub const ERROR_FILE_EXISTS: DWORD = 80; pub const ERROR_INVALID_PARAMETER: DWORD = 87; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 36b395507b12..2b6143de9605 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -11,7 +11,6 @@ use crate::sync::Arc; use crate::sys::handle::Handle; use crate::sys::time::SystemTime; use crate::sys::{c, cvt}; -pub use crate::sys_common::fs::try_exists; use crate::sys_common::FromInner; use super::to_u16s; @@ -945,3 +944,32 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> { .map(drop) } } + +// Try to see if a file exists but, unlike `exists`, report I/O errors. +pub fn try_exists(path: &Path) -> io::Result { + // Open the file to ensure any symlinks are followed to their target. + let mut opts = OpenOptions::new(); + // No read, write, etc access rights are needed. + opts.access_mode(0); + // Backup semantics enables opening directories as well as files. + opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS); + match File::open(path, &opts) { + Err(e) => match e.kind() { + // The file definitely does not exist + io::ErrorKind::NotFound => Ok(false), + + // `ERROR_SHARING_VIOLATION` means that the file has been locked by + // another process. This is often temporary so we simply report it + // as the file existing. + io::ErrorKind::Other if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as i32) => { + Ok(true) + } + // Other errors such as `ERROR_ACCESS_DENIED` may indicate that the + // file exists. However, these types of errors are usually more + // permanent so we report them here. + _ => Err(e), + }, + // The file was opened successfully therefore it must exist, + Ok(_) => Ok(true), + } +} From 39441bb2c1030884d0f1d200de0a65b146ba6b6d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 29 Apr 2021 11:10:14 -0700 Subject: [PATCH 22/26] Make a ui test to take the role of libproc_macro #[test] tests --- src/test/ui/proc-macro/auxiliary/api/mod.rs | 16 ++++++++++++++++ src/test/ui/proc-macro/test.rs | 12 ++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/proc-macro/auxiliary/api/mod.rs create mode 100644 src/test/ui/proc-macro/test.rs diff --git a/src/test/ui/proc-macro/auxiliary/api/mod.rs b/src/test/ui/proc-macro/auxiliary/api/mod.rs new file mode 100644 index 000000000000..72b02ad554e5 --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/api/mod.rs @@ -0,0 +1,16 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![crate_name = "proc_macro_api_tests"] +#![deny(dead_code)] // catch if a test function is never called + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn run(input: TokenStream) -> TokenStream { + assert!(input.is_empty()); + TokenStream::new() +} diff --git a/src/test/ui/proc-macro/test.rs b/src/test/ui/proc-macro/test.rs new file mode 100644 index 000000000000..c96aa73175f2 --- /dev/null +++ b/src/test/ui/proc-macro/test.rs @@ -0,0 +1,12 @@ +// check-pass +// aux-build:api/mod.rs + +//! This is for everything that *would* be a #[test] inside of libproc_macro, +//! except for the fact that proc_macro objects are not capable of existing +//! inside of an ordinary Rust test execution, only inside a macro. + +extern crate proc_macro_api_tests; + +proc_macro_api_tests::run!(); + +fn main() {} From 3c16c0e1df61755db2267897392529eb9451aa62 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 29 Apr 2021 11:17:44 -0700 Subject: [PATCH 23/26] Move proc_macro tests to ui test --- .../test/ui/proc-macro/auxiliary/api/cmp.rs | 9 +++++---- src/test/ui/proc-macro/auxiliary/api/mod.rs | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) rename library/proc_macro/tests/test.rs => src/test/ui/proc-macro/auxiliary/api/cmp.rs (88%) diff --git a/library/proc_macro/tests/test.rs b/src/test/ui/proc-macro/auxiliary/api/cmp.rs similarity index 88% rename from library/proc_macro/tests/test.rs rename to src/test/ui/proc-macro/auxiliary/api/cmp.rs index d2e6b0bb8093..3d17e9e350e6 100644 --- a/library/proc_macro/tests/test.rs +++ b/src/test/ui/proc-macro/auxiliary/api/cmp.rs @@ -1,8 +1,10 @@ -#![feature(proc_macro_span)] - use proc_macro::{LineColumn, Punct}; -#[test] +pub fn test() { + test_line_column_ord(); + test_punct_eq(); +} + fn test_line_column_ord() { let line0_column0 = LineColumn { line: 0, column: 0 }; let line0_column1 = LineColumn { line: 0, column: 1 }; @@ -11,7 +13,6 @@ fn test_line_column_ord() { assert!(line0_column1 < line1_column0); } -#[test] fn test_punct_eq() { // Good enough if it typechecks, since proc_macro::Punct can't exist in a test. fn _check(punct: Punct) { diff --git a/src/test/ui/proc-macro/auxiliary/api/mod.rs b/src/test/ui/proc-macro/auxiliary/api/mod.rs index 72b02ad554e5..019fb2e7ec87 100644 --- a/src/test/ui/proc-macro/auxiliary/api/mod.rs +++ b/src/test/ui/proc-macro/auxiliary/api/mod.rs @@ -3,14 +3,18 @@ #![crate_type = "proc-macro"] #![crate_name = "proc_macro_api_tests"] +#![feature(proc_macro_span)] #![deny(dead_code)] // catch if a test function is never called extern crate proc_macro; +mod cmp; + use proc_macro::TokenStream; #[proc_macro] pub fn run(input: TokenStream) -> TokenStream { assert!(input.is_empty()); + cmp::test(); TokenStream::new() } From faad7e209deee6d09d335ca00c06d9f41bc040b5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 29 Apr 2021 11:20:27 -0700 Subject: [PATCH 24/26] Make a more meaningful test for Punct eq --- src/test/ui/proc-macro/auxiliary/api/cmp.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/ui/proc-macro/auxiliary/api/cmp.rs b/src/test/ui/proc-macro/auxiliary/api/cmp.rs index 3d17e9e350e6..5784a6e5d94d 100644 --- a/src/test/ui/proc-macro/auxiliary/api/cmp.rs +++ b/src/test/ui/proc-macro/auxiliary/api/cmp.rs @@ -1,4 +1,4 @@ -use proc_macro::{LineColumn, Punct}; +use proc_macro::{LineColumn, Punct, Spacing}; pub fn test() { test_line_column_ord(); @@ -14,8 +14,8 @@ fn test_line_column_ord() { } fn test_punct_eq() { - // Good enough if it typechecks, since proc_macro::Punct can't exist in a test. - fn _check(punct: Punct) { - let _ = punct == ':'; - } + let colon_alone = Punct::new(':', Spacing::Alone); + assert_eq!(colon_alone, ':'); + let colon_joint = Punct::new(':', Spacing::Joint); + assert_eq!(colon_joint, ':'); } From 965bce48348bbcc3c86898bdb5e18d4c57c35d00 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 29 Apr 2021 12:03:35 -0700 Subject: [PATCH 25/26] Add proc macro Literal parse test --- src/test/ui/proc-macro/auxiliary/api/mod.rs | 4 ++++ src/test/ui/proc-macro/auxiliary/api/parse.rs | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/test/ui/proc-macro/auxiliary/api/parse.rs diff --git a/src/test/ui/proc-macro/auxiliary/api/mod.rs b/src/test/ui/proc-macro/auxiliary/api/mod.rs index 019fb2e7ec87..739c25132e77 100644 --- a/src/test/ui/proc-macro/auxiliary/api/mod.rs +++ b/src/test/ui/proc-macro/auxiliary/api/mod.rs @@ -9,12 +9,16 @@ extern crate proc_macro; mod cmp; +mod parse; use proc_macro::TokenStream; #[proc_macro] pub fn run(input: TokenStream) -> TokenStream { assert!(input.is_empty()); + cmp::test(); + parse::test(); + TokenStream::new() } diff --git a/src/test/ui/proc-macro/auxiliary/api/parse.rs b/src/test/ui/proc-macro/auxiliary/api/parse.rs new file mode 100644 index 000000000000..4105236b7f2d --- /dev/null +++ b/src/test/ui/proc-macro/auxiliary/api/parse.rs @@ -0,0 +1,23 @@ +use proc_macro::Literal; + +pub fn test() { + test_parse_literal(); +} + +fn test_parse_literal() { + assert_eq!("1".parse::().unwrap().to_string(), "1"); + assert_eq!("1.0".parse::().unwrap().to_string(), "1.0"); + assert_eq!("'a'".parse::().unwrap().to_string(), "'a'"); + assert_eq!("\"\n\"".parse::().unwrap().to_string(), "\"\n\""); + assert_eq!("b\"\"".parse::().unwrap().to_string(), "b\"\""); + assert_eq!("r##\"\"##".parse::().unwrap().to_string(), "r##\"\"##"); + assert_eq!("10ulong".parse::().unwrap().to_string(), "10ulong"); + + assert!("0 1".parse::().is_err()); + assert!("'a".parse::().is_err()); + assert!(" 0".parse::().is_err()); + assert!("0 ".parse::().is_err()); + assert!("/* comment */0".parse::().is_err()); + assert!("0/* comment */".parse::().is_err()); + assert!("0// comment".parse::().is_err()); +} From 34585cb678bc492be7e48ff48a2633f4ce1dc5ae Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 29 Apr 2021 12:08:35 -0700 Subject: [PATCH 26/26] impl FromStr for proc_macro::Literal --- .../rustc_expand/src/proc_macro_server.rs | 31 +++++++++++++++++-- library/proc_macro/src/bridge/mod.rs | 14 +++++++++ library/proc_macro/src/lib.rs | 28 +++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 7bf6502c976c..92315c4d4f6c 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -1,9 +1,7 @@ use crate::base::{ExtCtxt, ResolverExpand}; use rustc_ast as ast; -use rustc_ast::token; -use rustc_ast::token::Nonterminal; -use rustc_ast::token::NtIdent; +use rustc_ast::token::{self, Nonterminal, NtIdent, TokenKind}; use rustc_ast::tokenstream::{self, CanSynthesizeMissingTokens}; use rustc_ast::tokenstream::{DelimSpan, Spacing::*, TokenStream, TreeAndSpacing}; use rustc_ast_pretty::pprust; @@ -541,6 +539,33 @@ impl server::Ident for Rustc<'_> { } impl server::Literal for Rustc<'_> { + fn from_str(&mut self, s: &str) -> Result { + let override_span = None; + let stream = parse_stream_from_source_str( + FileName::proc_macro_source_code(s), + s.to_owned(), + self.sess, + override_span, + ); + if stream.len() != 1 { + return Err(()); + } + let tree = stream.into_trees().next().unwrap(); + let token = match tree { + tokenstream::TokenTree::Token(token) => token, + tokenstream::TokenTree::Delimited { .. } => return Err(()), + }; + let span_data = token.span.data(); + if (span_data.hi.0 - span_data.lo.0) as usize != s.len() { + // There is a comment or whitespace adjacent to the literal. + return Err(()); + } + let lit = match token.kind { + TokenKind::Literal(lit) => lit, + _ => return Err(()), + }; + Ok(Literal { lit, span: self.call_site }) + } fn debug_kind(&mut self, literal: &Self::Literal) -> String { format!("{:?}", literal.lit.kind) } diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 355ad1f9f881..a2953b68564a 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -107,6 +107,7 @@ macro_rules! with_api { Literal { fn drop($self: $S::Literal); fn clone($self: &$S::Literal) -> $S::Literal; + fn from_str(s: &str) -> Result<$S::Literal, ()>; fn debug_kind($self: &$S::Literal) -> String; fn symbol($self: &$S::Literal) -> String; fn suffix($self: &$S::Literal) -> Option; @@ -315,6 +316,19 @@ impl Unmark for Option { } } +impl Mark for Result { + type Unmarked = Result; + fn mark(unmarked: Self::Unmarked) -> Self { + unmarked.map(T::mark).map_err(E::mark) + } +} +impl Unmark for Result { + type Unmarked = Result; + fn unmark(self) -> Self::Unmarked { + self.map(T::unmark).map_err(E::unmark) + } +} + macro_rules! mark_noop { ($($ty:ty),* $(,)?) => { $( diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 525fd0fbe343..281999fe7158 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -91,6 +91,12 @@ pub struct LexError { _inner: (), } +impl LexError { + fn new() -> Self { + LexError { _inner: () } + } +} + #[stable(feature = "proc_macro_lexerror_impls", since = "1.44.0")] impl fmt::Display for LexError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1171,6 +1177,28 @@ impl Literal { } } +/// Parse a single literal from its stringified representation. +/// +/// In order to parse successfully, the input string must not contain anything +/// but the literal token. Specifically, it must not contain whitespace or +/// comments in addition to the literal. +/// +/// The resulting literal token will have a `Span::call_site()` span. +/// +/// NOTE: some errors may cause panics instead of returning `LexError`. We +/// reserve the right to change these errors into `LexError`s later. +#[stable(feature = "proc_macro_literal_parse", since = "1.54.0")] +impl FromStr for Literal { + type Err = LexError; + + fn from_str(src: &str) -> Result { + match bridge::client::Literal::from_str(src) { + Ok(literal) => Ok(Literal(literal)), + Err(()) => Err(LexError::new()), + } + } +} + // N.B., the bridge only provides `to_string`, implement `fmt::Display` // based on it (the reverse of the usual relationship between the two). #[stable(feature = "proc_macro_lib", since = "1.15.0")]