diff --git a/RELEASES.md b/RELEASES.md index 940fa7c6072a9..f2d74f2e7f1f0 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -67,6 +67,8 @@ Stabilized APIs - [`Atomic::get_mut_slice`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.Atomic.html#method.get_mut_slice) - [`Atomic::from_mut_slice`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.Atomic.html#method.from_mut_slice) - [`std::range::legacy`](https://doc.rust-lang.org/stable/std/range/legacy/index.html) +- [`bool::ok_or`](https://doc.rust-lang.org/stable/std/primitive.bool.html#method.ok_or) +- [`bool::ok_or_else`](https://doc.rust-lang.org/stable/std/primitive.bool.html#method.ok_or_else) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index c33765f03d77d..dfc48b0bd1cd6 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -13,7 +13,7 @@ #![cfg_attr(bootstrap, feature(never_type))] #![cfg_attr(test, feature(test))] #![deny(unsafe_op_in_unsafe_fn)] -#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))] +#![doc(test(no_crate_inject, attr(deny(warnings))))] #![feature(decl_macro)] #![feature(dropck_eyepatch)] #![feature(rustc_attrs)] diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 3b01eb6eefa7d..46d8e11cc0931 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -5,7 +5,7 @@ //! This API is completely unstable and subject to change. // tidy-alphabetical-start -#![doc(test(attr(deny(warnings), allow(internal_features))))] +#![doc(test(attr(deny(warnings))))] #![feature(associated_type_defaults)] #![feature(deref_patterns)] #![feature(iter_order_by)] diff --git a/compiler/rustc_builtin_macros/src/contracts.rs b/compiler/rustc_builtin_macros/src/contracts.rs index e47c1b1363df0..20001400857a6 100644 --- a/compiler/rustc_builtin_macros/src/contracts.rs +++ b/compiler/rustc_builtin_macros/src/contracts.rs @@ -137,6 +137,21 @@ fn expand_contract_clause_tts( annotated: TokenStream, clause_keyword: rustc_span::Symbol, ) -> Result { + if annotation.is_empty() { + let (name, example) = if clause_keyword == kw::ContractRequires { + ("requires", "condition") + } else { + ("ensures", "|result: &T| condition") + }; + ecx.sess.dcx().span_err( + attr_span, + format!("`{name}` attribute requires an argument, e.g., `#[{name}({example})]`"), + ); + // Returning `Err` would replace it with a dummy fragment and cause cascading name-resolution errors. + // Instead, we return the original token stream so that there is no later noises. + return Ok(annotated); + } + let feature_span = ecx.with_def_site_ctxt(attr_span); expand_contract_clause(ecx, attr_span, annotated, |new_tts| { new_tts.push(TokenTree::Token( diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e715f9cd16c9d..549769547da78 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -16,12 +16,12 @@ use rustc_target::spec::HasTargetSpec; use smallvec::SmallVec; use tracing::debug; -use crate::attributes; use crate::builder::Builder; use crate::common::Funclet; use crate::context::CodegenCx; use crate::llvm::{self, ToLlvmBool, Type, Value}; use crate::type_of::LayoutLlvmExt; +use crate::{attributes, llvm_util}; impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { fn codegen_inline_asm( @@ -499,7 +499,15 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> { template_str.push_str("\n.att_syntax\n"); } - llvm::append_module_inline_asm(self.llmod, template_str.as_bytes()); + let target_features = self.tcx.global_backend_features(()).join(","); + let target_cpu = llvm_util::target_cpu(self.tcx.sess); + + llvm::append_module_inline_asm( + self.llmod, + template_str.as_bytes(), + &target_features, + target_cpu, + ); } fn mangled_name(&self, instance: Instance<'tcx>) -> String { diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 66b51d9184a79..b8952ffc6bf81 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -1303,9 +1303,9 @@ fn embed_bitcode( // We need custom section flags, so emit module-level inline assembly. let section_flags = if cgcx.is_pe_coff { "n" } else { "e" }; let asm = create_section_with_flags_asm(".llvmbc", section_flags, bitcode); - llvm::append_module_inline_asm(llmod, &asm); + llvm::append_module_inline_asm(llmod, &asm, "", ""); let asm = create_section_with_flags_asm(".llvmcmd", section_flags, &[]); - llvm::append_module_inline_asm(llmod, &asm); + llvm::append_module_inline_asm(llmod, &asm, "", ""); } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8c9bf55b14e45..05d3bd0b08b95 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -907,13 +907,6 @@ unsafe extern "C" { pub(crate) fn LLVMGetDataLayoutStr(M: &Module) -> *const c_char; pub(crate) fn LLVMSetDataLayout(M: &Module, Triple: *const c_char); - /// Append inline assembly to a module. See `Module::appendModuleInlineAsm`. - pub(crate) fn LLVMAppendModuleInlineAsm( - M: &Module, - Asm: *const c_uchar, // See "PTR_LEN_STR". - Len: size_t, - ); - /// Create the specified uniqued inline asm string. See `InlineAsm::get()`. pub(crate) fn LLVMGetInlineAsm<'ll>( Ty: &'ll Type, @@ -2119,6 +2112,17 @@ unsafe extern "C" { ConstraintsLen: size_t, ) -> bool; + /// Append inline assembly to a module. See `Module::appendModuleInlineAsm`. + pub(crate) fn LLVMRustAppendModuleInlineAsm( + M: &Module, + Asm: *const c_uchar, // See "PTR_LEN_STR". + AsmLen: size_t, + TargetFeatures: *const c_uchar, // See "PTR_LEN_STR". + TargetFeaturesLen: size_t, + TargetCpu: *const c_uchar, // See "PTR_LEN_STR". + TargetCpuLen: size_t, + ); + /// A list of pointer-length strings is passed as two pointer-length slices, /// one slice containing pointers and one slice containing their corresponding /// lengths. The implementation will check that both slices have the same length. diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index eb7a529c0b198..5452f4abc5c33 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -474,11 +474,24 @@ pub(crate) fn set_dso_local<'ll>(v: &'ll Value) { } } -/// Safe wrapper for `LLVMAppendModuleInlineAsm`, which delegates to +/// Safe wrapper for `LLVMRustAppendModuleInlineAsm`, which delegates to /// `Module::appendModuleInlineAsm`. -pub(crate) fn append_module_inline_asm<'ll>(llmod: &'ll Module, asm: &[u8]) { +pub(crate) fn append_module_inline_asm<'ll>( + llmod: &'ll Module, + asm: &[u8], + target_features: &str, + target_cpu: &str, +) { unsafe { - LLVMAppendModuleInlineAsm(llmod, asm.as_ptr(), asm.len()); + LLVMRustAppendModuleInlineAsm( + llmod, + asm.as_ptr(), + asm.len(), + target_features.as_ptr(), + target_features.len(), + target_cpu.as_ptr(), + target_cpu.len(), + ); } } diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index cd1e573ea28df..2aaf9cea97e44 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -270,7 +270,7 @@ //! * [DOT language](https://www.graphviz.org/doc/info/lang.html) // tidy-alphabetical-start -#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] // tidy-alphabetical-end use std::borrow::Cow; diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 98269a5fd4e44..dbc503f5c7ec4 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -823,7 +823,7 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,compile_fail /// #![deny(dead_code_pub_in_binary)] /// /// pub fn unused_pub_fn() {} @@ -1132,9 +1132,9 @@ declare_lint! { /// /// ### Example /// - /// ```rust + /// ```rust,compile_fail /// #![deny(warnings)] - /// fn foo() {} + /// struct non_standard_name; /// ``` /// /// {{produces}} diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 983a506bd4ac6..c928282596cdd 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -661,6 +661,20 @@ extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints, unwrap(Ty), StringRef(Constraints, ConstraintsLen))); } +extern "C" void LLVMRustAppendModuleInlineAsm( + LLVMModuleRef M, const char *Asm, size_t AsmLen, const char *TargetFeatures, + size_t TargetFeaturesLen, const char *TargetCPU, size_t TargetCPULen) { +#if LLVM_VERSION_GE(23, 0) + Module::GlobalAsmProperties Props; + Props.TargetFeatures = std::string(TargetFeatures, TargetFeaturesLen); + Props.TargetCPU = std::string(TargetCPU, TargetCPULen); + unwrap(M)->appendModuleInlineAsm( + Module::GlobalAsmFragment(std::string(Asm, AsmLen), Props)); +#else + unwrap(M)->appendModuleInlineAsm(StringRef(Asm, AsmLen)); +#endif +} + template DIT *unwrapDIPtr(LLVMMetadataRef Ref) { return (DIT *)(Ref ? unwrap(Ref) : nullptr); } diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 256bc8c3fe30e..90e04fe388ad6 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -8,7 +8,7 @@ // We want to be able to build this crate with a stable compiler, // so no `#![feature]` attributes should be added. #![deny(unstable_features)] -#![doc(test(attr(deny(warnings), allow(internal_features))))] +#![doc(test(attr(deny(warnings))))] // tidy-alphabetical-end use std::ops::Range; diff --git a/compiler/rustc_public/src/lib.rs b/compiler/rustc_public/src/lib.rs index 4adc0e139a68e..ac2d1eb7a7a42 100644 --- a/compiler/rustc_public/src/lib.rs +++ b/compiler/rustc_public/src/lib.rs @@ -43,7 +43,7 @@ //! For more information, see . #![allow(rustc::usage_of_ty_tykind)] -#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(sized_hierarchy)] use std::fmt::Debug; diff --git a/compiler/rustc_public_bridge/src/lib.rs b/compiler/rustc_public_bridge/src/lib.rs index d598f88a00d27..c8859b0e349ea 100644 --- a/compiler/rustc_public_bridge/src/lib.rs +++ b/compiler/rustc_public_bridge/src/lib.rs @@ -13,7 +13,7 @@ // tidy-alphabetical-start #![allow(rustc::usage_of_ty_tykind)] -#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(trait_alias)] // tidy-alphabetical-end diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 39333ab00b57f..ae7c3854d00b4 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -4,7 +4,7 @@ #![allow(internal_features)] #![allow(rustc::internal)] #![cfg_attr(bootstrap, feature(never_type))] -#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))] +#![doc(test(attr(allow(unused_variables), deny(warnings))))] #![feature(core_intrinsics)] #![feature(min_specialization)] #![feature(nonzero_internals)] diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index a5053c408b155..95f6348cfbdbb 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3647,11 +3647,14 @@ pub enum Polonius { impl Default for Polonius { fn default() -> Self { - if option_env!("CFG_DEFAULT_POLONIUS_NEXT").is_some() { Self::Next } else { Self::Off } + Self::DEFAULT } } impl Polonius { + pub(crate) const DEFAULT: Self = + if option_env!("CFG_DEFAULT_POLONIUS_NEXT").is_some() { Self::Next } else { Self::Off }; + /// Returns whether the legacy version of polonius is enabled pub fn is_legacy_enabled(&self) -> bool { matches!(self, Polonius::Legacy) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 90459090ced87..bab087249593a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -510,7 +510,7 @@ macro_rules! options { $( { TARGET_MODIFIER: $tmod_variant:ident } )? $( { MITIGATION: $mitigation_variant:ident } )? , - $desc:literal + $desc:expr $(, removed: $removed:ident )? ), )* @@ -2350,6 +2350,12 @@ options! { // - src/doc/rustc/src/codegen-options/index.md } +const POLONIUS_HELP: &str = match Polonius::DEFAULT { + Polonius::Off => "enable polonius-based borrow-checker (default: no)", + Polonius::Next => "enable polonius-based borrow-checker (default: next)", + Polonius::Legacy => panic!("Polonius::Legacy is not a valid default value"), +}; + options! { UnstableOptions, UnstableOptionsTargetModifiers, Z_OPTIONS, dbopts, "Z", "unstable", @@ -2750,7 +2756,7 @@ options! { `vt-ptr-type-discrimination - incorporate type discrimination in authenticated vtable pointers Example: `-Zpointer-authentication=+calls,-init-fini`."), polonius: Polonius = (Polonius::default(), parse_polonius, [TRACKED], - "enable polonius-based borrow-checker (default: no)"), + POLONIUS_HELP), pre_link_arg: (/* redirected to pre_link_args */) = ((), parse_string_push, [UNTRACKED], "a single extra argument to prepend the linker invocation (can be used several times)"), pre_link_args: Vec = (Vec::new(), parse_list, [UNTRACKED], diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs index 4aa69dac2d7db..3603d54400536 100644 --- a/compiler/rustc_target/src/asm/loongarch.rs +++ b/compiler/rustc_target/src/asm/loongarch.rs @@ -53,7 +53,7 @@ impl LoongArchInlineAsmRegClass { (Self::vreg, _) => { if allow_experimental_reg { types! { - lsx: F16, F32, F64, + lsx: I128, F16, F32, F64, VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2); } } else { @@ -63,7 +63,7 @@ impl LoongArchInlineAsmRegClass { (Self::xreg, _) => { if allow_experimental_reg { types! { - lasx: F16, F32, F64, + lasx: I128, F16, F32, F64, VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2), VecI8(32), VecI16(16), VecI32(8), VecI64(4), VecF32(8), VecF64(4); } diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 3710d41dba0d9..03dff745210d6 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -59,12 +59,6 @@ fn normalize_canonicalized_projection<'tcx>( 0, &mut obligations, ); - obligations.extend(const_arg_has_type_obligation( - tcx, - param_env, - normalized_term, - goal, - )); ocx.register_obligations(obligations); // #112047: With projections and opaques, we are able to create opaques that // are recursive (given some generic parameters of the opaque's type variables). @@ -147,12 +141,6 @@ fn normalize_canonicalized_inherent_projection<'tcx>( 0, &mut obligations, ); - obligations.extend(const_arg_has_type_obligation( - tcx, - param_env, - normalized_term, - goal, - )); ocx.register_obligations(obligations); Ok(NormalizationResult { normalized_term }) diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index ba75f00791923..e107e76d69034 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -72,13 +72,13 @@ macro_rules! forward_ref_op_assign { macro_rules! impl_fn_for_zst { ($( $( #[$attr: meta] )* - struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = + $vis:vis struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty $body: block; )+) => { $( $( #[$attr] )* - struct $Name; + $vis struct $Name; impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { #[inline] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 201019037148d..40be9131931a4 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2456,6 +2456,8 @@ const impl PartialEq for Option { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cmp", issue = "143800")] const impl PartialOrd for Option { + /// See [the documentation](https://doc.rust-lang.org/std/option/#comparison-operators) for details. + /// [`None`] always compares less than any [`Some`] #[inline] fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 07920a36e6eda..e083a7fa32a4b 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -6,6 +6,12 @@ use crate::fmt::{self, Write}; #[cfg(not(all(target_arch = "loongarch64", target_feature = "lsx")))] use crate::intrinsics::const_eval_select; use crate::{ascii, iter, ops}; +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +use crate::{ + iter::{Filter, FusedIterator}, + slice::Split, + str::{BytesIsNotEmpty, IsAsciiWhitespace}, +}; impl [u8] { /// Checks if all bytes in this slice are within the ASCII range. @@ -314,6 +320,140 @@ impl [u8] { pub const fn trim_ascii(&self) -> &[u8] { self.trim_ascii_start().trim_ascii_end() } + + /// Splits a byte slice by ASCII whitespace. + /// + /// The returned iterator yields byte slices that are subslices of the + /// original byte slice, separated by any amount of ASCII whitespace. + /// + /// This uses the same definition as [`u8::is_ascii_whitespace`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// let mut iter = b"A few words".split_ascii_whitespace(); + /// + /// assert_eq!(Some(&b"A"[..]), iter.next()); + /// assert_eq!(Some(&b"few"[..]), iter.next()); + /// assert_eq!(Some(&b"words"[..]), iter.next()); + /// + /// assert_eq!(None, iter.next()); + /// ``` + /// + /// Various kinds of ASCII whitespace are considered + /// (see [`u8::is_ascii_whitespace`]): + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// let mut iter = b" Mary had\ta little \n\t lamb".split_ascii_whitespace(); + /// + /// assert_eq!(Some(&b"Mary"[..]), iter.next()); + /// assert_eq!(Some(&b"had"[..]), iter.next()); + /// assert_eq!(Some(&b"a"[..]), iter.next()); + /// assert_eq!(Some(&b"little"[..]), iter.next()); + /// assert_eq!(Some(&b"lamb"[..]), iter.next()); + /// + /// assert_eq!(None, iter.next()); + /// ``` + /// + /// If the byte slice is empty or contains only ASCII whitespace, the iterator + /// yields no byte slices: + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// assert_eq!(b"".split_ascii_whitespace().next(), None); + /// assert_eq!(b" ".split_ascii_whitespace().next(), None); + /// ``` + #[must_use = "this returns the split byte slice as an iterator, without modifying the original"] + #[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] + #[inline] + pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { + let inner = self.split(IsAsciiWhitespace).filter(BytesIsNotEmpty); + SplitAsciiWhitespace { inner } + } +} + +/// An iterator over the non-ASCII-whitespace subslices of a byte slice, +/// separated by any amount of ASCII whitespace. +/// +/// This struct is created by the [`split_ascii_whitespace`] method on [`[u8]`][byteslice]. +/// See its documentation for more. +/// +/// [`split_ascii_whitespace`]: slice::split_ascii_whitespace +/// [byteslice]: prim@slice +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +#[derive(Clone, Debug)] +pub struct SplitAsciiWhitespace<'a> { + pub(crate) inner: Filter, BytesIsNotEmpty>, +} + +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +impl<'a> Iterator for SplitAsciiWhitespace<'a> { + type Item = &'a [u8]; + + #[inline] + fn next(&mut self) -> Option<&'a [u8]> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } + + #[inline] + fn last(mut self) -> Option<&'a [u8]> { + self.next_back() + } +} + +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> { + #[inline] + fn next_back(&mut self) -> Option<&'a [u8]> { + self.inner.next_back() + } +} + +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +impl FusedIterator for SplitAsciiWhitespace<'_> {} + +impl<'a> SplitAsciiWhitespace<'a> { + /// Returns remainder of the split slice. + /// + /// If the iterator is empty, returns `None`. + /// + /// # Examples + /// + /// ``` + /// #![feature(u8_split_ascii_whitespace)] + /// + /// let mut split = b"Mary had a little lamb".split_ascii_whitespace(); + /// assert_eq!(split.remainder(), Some(b"Mary had a little lamb".as_slice())); + /// + /// split.next(); + /// assert_eq!(split.remainder(), Some(b"had a little lamb".as_slice())); + /// + /// split.by_ref().for_each(drop); + /// assert_eq!(split.remainder(), None); + /// ``` + #[inline] + #[must_use] + // This is also blocked on: https://github.com/rust-lang/rust/issues/77998 + #[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] + pub fn remainder(&self) -> Option<&'a [u8]> { + if self.inner.iter.finished { + return None; + } + + Some(self.inner.iter.v) + } } impl_fn_for_zst! { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f73f0c5390629..f787b7994ba9d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -45,6 +45,8 @@ mod specialize; #[stable(feature = "inherent_ascii_escape", since = "1.60.0")] pub use ascii::EscapeAscii; +#[unstable(feature = "u8_split_ascii_whitespace", issue = "147878")] +pub use ascii::SplitAsciiWhitespace; #[unstable(feature = "str_internals", issue = "none")] #[doc(hidden)] pub use ascii::is_ascii_simple; diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 79f4f29da2d43..f0dd0430230e2 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -1263,8 +1263,7 @@ impl str { #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] #[inline] pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> { - let inner = - self.as_bytes().split(IsAsciiWhitespace).filter(BytesIsNotEmpty).map(UnsafeBytesToStr); + let inner = self.as_bytes().split_ascii_whitespace().inner.map(UnsafeBytesToStr); SplitAsciiWhitespace { inner } } @@ -3351,7 +3350,7 @@ impl_fn_for_zst! { }; #[derive(Clone)] - struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool { + pub(crate) struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool { byte.is_ascii_whitespace() }; @@ -3361,7 +3360,7 @@ impl_fn_for_zst! { }; #[derive(Clone)] - struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool { + pub(crate) struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool { !s.is_empty() }; diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 34a4fc74055d0..e81cae69e1852 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -124,6 +124,7 @@ #![feature(try_from_int_error_kind)] #![feature(try_trait_v2)] #![feature(type_info)] +#![feature(u8_split_ascii_whitespace)] #![feature(uint_carryless_mul)] #![feature(uint_gather_scatter_bits)] #![feature(unicode_internals)] diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs index 9b0db0e733c57..e570bff645af7 100644 --- a/library/coretests/tests/slice.rs +++ b/library/coretests/tests/slice.rs @@ -2610,3 +2610,30 @@ fn test_shift_right() { case([1, 2, 3, 4], [5], [1], [2, 3, 4, 5]); case([1, 2, 3, 4, 5], [], [], [1, 2, 3, 4, 5]); } + +#[test] +fn test_split_ascii_whitespace_non_ascii() { + let bytes = b"\xff \x80 \xc2\xa0"; + + assert_eq!( + bytes.split_ascii_whitespace().collect::>(), + vec![&b"\xff"[..], &b"\x80"[..], &b"\xc2\xa0"[..]], + ); +} + +#[test] +fn test_split_ascii_whitespace_remainder() { + let bytes = b" Mary \t had "; + let mut split = bytes.split_ascii_whitespace(); + + assert_eq!(split.remainder(), Some(&bytes[..])); + + assert_eq!(split.next(), Some(&b"Mary"[..])); + assert_eq!(split.remainder(), Some(&b"\t had "[..])); + + assert_eq!(split.next(), Some(&b"had"[..])); + assert_eq!(split.remainder(), Some(&b" "[..])); + + assert_eq!(split.next(), None); + assert_eq!(split.remainder(), None); +} diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 6ad20b192fa5c..8df809264a6dd 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -3620,22 +3620,22 @@ pub fn set_permissions>(path: P, perm: Permissions) -> io::Result /// /// # Platform-specific behavior /// -/// This function currently corresponds to: -/// * `open` with `O_NOFOLLOW` flag enabled + `fchmod` on WASI -/// * `fchmodat` function with the flag `AT_SYMLINK_NOFOLLOW` enabled -/// on Unix platforms -/// * The flag `FILE_FLAG_OPEN_REPARSE_POINT` is enabled and then the -/// permissions of the file is set through `SetFileInformationByHandle` -/// on Windows. -/// * On all other platforms, the behavior remains the same with -/// [`fs::set_permissions`]. -/// -/// [`fs::set_permissions`]: crate::fs::set_permissions +/// This function currently corresponds to the following underlying operations: +/// * Android: returns [`Unsupported`] on all files. +/// * Linux, BSD-based platforms, QNX, NTO: `fchmodat` with `AT_SYMLINK_NOFOLLOW`. +/// If that is not supported, we fall back to: +/// * Unix-based platforms with symlinks: `open` with `O_NOFOLLOW` followed by +/// [`fs::set_permissions`]. +/// * Unix-based platforms without symlinks: `open` followed by [`fs::set_permissions`]. +/// * Windows: `CreateFileW` with `FILE_FLAG_OPEN_REPARSE_POINT` followed +/// by `SetFileInformationByHandle`. /// /// Note that, this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior /// +/// [`fs::set_permissions`]: crate::fs::set_permissions +/// /// # Errors /// /// This function will return an error in the following situations, but is not @@ -3644,10 +3644,8 @@ pub fn set_permissions>(path: P, perm: Permissions) -> io::Result /// * `path` does not exist. /// * The user lacks the permission to change attributes of the file. /// -/// Note: On Linux, this will result in a [`Unsupported`] error -/// if the final element is a symlink. On BSD-based systems, the -/// behavior can vary from symlink permission bits changing or -/// there being no effects on symlinks +/// Note: On Linux and other Unix-based platforms with symlinks (non-BSD-based), +/// this will result in an [`Unsupported`] error if the final element is a symlink. /// /// [`Unsupported`]: crate::io::ErrorKind::Unsupported /// @@ -3660,8 +3658,8 @@ pub fn set_permissions>(path: P, perm: Permissions) -> io::Result /// fn main() -> std::io::Result<()> { /// let mut perms = fs::symlink_metadata("foo.txt")?.permissions(); /// perms.set_readonly(true); -/// // This should result in an error on certain platforms -/// // or succeed in modifying the permissions of a symlink +/// // This should result in an error on certain platforms or +/// // succeed in modifying the permissions of a symlink /// fs::set_permissions_nofollow("foo.txt", perms)?; /// Ok(()) /// } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 075814b379027..3ed9e214a78e6 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -613,6 +613,7 @@ fn set_get_unix_permissions() { assert_eq!(mask & metadata1.permissions().mode(), 0o0777); } +#[cfg(not(target_os = "android"))] #[test] fn set_get_permissions_nofollows() { let tmpdir = tmpdir(); @@ -649,7 +650,10 @@ fn set_get_permissions_nofollows() { // Only Windows and Unix support `fs::set_permissions_nofollow` #[test] -#[cfg(all(any(windows, unix), not(any(target_os = "espidf", target_os = "horizon"))))] +#[cfg(all( + any(windows, unix), + not(any(target_os = "espidf", target_os = "horizon", target_os = "wasi")) +))] fn set_get_permissions_nofollows_symlink() { #[cfg(not(windows))] use crate::os::unix::fs::symlink as symlink_dir; @@ -662,43 +666,55 @@ fn set_get_permissions_nofollows_symlink() { check!(File::create(&filename)); check!(symlink_dir(&filename, &symlink_name)); - let sym_metadata = check!(fs::symlink_metadata(&symlink_name)); - let mut permission_bits = sym_metadata.permissions(); - permission_bits.set_readonly(true); - let result = fs::set_permissions_nofollow(&symlink_name, permission_bits); + let init_symlink_metadata = check!(fs::symlink_metadata(&symlink_name)); + let mut init_symlink_permissions = init_symlink_metadata.permissions(); + + let init_target_metadata = check!(fs::metadata(&symlink_name)); + let init_target_permissions = init_target_metadata.permissions(); + + // Set symlink permissions to readonly + init_symlink_permissions.set_readonly(true); + let result = fs::set_permissions_nofollow(&symlink_name, init_symlink_permissions); cfg_select! { any( windows, - target_os = "android", target_os = "macos", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", - target_os = "dragonfly" + target_os = "dragonfly", + target_os = "nto", + target_os = "qnx" ) => { assert_eq!(result.unwrap(), ()); - let metadata0 = check!(fs::symlink_metadata(&symlink_name)); - // So seems like BSD-based systems trying to set permissions - // on symlinks could lead to no effect, so we should expect - // there being no change to BSD-based systems. + + let after_target_metadata = check!(fs::metadata(&symlink_name)); + // We should expect the target file to not have its permission bits + // changed + assert_eq!(after_target_metadata.permissions(), init_target_permissions); + + let after_symlink_metadata = check!(fs::symlink_metadata(&symlink_name)); + // On these systems, it's confirmed the symlink itself is marked readonly // https://superuser.com/questions/1099634/change-permissions-symbolic-link-mac-os - #[cfg(windows)] - assert!(metadata0.permissions().readonly()); - #[cfg(not(windows))] - assert!(!metadata0.permissions().readonly()); + assert!(after_symlink_metadata.permissions().readonly()); // Reset the read-only bit under Windows 7: avoids the // `TempDir::drop` from crashing on a permission denial when // trying to delete the file that has it. #[cfg(all(windows, target_vendor = "win7"))] { - let mut permission_bits = metadata0.permissions(); - permission_bits.set_readonly(false); - check!(fs::set_permissions_nofollow(&symlink_name, permission_bits)); + let mut symlink_permission_bits = after_symlink_metadata.permissions(); + symlink_permission_bits.set_readonly(false); + check!(fs::set_permissions_nofollow(&symlink_name, symlink_permission_bits)); } } _ => { + let after_target_metadata = check!(fs::metadata(&symlink_name)); + // We should expect the target file to not have its permission bits + // changed + assert_eq!(after_target_metadata.permissions(), init_target_permissions); + let error_kind = result.unwrap_err().kind(); assert_eq!(error_kind, crate::io::ErrorKind::Unsupported); } @@ -1426,6 +1442,7 @@ fn fchmod_works() { check!(file.set_permissions(p)); } +#[cfg(not(target_os = "android"))] #[test] fn fchmodat_works() { let tmpdir = tmpdir(); diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 6dbe37ca9fba8..f1208e090f040 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -7,7 +7,7 @@ mod tests; )] use crate::{ io::{Error, OsFunctions, RawOsError}, - sys::io::{decode_error_kind, errno, error_string, is_interrupted}, + sys::io::{decode_error_kind, errno, format_error, is_interrupted}, }; // Because std is linked in during testing, these incoherent implementations would @@ -74,11 +74,8 @@ impl Error { #[must_use] #[inline] pub fn from_raw_os_error(code: RawOsError) -> Error { - const FUNCTIONS: &'static OsFunctions = &OsFunctions { - format_os_error: |code, fmt| fmt.write_str(&error_string(code)), - decode_error_kind, - is_interrupted, - }; + const FUNCTIONS: &'static OsFunctions = + &OsFunctions { format_os_error: format_error, decode_error_kind, is_interrupted }; // SAFETY: `FUNCTIONS` is a constant and not created at runtime. unsafe { Error::from_raw_os_error_with_functions(code, FUNCTIONS) } diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs index a3a2f5830ae91..7f75d7b4c980c 100644 --- a/library/std/src/io/error/tests.rs +++ b/library/std/src/io/error/tests.rs @@ -1,5 +1,5 @@ use crate::io::{Error, ErrorKind, const_error}; -use crate::sys::io::{decode_error_kind, error_string}; +use crate::sys::io::{decode_error_kind, format_error}; use crate::{assert_matches, error, fmt}; #[test] @@ -10,7 +10,7 @@ fn test_size() { #[test] fn test_debug_error() { let code = 6; - let msg = error_string(code); + let msg = fmt::from_fn(|f| format_error(code, f)).to_string(); let kind = decode_error_kind(code); let err = Error::new(ErrorKind::InvalidInput, Error::from_raw_os_error(code)); let expected = format!( diff --git a/library/std/src/path.rs b/library/std/src/path.rs index dbfc00b2c2b47..95de11b3d6386 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2377,7 +2377,7 @@ pub struct NormalizeError; impl Path { // The following (private!) function allows construction of a path from a u8 // slice, which is only safe when it is known to follow the OsStr encoding. - unsafe fn from_u8_slice(s: &[u8]) -> &Path { + pub(crate) unsafe fn from_u8_slice(s: &[u8]) -> &Path { unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) } } // The following (private!) function reveals the byte encoding used for OsStr. diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 1a0da329ce1a3..08473e245cc8e 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -360,12 +360,7 @@ impl File { let off = match pos { SeekFrom::Start(p) => p, SeekFrom::End(p) => { - // Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to be set to the end of the file. - if p == 0 { - 0xFFFFFFFFFFFFFFFF - } else { - self.file_attr()?.size().checked_add_signed(p).ok_or(NEG_OFF_ERR)? - } + self.file_attr()?.size().checked_add_signed(p).ok_or(NEG_OFF_ERR)? } SeekFrom::Current(p) => self.tell()?.checked_add_signed(p).ok_or(NEG_OFF_ERR)?, }; diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index b33ebadebe4ad..74b4322d027c5 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1884,31 +1884,91 @@ pub fn set_perm(p: &CStr, perm: FilePermissions) -> io::Result<()> { cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ()) } +#[cfg(target_os = "android")] +pub fn set_perm_nofollow(_p: &CStr, _perm: FilePermissions) -> io::Result<()> { + // Currently Android seems to be having inconsistent behavior with fchmodat + // with `AT_SYMLINK_NOFOLLOW` or openat with `O_NOFOLLOW` + fchmod. + // See this issue here mentioning inconsistent behavior on fchmodat: + // https://github.com/android/ndk/issues/1258 + // On the arm-android CI job, using fchmodat with `AT_SYMLINK_NOFOLLOW` + + // fallback behavior on a symlink sets the target file's permissions, + // which is incorrect behavior. + Err(crate::io::ErrorKind::Unsupported.into()) +} + +#[cfg(not(target_os = "android"))] pub fn set_perm_nofollow(p: &CStr, perm: FilePermissions) -> io::Result<()> { - // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it. - // Their filesystems do not have symbolic links, so no special handling is required. - cfg_select! { - // wasm32-wasip1 targets do not support fchmodat, so we fall down to - // open + fchmod - target_os = "wasi" => { - use crate::fs::{OpenOptions, Permissions}; - use crate::os::wasi::ffi::OsStrExt; - use crate::os::wasi::fs::OpenOptionsExt; + #[inline] + /// Helper function for fallback open with `O_NOFOLLOW` + `fchmod` behavior + fn open_and_set_permissions(p: &CStr, perm: FilePermissions) -> io::Result<()> { + use crate::fs::{OpenOptions, Permissions}; - let mut options = OpenOptions::new(); - options.custom_flags(libc::O_NOFOLLOW); + let mut options = OpenOptions::new(); - let bytes = p.to_bytes(); - let os_str = OsStr::from_bytes(bytes); - options.open(Path::new(os_str))?.set_permissions(Permissions::from_inner(perm)) + // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it. + // Their filesystems do not have symbolic links, so no special handling is required. + #[cfg(not(any(target_os = "espidf", target_os = "horizon")))] + { + #[cfg(not(target_os = "wasi"))] + use crate::os::unix::fs::OpenOptionsExt; + #[cfg(target_os = "wasi")] + use crate::os::wasi::fs::OpenOptionsExt; + options.read(true).custom_flags(libc::O_NOFOLLOW); } - all(target_os = "linux", not(any(target_os = "espidf", target_os = "horizon"))) => { - cvt_r(|| unsafe { - libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, libc::AT_SYMLINK_NOFOLLOW) - }) - .map(|_| ()) + + // SAFETY: Since this function is called with `with_native_path` + // and that successfully converted the `&Path` to a `CString`, + // it should be safe to convert the `&CStr` back to a `Path`. + let os_str = unsafe { OsStr::from_encoded_bytes_unchecked(p.to_bytes()) }; + options.open(Path::new(os_str))?.set_permissions(Permissions::from_inner(perm)) + } + + // This res value is modified for platforms that support the `fchmodat` syscall. + #[allow(unused)] + let mut res: Result<(), core::io::Error> = Err(crate::io::ErrorKind::Unsupported.into()); + + // These platforms support `fchmodat`, so utilize this syscall over `open` + `fchmod` + #[cfg(any( + target_os = "linux", + target_os = "macos", + target_os = "freebsd", + target_os = "openbsd", + target_os = "netbsd", + target_os = "dragonfly", + target_os = "nto", + target_os = "qnx" + ))] + { + res = cvt_r(|| unsafe { + libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, libc::AT_SYMLINK_NOFOLLOW) + }) + .map(|_| ()); + } + + // If fchmodat fails with `ErrorKind::Unsupported` fallback to using open + fchmod. This is just in case + // for older systems like Ubuntu 20.04 where fchmodat fails with EOPNOTSUPP on both regular files and + // symlinks when AT_SYMLINK_NOFOLLOW is passed in. + match res { + Ok(_) => Ok(()), + Err(err) => { + if err.kind() == crate::io::ErrorKind::Unsupported { + match open_and_set_permissions(p, perm) { + Ok(_) => return Ok(()), + Err(e) => { + if e.kind() == crate::io::ErrorKind::FilesystemLoop { + // When open is used with O_NOFOLLOW flag, if the trailing component of + // a path is a symbolic link, it should fail with ELOOP error. Instead of + // returning `FilesystemLoop`, this returns `Unsupported` to keep it consistent + // with what `fchmodat` would return when chmoding a symlink using AT_SYMLINK_NOFOLLOW. + return Err(err); + } + return Err(e); + } + } + } + + Err(err) } - _ => cvt_r(|| unsafe { libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, 0) }).map(|_| ()), } } diff --git a/library/std/src/sys/io/error/generic.rs b/library/std/src/sys/io/error/generic.rs index fc70fbaba7e8c..1ff0e9303041d 100644 --- a/library/std/src/sys/io/error/generic.rs +++ b/library/std/src/sys/io/error/generic.rs @@ -1,3 +1,5 @@ +use crate::fmt; + pub fn errno() -> i32 { 0 } @@ -10,6 +12,6 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { crate::io::ErrorKind::Uncategorized } -pub fn error_string(_errno: i32) -> String { - "operation successful".to_string() +pub fn format_error(_errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("operation successful") } diff --git a/library/std/src/sys/io/error/hermit.rs b/library/std/src/sys/io/error/hermit.rs index 5f42144bb7cfb..28735c4c8275c 100644 --- a/library/std/src/sys/io/error/hermit.rs +++ b/library/std/src/sys/io/error/hermit.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::{fmt, io}; pub fn errno() -> i32 { unsafe { hermit_abi::get_errno() } @@ -30,6 +30,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { } } -pub fn error_string(errno: i32) -> String { - hermit_abi::error_string(errno).to_string() +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let description = hermit_abi::error_string(errno); + f.write_str(description) } diff --git a/library/std/src/sys/io/error/motor.rs b/library/std/src/sys/io/error/motor.rs index 06417417e8554..3afbd3fa9b7f1 100644 --- a/library/std/src/sys/io/error/motor.rs +++ b/library/std/src/sys/io/error/motor.rs @@ -1,4 +1,4 @@ -use crate::io; +use crate::{fmt, io}; pub fn errno() -> io::RawOsError { // Not used in Motor OS because it is ambiguous: Motor OS @@ -57,11 +57,12 @@ pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { } } -pub fn error_string(errno: io::RawOsError) -> String { - let error: moto_rt::Error = match errno { +pub fn format_error(errno: io::RawOsError, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let error = match errno { x if x < 0 => moto_rt::Error::Unknown, x if x > u16::MAX.into() => moto_rt::Error::Unknown, - x => (x as moto_rt::ErrorCode).into(), /* u16 */ + x => moto_rt::Error::from(x as moto_rt::ErrorCode), /* u16 */ }; - format!("{}", error) + + write!(f, "{error}") } diff --git a/library/std/src/sys/io/error/sgx.rs b/library/std/src/sys/io/error/sgx.rs index b7b4030422e12..2d0827aad39ab 100644 --- a/library/std/src/sys/io/error/sgx.rs +++ b/library/std/src/sys/io/error/sgx.rs @@ -1,6 +1,6 @@ use fortanix_sgx_abi::{Error, RESULT_SUCCESS}; -use crate::io; +use crate::{fmt, io}; pub fn errno() -> i32 { RESULT_SUCCESS @@ -54,12 +54,13 @@ pub fn decode_error_kind(code: i32) -> io::ErrorKind { } } -pub fn error_string(errno: i32) -> String { +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { if errno == RESULT_SUCCESS { - "operation successful".into() + f.write_str("operation successful") } else if ((Error::UserRangeStart as _)..=(Error::UserRangeEnd as _)).contains(&errno) { - format!("user-specified error {errno:08x}") + write!(f, "user-specified error {errno:08x}") } else { - format!("{}", decode_error_kind(errno)) + let kind = decode_error_kind(errno); + write!(f, "{kind}") } } diff --git a/library/std/src/sys/io/error/solid.rs b/library/std/src/sys/io/error/solid.rs index 8e9503272abbc..ced354cb4c6e2 100644 --- a/library/std/src/sys/io/error/solid.rs +++ b/library/std/src/sys/io/error/solid.rs @@ -1,5 +1,5 @@ -use crate::io; use crate::sys::pal::error; +use crate::{fmt, io}; pub fn errno() -> i32 { 0 @@ -14,6 +14,6 @@ pub fn decode_error_kind(code: i32) -> io::ErrorKind { error::decode_error_kind(code) } -pub fn error_string(errno: i32) -> String { - if let Some(name) = error::error_name(errno) { name.to_owned() } else { format!("{errno}") } +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(name) = error::error_name(errno) { f.write_str(name) } else { write!(f, "{errno}") } } diff --git a/library/std/src/sys/io/error/uefi.rs b/library/std/src/sys/io/error/uefi.rs index bedea240d523b..a8793f2799be9 100644 --- a/library/std/src/sys/io/error/uefi.rs +++ b/library/std/src/sys/io/error/uefi.rs @@ -1,6 +1,6 @@ use r_efi::efi::Status; -use crate::io; +use crate::{fmt, io}; pub fn errno() -> io::RawOsError { 0 @@ -54,7 +54,7 @@ pub fn decode_error_kind(code: io::RawOsError) -> io::ErrorKind { } } -pub fn error_string(errno: io::RawOsError) -> String { +pub fn format_error(errno: io::RawOsError, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Keep the List in Alphabetical Order // The Messages are taken from UEFI Specification Appendix D - Status Codes #[rustfmt::skip] @@ -98,7 +98,7 @@ pub fn error_string(errno: io::RawOsError) -> String { Status::VOLUME_FULL => "There is no more space on the file system.", Status::VOLUME_CORRUPTED => "An inconstancy was detected on the file system causing the operating to fail.", Status::WRITE_PROTECTED => "The device cannot be written to.", - _ => return format!("Status: {errno}"), + _ => return write!(f, "Status: {errno}"), }; - msg.to_owned() + f.write_str(msg) } diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs index 12acde7311e4c..5f60abf9d9528 100644 --- a/library/std/src/sys/io/error/unix.rs +++ b/library/std/src/sys/io/error/unix.rs @@ -1,7 +1,7 @@ use crate::ffi::c_int; #[cfg(not(target_os = "teeos"))] use crate::ffi::{CStr, c_char}; -use crate::io; +use crate::{fmt, io}; unsafe extern "C" { #[cfg(not(any( @@ -195,7 +195,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { /// Gets a detailed string description for the given error number. #[cfg(any(target_family = "unix", target_os = "wasi"))] -pub fn error_string(errno: i32) -> String { +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { const TMPBUF_SZ: usize = if cfg!(target_os = "wasi") { 1024 } else { 128 }; unsafe extern "C" { @@ -226,11 +226,11 @@ pub fn error_string(errno: i32) -> String { let p = p as *const _; // We can't always expect a UTF-8 environment. When we don't get that luxury, // it's better to give a low-quality error message than none at all. - String::from_utf8_lossy(CStr::from_ptr(p).to_bytes()).into() + write!(f, "{}", CStr::from_ptr(p).display()) } } #[cfg(target_os = "teeos")] -pub fn error_string(_errno: i32) -> String { - "error string unimplemented".to_string() +pub fn format_error(_errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("error string unimplemented") } diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs index 0ca3aee389b3e..6056f1774c146 100644 --- a/library/std/src/sys/io/error/windows.rs +++ b/library/std/src/sys/io/error/windows.rs @@ -1,5 +1,5 @@ use crate::sys::pal::{api, c}; -use crate::{io, ptr}; +use crate::{fmt, io, ptr}; #[cfg(test)] mod tests; @@ -95,7 +95,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { } /// Gets a detailed string description for the given error number. -pub fn error_string(mut errnum: i32) -> String { +pub fn format_error(mut errnum: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut buf = [0 as c::WCHAR; 2048]; unsafe { @@ -131,21 +131,15 @@ pub fn error_string(mut errnum: i32) -> String { if res == 0 { // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId, let fm_err = errno(); - return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})"); + return write!(f, "OS Error {errnum} (FormatMessageW() returned error {fm_err})"); } match String::from_utf16(&buf[..res]) { - Ok(mut msg) => { + Ok(msg) => { // Trim trailing CRLF inserted by FormatMessageW - let len = msg.trim_ascii_end().len(); - msg.truncate(len); - msg + f.write_str(msg.trim_ascii_end()) } - Err(..) => format!( - "OS Error {} (FormatMessageW() returned \ - invalid UTF-16)", - errnum - ), + Err(..) => write!(f, "OS Error {} (FormatMessageW() returned invalid UTF-16)", errnum), } } } diff --git a/library/std/src/sys/io/error/windows/tests.rs b/library/std/src/sys/io/error/windows/tests.rs index 7fc545ad00666..088472eceab71 100644 --- a/library/std/src/sys/io/error/windows/tests.rs +++ b/library/std/src/sys/io/error/windows/tests.rs @@ -1,7 +1,7 @@ use crate::io::Error; use crate::sys::pal::c; -// tests `error_string` above +// tests `format_error` #[test] fn ntstatus_error() { const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001; diff --git a/library/std/src/sys/io/error/xous.rs b/library/std/src/sys/io/error/xous.rs index 2e9ea8e4f0928..bdecf437d0126 100644 --- a/library/std/src/sys/io/error/xous.rs +++ b/library/std/src/sys/io/error/xous.rs @@ -1,3 +1,4 @@ +use crate::fmt; use crate::os::xous::ffi::Error as XousError; pub fn errno() -> i32 { @@ -12,6 +13,7 @@ pub fn decode_error_kind(_code: i32) -> crate::io::ErrorKind { crate::io::ErrorKind::Uncategorized } -pub fn error_string(errno: i32) -> String { - Into::::into(errno).to_string() +pub fn format_error(errno: i32, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let error = XousError::from(errno); + write!(f, "{error}") } diff --git a/library/std/src/sys/io/mod.rs b/library/std/src/sys/io/mod.rs index 33182e4eb5539..b9c48e3fe6ba5 100644 --- a/library/std/src/sys/io/mod.rs +++ b/library/std/src/sys/io/mod.rs @@ -51,5 +51,5 @@ pub use error::errno_location; target_os = "wasi", ))] pub use error::set_errno; -pub use error::{decode_error_kind, errno, error_string, is_interrupted}; +pub use error::{decode_error_kind, errno, format_error, is_interrupted}; pub use is_terminal::is_terminal; diff --git a/library/std/src/sys/process/uefi.rs b/library/std/src/sys/process/uefi.rs index 0f5c7c9a58c40..8c233a0d2024e 100644 --- a/library/std/src/sys/process/uefi.rs +++ b/library/std/src/sys/process/uefi.rs @@ -8,7 +8,7 @@ use crate::num::{NonZero, NonZeroI32}; use crate::path::{Path, PathBuf}; use crate::process::StdioPipes; use crate::sys::fs::File; -use crate::sys::io::error_string; +use crate::sys::io::format_error; use crate::sys::pal::helpers; use crate::sys::unsupported; use crate::{fmt, io}; @@ -264,8 +264,7 @@ impl ExitStatus { impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = error_string(self.0.as_usize()); - write!(f, "{}", err_str) + format_error(self.0.as_usize(), f) } } @@ -280,8 +279,7 @@ pub struct ExitStatusError(r_efi::efi::Status); impl fmt::Debug for ExitStatusError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = error_string(self.0.as_usize()); - write!(f, "{}", err_str) + format_error(self.0.as_usize(), f) } } diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs index eba1e9ef1c5cf..da80d7cd8c599 100644 --- a/src/bootstrap/src/bin/rustdoc.rs +++ b/src/bootstrap/src/bin/rustdoc.rs @@ -65,7 +65,10 @@ fn main() { if let Some(crate_name) = parse_value_from_args(&args, "--crate-name") { // Add rust logo and set html root for all rustc crates. if crate_name.starts_with("rustc_") { - cmd.arg("-Ainternal_features") + // We use `-Zcrate-attr=allow` instead of `-A` to force rustdoc to forward this flag to + // the actual doctests. Otherwise those tests all receive the + // `feature(rustdoc_internals)` without receiving the `-A` which leads to errors. + cmd.arg("-Zcrate-attr=allow(internal_features)") .arg("-Zcrate-attr=doc(rust_logo)") .arg("-Zcrate-attr=doc(html_root_url = \"https://doc.rust-lang.org/nightly/nightly-rustc/\")"); diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index d41ce974c5009..7fecfe14cc578 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -141,11 +141,8 @@ pub fn libdir(target: TargetSelection) -> &'static str { /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. /// If the dylib_path_var is already set for this cmd, the old value will be overwritten! pub fn add_dylib_path(path: Vec, cmd: &mut BootstrapCommand) { - let mut list = dylib_path(); - for path in path { - list.insert(0, path); - } - cmd.env(dylib_path_var(), t!(env::join_paths(list))); + let paths = path.into_iter().chain(dylib_path()); + cmd.env(dylib_path_var(), t!(env::join_paths(paths))); } pub struct TimeIt(bool, Instant); diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md index db72c44a2dc92..854d66f96756c 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-reg.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-reg.md @@ -19,8 +19,8 @@ This tracks support for additional registers in architectures where inline assem | Architecture | Register class | Target feature | Allowed types | | ------------ | -------------- | -------------- | ------------- | -| LoongArch | `vreg` | `lsx` | `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | -| LoongArch | `xreg` | `lasx` | `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`,
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` | +| LoongArch | `vreg` | `lsx` | `i128`, `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` | +| LoongArch | `xreg` | `lasx` | `i128`, `f32`, `f64`,
`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2`,
`i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` | ## Register aliases diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cb7ddd0ec58e7..d7fbe64c30771 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -250,17 +250,21 @@ pub(crate) fn get_item_path(tcx: TyCtxt<'_>, def_id: DefId, kind: ItemType) -> V if let ItemType::Macro = kind { // Check to see if it is a macro 2.0 or built-in macro // More information in . - if matches!( - CStore::from_tcx(tcx).load_macro_untracked(tcx, def_id), - LoadedMacro::MacroDef { def, .. } if !def.macro_rules - ) { - once(crate_name).chain(relative).collect() + let is_macro_2_0_or_builtin = if let Some(local_def_id) = def_id.as_local() { + let (_, macro_def, _) = tcx.hir_expect_item(local_def_id).expect_macro(); + !macro_def.macro_rules } else { - vec![crate_name, *relative.last().expect("relative was empty")] + matches!( + CStore::from_tcx(tcx).load_macro_untracked(tcx, def_id), + LoadedMacro::MacroDef { def, .. } if !def.macro_rules + ) + }; + if !is_macro_2_0_or_builtin { + return vec![crate_name, *relative.last().expect("relative was empty")]; } - } else { - once(crate_name).chain(relative).collect() } + + once(crate_name).chain(relative).collect() } /// Record an external fully qualified name in the external_paths cache. diff --git a/tests/run-make/rustc-help/polonius-help.stdout b/tests/run-make/rustc-help/polonius-help.stdout new file mode 100644 index 0000000000000..b1dfd15c09958 --- /dev/null +++ b/tests/run-make/rustc-help/polonius-help.stdout @@ -0,0 +1 @@ + -Z polonius=val -- enable polonius-based borrow-checker (default: next) diff --git a/tests/run-make/rustc-help/rmake.rs b/tests/run-make/rustc-help/rmake.rs index 17811ef18449f..a5e733fb8d9fc 100644 --- a/tests/run-make/rustc-help/rmake.rs +++ b/tests/run-make/rustc-help/rmake.rs @@ -22,6 +22,12 @@ fn main() { // Check that all help options can be invoked at once let codegen_help = bare_rustc().arg("-Chelp").run().stdout_utf8(); let unstable_help = bare_rustc().arg("-Zhelp").run().stdout_utf8(); + let polonius_help = + format!("{}\n", unstable_help.lines().find(|line| line.contains("polonius=val")).unwrap()); + diff() + .expected_file("polonius-help.stdout") + .actual_text("rustc -Zhelp (polonius)", &polonius_help) + .run(); let lints_help = bare_rustc().arg("-Whelp").run().stdout_utf8(); let expected_all = format!("{help}{codegen_help}{unstable_help}{lints_help}"); let all_help = bare_rustc().args(["--help", "-Chelp", "-Zhelp", "-Whelp"]).run().stdout_utf8(); diff --git a/tests/rustdoc-html/auxiliary/generated_macro.rs b/tests/rustdoc-html/auxiliary/generated_macro.rs new file mode 100644 index 0000000000000..47a2eae5b3c2c --- /dev/null +++ b/tests/rustdoc-html/auxiliary/generated_macro.rs @@ -0,0 +1,17 @@ +//@ no-prefer-dynamic + +#![crate_type = "proc-macro"] + +use std::str::FromStr; + +extern crate proc_macro; + +#[proc_macro_derive(MyDeriveMacro)] +pub fn derive_my_derive_macro(item: proc_macro::TokenStream) -> proc_macro::TokenStream { + proc_macro::TokenStream::from_str(" + #[macro_export] + macro_rules! my_generated_macro { + ($my_macro_parameter: expr) => {}; + } + ").unwrap() +} diff --git a/tests/rustdoc-html/generated_macro.rs b/tests/rustdoc-html/generated_macro.rs new file mode 100644 index 0000000000000..3986930f8e631 --- /dev/null +++ b/tests/rustdoc-html/generated_macro.rs @@ -0,0 +1,16 @@ +// This test ensures that the macro generated by the proc macro has the correct +// "item-decl" code block. +// Regression test for . + +//@ aux-build:generated_macro.rs + +#![crate_name = "foo"] + +extern crate generated_macro; + +//@ has 'foo/macro.my_generated_macro.html' +//@ matches - '//*[@class="rust item-decl"]/code' \ +// 'macro_rules! my_generated_macro \{\s+\(\$my_macro_parameter:expr\) => \{ ... \};\s+\}' + +#[derive(generated_macro::MyDeriveMacro)] +struct MyStruct {} diff --git a/tests/rustdoc-ui/lints/redundant-explicit-links-ice.fixed b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.fixed new file mode 100644 index 0000000000000..bfd09e970db06 --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.fixed @@ -0,0 +1,13 @@ +// Regression test for . + +//@ run-rustfix + +#![deny(rustdoc::redundant_explicit_links)] + +//! [queue] +//~^ ERROR redundant explicit link target + +#[macro_export] +macro_rules! queue { + () => {}; +} diff --git a/tests/rustdoc-ui/lints/redundant-explicit-links-ice.rs b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.rs new file mode 100644 index 0000000000000..a129baecdb79f --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.rs @@ -0,0 +1,13 @@ +// Regression test for . + +//@ run-rustfix + +#![deny(rustdoc::redundant_explicit_links)] + +//! [queue](macro.queue.html) +//~^ ERROR redundant explicit link target + +#[macro_export] +macro_rules! queue { + () => {}; +} diff --git a/tests/rustdoc-ui/lints/redundant-explicit-links-ice.stderr b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.stderr new file mode 100644 index 0000000000000..2caf08e26936f --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant-explicit-links-ice.stderr @@ -0,0 +1,23 @@ +error: redundant explicit link target + --> $DIR/redundant-explicit-links-ice.rs:7:13 + | +LL | //! [queue](macro.queue.html) + | ----- ^^^^^^^^^^^^^^^^ explicit target is redundant + | | + | because label contains path that resolves to same destination + | + = note: when a link's destination is not specified, + the label is used to resolve intra-doc links +note: the lint level is defined here + --> $DIR/redundant-explicit-links-ice.rs:5:9 + | +LL | #![deny(rustdoc::redundant_explicit_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: remove explicit link target + | +LL - //! [queue](macro.queue.html) +LL + //! [queue] + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/asm/global-target-feature.rs b/tests/ui/asm/global-target-feature.rs new file mode 100644 index 0000000000000..d84b4d51e6582 --- /dev/null +++ b/tests/ui/asm/global-target-feature.rs @@ -0,0 +1,49 @@ +//@ build-pass +//@ add-minicore +//@ min-llvm-version: 23 +//@ ignore-backends: gcc +// +//@ revisions: riscv opt-0-bitcode-no opt-0 opt-s-bitcode-no +// +//@[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu -Clto=thin +//@[riscv] needs-llvm-components: riscv +// +//@[opt-0-bitcode-no] compile-flags: --target armv7r-none-eabihf -Copt-level=0 -Cembed-bitcode=no +//@[opt-0-bitcode-no] needs-llvm-components: arm +// +//@[opt-0] compile-flags: --target armv7r-none-eabihf -Copt-level=0 +//@[opt-0] needs-llvm-components: arm +// +//@[opt-s-bitcode-no] compile-flags: --target armv7r-none-eabihf -Copt-level=s -Cembed-bitcode=no +//@[opt-s-bitcode-no] needs-llvm-components: arm + +// Regression test for +// +// - https://github.com/llvm/llvm-project/issues/61991 +// - https://github.com/rust-lang/rust/issues/80608 +// - https://github.com/rust-lang/rust/issues/127269 +// +// Since LLVM 23 target features are taken into account for module-level assembly. + +#![feature(no_core)] +#![no_core] +#![crate_type = "lib"] + +extern crate minicore; +use minicore::*; + +#[cfg(target_arch = "riscv64")] +global_asm!("fld f0, 0(sp)"); + +#[cfg(target_arch = "arm")] +global_asm!( + r#" +.section .text.startup +.global _start +.code 32 +.align 0 + +_start: + vmsr fpexc, r0 +"# +); diff --git a/tests/ui/asm/inline-syntax.arm.stderr b/tests/ui/asm/inline-syntax.arm.stderr index 5b4eb3cc1409c..5b193d26c8776 100644 --- a/tests/ui/asm/inline-syntax.arm.stderr +++ b/tests/ui/asm/inline-syntax.arm.stderr @@ -13,6 +13,7 @@ note: instantiated into assembly here | LL | .intel_syntax noprefix | ^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: unknown directive --> $DIR/inline-syntax.rs:21:15 diff --git a/tests/ui/asm/inline-syntax.rs b/tests/ui/asm/inline-syntax.rs index b48841aabfe7b..63395c1096c09 100644 --- a/tests/ui/asm/inline-syntax.rs +++ b/tests/ui/asm/inline-syntax.rs @@ -3,10 +3,10 @@ //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu //@[x86_64] check-pass //@[x86_64] needs-llvm-components: x86 -// LLVM 19+ has full support for 64-bit cookies. //@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf //@[arm] build-fail //@[arm] needs-llvm-components: arm +//@[arm] min-llvm-version: 23 //@ ignore-backends: gcc #![feature(no_core)] diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr index 28ac455c06441..dca21ad47ea10 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32d.stderr @@ -1,41 +1,51 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 + | +LL | asm!("/* {} */", in(vreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", in(vreg) f); | ^^^^^^^^^^ @@ -45,7 +55,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:55:26 + --> $DIR/bad-reg.rs:59:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ @@ -55,7 +65,7 @@ LL | asm!("/* {} */", out(vreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:57:26 + --> $DIR/bad-reg.rs:61:26 | LL | asm!("/* {} */", in(vreg) d); | ^^^^^^^^^^ @@ -65,7 +75,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:60:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", out(vreg) d); | ^^^^^^^^^^^ @@ -75,7 +85,17 @@ LL | asm!("/* {} */", out(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:65:26 + --> $DIR/bad-reg.rs:69:26 + | +LL | asm!("/* {} */", in(xreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `xreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", in(xreg) f); | ^^^^^^^^^^ @@ -85,7 +105,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:68:26 + --> $DIR/bad-reg.rs:75:26 | LL | asm!("/* {} */", out(xreg) _); | ^^^^^^^^^^^ @@ -95,7 +115,7 @@ LL | asm!("/* {} */", out(xreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:70:26 + --> $DIR/bad-reg.rs:77:26 | LL | asm!("/* {} */", in(xreg) d); | ^^^^^^^^^^ @@ -105,7 +125,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:80:26 | LL | asm!("/* {} */", out(xreg) d); | ^^^^^^^^^^^ @@ -115,7 +135,7 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^^ @@ -125,7 +145,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -135,7 +155,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -145,7 +165,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -154,8 +174,18 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:53:35 + | +LL | asm!("/* {} */", in(vreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:56:35 | LL | asm!("/* {} */", in(vreg) f); | ^ @@ -165,7 +195,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:57:35 + --> $DIR/bad-reg.rs:61:35 | LL | asm!("/* {} */", in(vreg) d); | ^ @@ -175,7 +205,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:60:36 + --> $DIR/bad-reg.rs:64:36 | LL | asm!("/* {} */", out(vreg) d); | ^ @@ -184,8 +214,18 @@ LL | asm!("/* {} */", out(vreg) d); = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:69:35 + | +LL | asm!("/* {} */", in(xreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:65:35 + --> $DIR/bad-reg.rs:72:35 | LL | asm!("/* {} */", in(xreg) f); | ^ @@ -195,7 +235,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:70:35 + --> $DIR/bad-reg.rs:77:35 | LL | asm!("/* {} */", in(xreg) d); | ^ @@ -205,7 +245,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:73:36 + --> $DIR/bad-reg.rs:80:36 | LL | asm!("/* {} */", out(xreg) d); | ^ @@ -215,7 +255,7 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:77:42 + --> $DIR/bad-reg.rs:84:42 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^ @@ -225,7 +265,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:42 + --> $DIR/bad-reg.rs:89:42 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^ @@ -235,7 +275,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:29 + --> $DIR/bad-reg.rs:94:29 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -245,7 +285,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:43 + --> $DIR/bad-reg.rs:94:43 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -254,6 +294,6 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 28 previous errors +error: aborting due to 32 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr index 1ee1b86989c4d..9ffab83db95cb 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch32_ilp32s.stderr @@ -1,41 +1,51 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 + | +LL | asm!("/* {} */", in(vreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", in(vreg) f); | ^^^^^^^^^^ @@ -45,7 +55,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:55:26 + --> $DIR/bad-reg.rs:59:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ @@ -55,7 +65,7 @@ LL | asm!("/* {} */", out(vreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:57:26 + --> $DIR/bad-reg.rs:61:26 | LL | asm!("/* {} */", in(vreg) d); | ^^^^^^^^^^ @@ -65,7 +75,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:60:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", out(vreg) d); | ^^^^^^^^^^^ @@ -75,7 +85,17 @@ LL | asm!("/* {} */", out(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:65:26 + --> $DIR/bad-reg.rs:69:26 + | +LL | asm!("/* {} */", in(xreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `xreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", in(xreg) f); | ^^^^^^^^^^ @@ -85,7 +105,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:68:26 + --> $DIR/bad-reg.rs:75:26 | LL | asm!("/* {} */", out(xreg) _); | ^^^^^^^^^^^ @@ -95,7 +115,7 @@ LL | asm!("/* {} */", out(xreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:70:26 + --> $DIR/bad-reg.rs:77:26 | LL | asm!("/* {} */", in(xreg) d); | ^^^^^^^^^^ @@ -105,7 +125,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:80:26 | LL | asm!("/* {} */", out(xreg) d); | ^^^^^^^^^^^ @@ -115,7 +135,7 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^^ @@ -125,7 +145,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -135,7 +155,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -145,7 +165,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -155,31 +175,41 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:42:26 + --> $DIR/bad-reg.rs:43:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:44:26 + --> $DIR/bad-reg.rs:45:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:46:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:48:26 + --> $DIR/bad-reg.rs:49:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:53:35 + | +LL | asm!("/* {} */", in(vreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:56:35 | LL | asm!("/* {} */", in(vreg) f); | ^ @@ -189,7 +219,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:57:35 + --> $DIR/bad-reg.rs:61:35 | LL | asm!("/* {} */", in(vreg) d); | ^ @@ -199,7 +229,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:60:36 + --> $DIR/bad-reg.rs:64:36 | LL | asm!("/* {} */", out(vreg) d); | ^ @@ -208,8 +238,18 @@ LL | asm!("/* {} */", out(vreg) d); = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:69:35 + | +LL | asm!("/* {} */", in(xreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:65:35 + --> $DIR/bad-reg.rs:72:35 | LL | asm!("/* {} */", in(xreg) f); | ^ @@ -219,7 +259,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:70:35 + --> $DIR/bad-reg.rs:77:35 | LL | asm!("/* {} */", in(xreg) d); | ^ @@ -229,7 +269,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:73:36 + --> $DIR/bad-reg.rs:80:36 | LL | asm!("/* {} */", out(xreg) d); | ^ @@ -239,13 +279,13 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:77:18 + --> $DIR/bad-reg.rs:84:18 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:77:42 + --> $DIR/bad-reg.rs:84:42 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^ @@ -255,13 +295,13 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:89:18 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:42 + --> $DIR/bad-reg.rs:89:42 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^ @@ -271,7 +311,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:29 + --> $DIR/bad-reg.rs:94:29 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -281,7 +321,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:43 + --> $DIR/bad-reg.rs:94:43 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -290,6 +330,6 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 34 previous errors +error: aborting due to 38 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr index 97462d6dc5f0b..067dd354f3093 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64d.stderr @@ -1,41 +1,41 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error: register `$vr0` conflicts with register `$f0` - --> $DIR/bad-reg.rs:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ----------- ^^^^^^^^^^^^ register `$vr0` @@ -43,7 +43,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); | register `$f0` error: register `$xr0` conflicts with register `$f0` - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ----------- ^^^^^^^^^^^^ register `$xr0` @@ -51,7 +51,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); | register `$f0` error: register `$xr0` conflicts with register `$vr0` - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ------------ ^^^^^^^^^^^^ register `$xr0` diff --git a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr index 1ee1b86989c4d..9ffab83db95cb 100644 --- a/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr +++ b/tests/ui/asm/loongarch/bad-reg.loongarch64_lp64s.stderr @@ -1,41 +1,51 @@ error: invalid register `$r0`: constant zero cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:28:18 + --> $DIR/bad-reg.rs:29:18 | LL | asm!("", out("$r0") _); | ^^^^^^^^^^^^ error: invalid register `$tp`: reserved for TLS - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("$tp") _); | ^^^^^^^^^^^^ error: invalid register `$sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("$sp") _); | ^^^^^^^^^^^^ error: invalid register `$r21`: reserved by the ABI - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("$r21") _); | ^^^^^^^^^^^^^ error: invalid register `$fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("$fp") _); | ^^^^^^^^^^^^ error: invalid register `$r31`: $r31 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("$r31") _); | ^^^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 + | +LL | asm!("/* {} */", in(vreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `vreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", in(vreg) f); | ^^^^^^^^^^ @@ -45,7 +55,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:55:26 + --> $DIR/bad-reg.rs:59:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ @@ -55,7 +65,7 @@ LL | asm!("/* {} */", out(vreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:57:26 + --> $DIR/bad-reg.rs:61:26 | LL | asm!("/* {} */", in(vreg) d); | ^^^^^^^^^^ @@ -65,7 +75,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:60:26 + --> $DIR/bad-reg.rs:64:26 | LL | asm!("/* {} */", out(vreg) d); | ^^^^^^^^^^^ @@ -75,7 +85,17 @@ LL | asm!("/* {} */", out(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:65:26 + --> $DIR/bad-reg.rs:69:26 + | +LL | asm!("/* {} */", in(xreg) q); + | ^^^^^^^^^^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: register class `xreg` can only be used as a clobber in stable + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", in(xreg) f); | ^^^^^^^^^^ @@ -85,7 +105,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:68:26 + --> $DIR/bad-reg.rs:75:26 | LL | asm!("/* {} */", out(xreg) _); | ^^^^^^^^^^^ @@ -95,7 +115,7 @@ LL | asm!("/* {} */", out(xreg) _); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:70:26 + --> $DIR/bad-reg.rs:77:26 | LL | asm!("/* {} */", in(xreg) d); | ^^^^^^^^^^ @@ -105,7 +125,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:80:26 | LL | asm!("/* {} */", out(xreg) d); | ^^^^^^^^^^^ @@ -115,7 +135,7 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:77:31 + --> $DIR/bad-reg.rs:84:31 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^^ @@ -125,7 +145,7 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:31 + --> $DIR/bad-reg.rs:89:31 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -135,7 +155,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:18 + --> $DIR/bad-reg.rs:94:18 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -145,7 +165,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `xreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:87:32 + --> $DIR/bad-reg.rs:94:32 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^^^^^^^^^^^^ @@ -155,31 +175,41 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:42:26 + --> $DIR/bad-reg.rs:43:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:44:26 + --> $DIR/bad-reg.rs:45:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:46:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:48:26 + --> $DIR/bad-reg.rs:49:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:53:35 + | +LL | asm!("/* {} */", in(vreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:56:35 | LL | asm!("/* {} */", in(vreg) f); | ^ @@ -189,7 +219,7 @@ LL | asm!("/* {} */", in(vreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:57:35 + --> $DIR/bad-reg.rs:61:35 | LL | asm!("/* {} */", in(vreg) d); | ^ @@ -199,7 +229,7 @@ LL | asm!("/* {} */", in(vreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:60:36 + --> $DIR/bad-reg.rs:64:36 | LL | asm!("/* {} */", out(vreg) d); | ^ @@ -208,8 +238,18 @@ LL | asm!("/* {} */", out(vreg) d); = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: type `u128` cannot be used with this register class in stable + --> $DIR/bad-reg.rs:69:35 + | +LL | asm!("/* {} */", in(xreg) q); + | ^ + | + = note: see issue #133416 for more information + = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:65:35 + --> $DIR/bad-reg.rs:72:35 | LL | asm!("/* {} */", in(xreg) f); | ^ @@ -219,7 +259,7 @@ LL | asm!("/* {} */", in(xreg) f); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:70:35 + --> $DIR/bad-reg.rs:77:35 | LL | asm!("/* {} */", in(xreg) d); | ^ @@ -229,7 +269,7 @@ LL | asm!("/* {} */", in(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:73:36 + --> $DIR/bad-reg.rs:80:36 | LL | asm!("/* {} */", out(xreg) d); | ^ @@ -239,13 +279,13 @@ LL | asm!("/* {} */", out(xreg) d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:77:18 + --> $DIR/bad-reg.rs:84:18 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:77:42 + --> $DIR/bad-reg.rs:84:42 | LL | asm!("", in("$f0") f, in("$vr0") d); | ^ @@ -255,13 +295,13 @@ LL | asm!("", in("$f0") f, in("$vr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:89:18 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^^^^^^^^^^^ error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:42 + --> $DIR/bad-reg.rs:89:42 | LL | asm!("", in("$f0") f, in("$xr0") d); | ^ @@ -271,7 +311,7 @@ LL | asm!("", in("$f0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:29 + --> $DIR/bad-reg.rs:94:29 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -281,7 +321,7 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `f64` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:87:43 + --> $DIR/bad-reg.rs:94:43 | LL | asm!("", in("$vr0") f, in("$xr0") d); | ^ @@ -290,6 +330,6 @@ LL | asm!("", in("$vr0") f, in("$xr0") d); = help: add `#![feature(asm_experimental_reg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 34 previous errors +error: aborting due to 38 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs index 6bda28eb10fde..ac2eeb7d78a70 100644 --- a/tests/ui/asm/loongarch/bad-reg.rs +++ b/tests/ui/asm/loongarch/bad-reg.rs @@ -8,6 +8,7 @@ //@[loongarch64_lp64d] needs-llvm-components: loongarch //@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat //@[loongarch64_lp64s] needs-llvm-components: loongarch +//@ min-llvm-version: 23 //@ ignore-backends: gcc #![cfg_attr(loongarch64_lp64d, feature(asm_experimental_reg))] @@ -20,7 +21,7 @@ extern crate minicore; use minicore::*; fn f() { - let mut x = 0; + let mut q = 0_u128; let mut f = 0.0_f32; let mut d = 0.0_f64; unsafe { @@ -49,6 +50,9 @@ fn f() { //[loongarch32_ilp32s,loongarch64_lp64s]~^ ERROR register class `freg` requires at least one of the following target features: d, f asm!("", out("$vr0") _); // ok + asm!("/* {} */", in(vreg) q); + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `u128` cannot be used with this register class in stable asm!("/* {} */", in(vreg) f); //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `vreg` can only be used as a clobber in stable //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f32` cannot be used with this register class in stable @@ -62,6 +66,9 @@ fn f() { //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f64` cannot be used with this register class in stable asm!("", out("$xr0") _); // ok + asm!("/* {} */", in(xreg) q); + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable + //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `u128` cannot be used with this register class in stable asm!("/* {} */", in(xreg) f); //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~^ ERROR register class `xreg` can only be used as a clobber in stable //[loongarch32_ilp32s,loongarch32_ilp32d,loongarch64_lp64s]~| ERROR type `f32` cannot be used with this register class in stable diff --git a/tests/ui/const-generics/generic_const_parameter_types/inherent-type-const.rs b/tests/ui/const-generics/generic_const_parameter_types/inherent-type-const.rs new file mode 100644 index 0000000000000..86eab5ec70eb2 --- /dev/null +++ b/tests/ui/const-generics/generic_const_parameter_types/inherent-type-const.rs @@ -0,0 +1,22 @@ +//@ check-pass +#![feature( + min_generic_const_args, + generic_const_parameter_types, + inherent_associated_types, + min_adt_const_params, + const_param_ty_trait +)] + +struct ThreeTypes(T1, T2, T3); + +impl ThreeTypes { + type const INHERENT: [T3; 0] = []; +} + +struct Struct; + +fn f() -> Struct<{ core::direct_const_arg!(ThreeTypes::::INHERENT) }> { + Struct +} + +fn main() {} diff --git a/tests/ui/contracts/empty-ensures.rs b/tests/ui/contracts/empty-ensures.rs index 79e57df6eb984..242e903b7cc96 100644 --- a/tests/ui/contracts/empty-ensures.rs +++ b/tests/ui/contracts/empty-ensures.rs @@ -6,7 +6,7 @@ extern crate core; use core::contracts::ensures; #[ensures()] -//~^ ERROR expected an `Fn(&_)` closure, found `()` [E0277] +//~^ ERROR `ensures` attribute requires an argument fn foo(x: u32) -> u32 { x * 2 } diff --git a/tests/ui/contracts/empty-ensures.stderr b/tests/ui/contracts/empty-ensures.stderr index b87f709eeb7a4..369ba431b62ce 100644 --- a/tests/ui/contracts/empty-ensures.stderr +++ b/tests/ui/contracts/empty-ensures.stderr @@ -1,16 +1,8 @@ -error[E0277]: expected an `Fn(&_)` closure, found `()` +error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]` --> $DIR/empty-ensures.rs:8:1 | LL | #[ensures()] | ^^^^^^^^^^^^ - | | - | expected an `Fn(&_)` closure, found `()` - | required by a bound introduced by this call - | - = help: the trait `for<'a> Fn(&'a _)` is not implemented for `()` -note: required by a bound in `build_check_ensures` - --> $SRC_DIR/core/src/contracts.rs:LL:COL error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/contracts/empty-requires.rs b/tests/ui/contracts/empty-requires.rs index dedcc10d52cb0..eae86607acf31 100644 --- a/tests/ui/contracts/empty-requires.rs +++ b/tests/ui/contracts/empty-requires.rs @@ -1,4 +1,3 @@ -//@ dont-require-annotations: NOTE //@ compile-flags: -Zcontract-checks=yes #![expect(incomplete_features)] #![feature(contracts)] @@ -7,8 +6,7 @@ extern crate core; use core::contracts::requires; #[requires()] -//~^ ERROR mismatched types [E0308] -//~| NOTE expected `bool`, found `()` +//~^ ERROR `requires` attribute requires an argument fn foo(x: u32) -> u32 { x * 2 } diff --git a/tests/ui/contracts/empty-requires.stderr b/tests/ui/contracts/empty-requires.stderr index 702b8a23c55e3..c8fa644702259 100644 --- a/tests/ui/contracts/empty-requires.stderr +++ b/tests/ui/contracts/empty-requires.stderr @@ -1,9 +1,8 @@ -error[E0308]: mismatched types - --> $DIR/empty-requires.rs:9:1 +error: `requires` attribute requires an argument, e.g., `#[requires(condition)]` + --> $DIR/empty-requires.rs:8:1 | LL | #[requires()] - | ^^^^^^^^^^^^^ expected `bool`, found `()` + | ^^^^^^^^^^^^^ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/lint/single-use-lifetimes-issue-146834.rs b/tests/ui/lint/single-use-lifetimes-issue-146834.rs new file mode 100644 index 0000000000000..8c03e40fa8070 --- /dev/null +++ b/tests/ui/lint/single-use-lifetimes-issue-146834.rs @@ -0,0 +1,18 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/146834. + +//@ compile-flags: -Wsingle-use-lifetimes +//@ edition: 2024 + +#![expect(incomplete_features)] +#![feature(contracts)] + +#[core::contracts::ensures] +//~^ ERROR `ensures` attribute requires an argument +fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + //~^ ERROR missing lifetime specifiers + //~| WARN lifetime parameter `'a` only used once + //~| WARN lifetime parameter `'b` only used once + loop {} +} + +fn main() {} diff --git a/tests/ui/lint/single-use-lifetimes-issue-146834.stderr b/tests/ui/lint/single-use-lifetimes-issue-146834.stderr new file mode 100644 index 0000000000000..d7b84680fd081 --- /dev/null +++ b/tests/ui/lint/single-use-lifetimes-issue-146834.stderr @@ -0,0 +1,55 @@ +error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]` + --> $DIR/single-use-lifetimes-issue-146834.rs:9:1 + | +LL | #[core::contracts::ensures] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0106]: missing lifetime specifiers + --> $DIR/single-use-lifetimes-issue-146834.rs:11:42 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ------- ------- ^ ^ expected named lifetime parameter + | | + | expected named lifetime parameter + | + = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments +note: these named lifetimes are available to use + --> $DIR/single-use-lifetimes-issue-146834.rs:11:6 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ^^ ^^ +help: consider using one of the available lifetimes here + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&'lifetime i32, &'lifetime i32) { + | +++++++++ +++++++++ + +warning: lifetime parameter `'a` only used once + --> $DIR/single-use-lifetimes-issue-146834.rs:11:6 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ^^ -- ...is used only here + | | + | this lifetime... + | + = note: requested on the command line with `-W single-use-lifetimes` +help: elide the single-use lifetime + | +LL - fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { +LL + fn f<'b>(a: &i32, b: &'b i32) -> (&i32, &i32) { + | + +warning: lifetime parameter `'b` only used once + --> $DIR/single-use-lifetimes-issue-146834.rs:11:10 + | +LL | fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { + | ^^ this lifetime... -- ...is used only here + | +help: elide the single-use lifetime + | +LL - fn f<'a, 'b>(a: &'a i32, b: &'b i32) -> (&i32, &i32) { +LL + fn f<'a>(a: &'a i32, b: &i32) -> (&i32, &i32) { + | + +error: aborting due to 2 previous errors; 2 warnings emitted + +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs index 2b1bacf7e0c31..db85d496991f7 100644 --- a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs +++ b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs @@ -4,7 +4,7 @@ struct T; impl T { - #[core::contracts::ensures] //~ ERROR expected an `Fn(&_)` closure, found `()` + #[core::contracts::ensures] //~ ERROR `ensures` attribute requires an argument fn b() {(loop)} //~^ ERROR expected `{`, found `)` //~| ERROR expected `{`, found `)` diff --git a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr index 56dbdae14189b..ab6459bdc919a 100644 --- a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr +++ b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr @@ -6,6 +6,12 @@ LL | fn b() {(loop)} | | | while parsing this `loop` expression +error: `ensures` attribute requires an argument, e.g., `#[ensures(|result: &T| condition)]` + --> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5 + | +LL | #[core::contracts::ensures] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: expected `{`, found `)` --> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:8:18 | @@ -16,19 +22,5 @@ LL | fn b() {(loop)} | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error[E0277]: expected an `Fn(&_)` closure, found `()` - --> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5 - | -LL | #[core::contracts::ensures] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected an `Fn(&_)` closure, found `()` - | required by a bound introduced by this call - | - = help: the trait `for<'a> Fn(&'a _)` is not implemented for `()` -note: required by a bound in `build_check_ensures` - --> $SRC_DIR/core/src/contracts.rs:LL:COL - error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`.