diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 63b0809d0d8c9..8ca5f0f7228e3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -38,6 +38,17 @@ impl NoArgsAttributeParser for PassByValueParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue; } +pub(crate) struct RustcShouldNotBeCalledOnConstItems; +impl NoArgsAttributeParser for RustcShouldNotBeCalledOnConstItems { + const PATH: &[Symbol] = &[sym::rustc_should_not_be_called_on_const_items]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); + const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcShouldNotBeCalledOnConstItems; +} + pub(crate) struct AutomaticallyDerivedParser; impl NoArgsAttributeParser for AutomaticallyDerivedParser { const PATH: &[Symbol] = &[sym::automatically_derived]; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index d1777991731c0..99e6c748dbe90 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -39,6 +39,7 @@ use crate::attributes::link_attrs::{ }; use crate::attributes::lint_helpers::{ AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser, + RustcShouldNotBeCalledOnConstItems, }; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::macro_attrs::{ @@ -244,6 +245,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index fde7dd6ef7a85..56b4a4700fa8c 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -9,8 +9,8 @@ use libc::{c_char, c_int, c_void, size_t}; use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::versioned_llvm_target; use rustc_codegen_ssa::back::write::{ - BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig, - TargetMachineFactoryFn, + BitcodeSection, CodegenContext, EmitObj, InlineAsmError, ModuleConfig, + TargetMachineFactoryConfig, TargetMachineFactoryFn, }; use rustc_codegen_ssa::base::wants_wasm_eh; use rustc_codegen_ssa::traits::*; @@ -434,7 +434,7 @@ fn report_inline_asm( level: llvm::DiagnosticLevel, cookie: u64, source: Option<(String, Vec)>, -) { +) -> InlineAsmError { // In LTO build we may get srcloc values from other crates which are invalid // since they use a different source map. To be safe we just suppress these // in LTO builds. @@ -454,7 +454,7 @@ fn report_inline_asm( llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note, }; let msg = msg.trim_prefix("error: ").to_string(); - cgcx.diag_emitter.inline_asm_error(span, msg, level, source); + InlineAsmError { span, msg, level, source } } unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) { @@ -466,7 +466,13 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void match unsafe { llvm::diagnostic::Diagnostic::unpack(info) } { llvm::diagnostic::InlineAsm(inline) => { - report_inline_asm(cgcx, inline.message, inline.level, inline.cookie, inline.source); + cgcx.diag_emitter.inline_asm_error(report_inline_asm( + cgcx, + inline.message, + inline.level, + inline.cookie, + inline.source, + )); } llvm::diagnostic::Optimization(opt) => { @@ -765,6 +771,13 @@ pub(crate) unsafe fn llvm_optimize( llvm_plugins.len(), ) }; + + if cgcx.target_is_like_gpu && config.offload.contains(&config::Offload::Enable) { + unsafe { + llvm::LLVMRustBundleImages(module.module_llvm.llmod(), module.module_llvm.tm.raw()); + } + } + result.into_result().unwrap_or_else(|()| llvm_err(dcx, LlvmError::RunLlvmPasses)) } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index ca64d96c2a33c..34f0e4b953381 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1641,6 +1641,9 @@ unsafe extern "C" { Name: *const c_char, ) -> &'a Value; + /// Processes the module and writes it in an offload compatible way into a "host.out" file. + pub(crate) fn LLVMRustBundleImages<'a>(M: &'a Module, TM: &'a TargetMachine) -> bool; + /// Writes a module to the specified path. Returns 0 on success. pub(crate) fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index fc1edec8de843..3e36bd8552b18 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1208,6 +1208,7 @@ pub struct CguMessage; // - `is_lint`: lints aren't relevant during codegen. // - `emitted_at`: not used for codegen diagnostics. struct Diagnostic { + span: Vec, level: Level, messages: Vec<(DiagMessage, Style)>, code: Option, @@ -1218,7 +1219,7 @@ struct Diagnostic { // A cut-down version of `rustc_errors::Subdiag` that impls `Send`. It's // missing the following fields from `rustc_errors::Subdiag`. // - `span`: it doesn't impl `Send`. -pub(crate) struct Subdiagnostic { +struct Subdiagnostic { level: Level, messages: Vec<(DiagMessage, Style)>, } @@ -1897,10 +1898,17 @@ fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>( enum SharedEmitterMessage { Diagnostic(Diagnostic), - InlineAsmError(SpanData, String, Level, Option<(String, Vec)>), + InlineAsmError(InlineAsmError), Fatal(String), } +pub struct InlineAsmError { + pub span: SpanData, + pub msg: String, + pub level: Level, + pub source: Option<(String, Vec)>, +} + #[derive(Clone)] pub struct SharedEmitter { sender: Sender, @@ -1917,14 +1925,8 @@ impl SharedEmitter { (SharedEmitter { sender }, SharedEmitterMain { receiver }) } - pub fn inline_asm_error( - &self, - span: SpanData, - msg: String, - level: Level, - source: Option<(String, Vec)>, - ) { - drop(self.sender.send(SharedEmitterMessage::InlineAsmError(span, msg, level, source))); + pub fn inline_asm_error(&self, err: InlineAsmError) { + drop(self.sender.send(SharedEmitterMessage::InlineAsmError(err))); } fn fatal(&self, msg: &str) { @@ -1940,7 +1942,7 @@ impl Emitter for SharedEmitter { ) { // Check that we aren't missing anything interesting when converting to // the cut-down local `DiagInner`. - assert_eq!(diag.span, MultiSpan::new()); + assert!(!diag.span.has_span_labels()); assert_eq!(diag.suggestions, Suggestions::Enabled(vec![])); assert_eq!(diag.sort_span, rustc_span::DUMMY_SP); assert_eq!(diag.is_lint, None); @@ -1949,6 +1951,7 @@ impl Emitter for SharedEmitter { let args = mem::replace(&mut diag.args, DiagArgMap::default()); drop( self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic { + span: diag.span.primary_spans().iter().map(|span| span.data()).collect::>(), level: diag.level(), messages: diag.messages, code: diag.code, @@ -1993,6 +1996,9 @@ impl SharedEmitterMain { let dcx = sess.dcx(); let mut d = rustc_errors::DiagInner::new_with_messages(diag.level, diag.messages); + d.span = MultiSpan::from_spans( + diag.span.into_iter().map(|span| span.span()).collect(), + ); d.code = diag.code; // may be `None`, that's ok d.children = diag .children @@ -2007,15 +2013,15 @@ impl SharedEmitterMain { dcx.emit_diagnostic(d); sess.dcx().abort_if_errors(); } - Ok(SharedEmitterMessage::InlineAsmError(span, msg, level, source)) => { - assert_matches!(level, Level::Error | Level::Warning | Level::Note); - let mut err = Diag::<()>::new(sess.dcx(), level, msg); - if !span.is_dummy() { - err.span(span.span()); + Ok(SharedEmitterMessage::InlineAsmError(inner)) => { + assert_matches!(inner.level, Level::Error | Level::Warning | Level::Note); + let mut err = Diag::<()>::new(sess.dcx(), inner.level, inner.msg); + if !inner.span.is_dummy() { + err.span(inner.span.span()); } // Point to the generated assembly if it is available. - if let Some((buffer, spans)) = source { + if let Some((buffer, spans)) = inner.source { let source = sess .source_map() .new_source_file(FileName::inline_asm_source_code(&buffer), buffer); diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 64dcf3c1f72d8..085403c8ef36b 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -455,10 +455,6 @@ impl MultiSpan { replacements_occurred } - pub fn pop_span_label(&mut self) -> Option<(Span, DiagMessage)> { - self.span_labels.pop() - } - /// Returns the strings to highlight. We always ensure that there /// is an entry for each of the primary spans -- for each primary /// span `P`, if there is at least one label with span `P`, we return diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index ce7dd16cd19cb..c1e947720452c 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1267,6 +1267,11 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ EncodeCrossCrate::Yes, "`#[rustc_as_ptr]` is used to mark functions returning pointers to their inner allocations." ), + rustc_attr!( + rustc_should_not_be_called_on_const_items, Normal, template!(Word), ErrorFollowing, + EncodeCrossCrate::Yes, + "`#[rustc_should_not_be_called_on_const_items]` is used to mark methods that don't make sense to be called on interior mutable consts." + ), rustc_attr!( rustc_pass_by_value, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 4ba64b240ac03..708210ac6c6e4 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -701,6 +701,9 @@ pub enum AttributeKind { /// Represents `#[rustc_pass_indirectly_in_non_rustic_abis]` RustcPassIndirectlyInNonRusticAbis(Span), + /// Represents `#[rustc_should_not_be_called_on_const_items]` + RustcShouldNotBeCalledOnConstItems(Span), + /// Represents `#[rustc_simd_monomorphize_lane_limit = "N"]`. RustcSimdMonomorphizeLaneLimit(Limit), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 2ccfdc2ad983d..74fc6c6af009e 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -91,6 +91,7 @@ impl AttributeKind { RustcMain => No, RustcObjectLifetimeDefault => No, RustcPassIndirectlyInNonRusticAbis(..) => No, + RustcShouldNotBeCalledOnConstItems(..) => Yes, RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate Sanitize { .. } => No, ShouldPanic { .. } => No, diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index c996181354b92..df04d135600ac 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -193,6 +193,14 @@ lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as i .current_use = this identifier can be confused with `{$existing_sym}` .other_use = other identifier used here +lint_const_item_interior_mutations = + mutation of an interior mutable `const` item with call to `{$method_name}` + .label = `{$const_name}` is a interior mutable `const` item of type `{$const_ty}` + .temporary = each usage of a `const` item creates a new temporary + .never_original = only the temporaries and never the original `const {$const_name}` will be modified + .suggestion_static = for a shared instance of `{$const_name}`, consider making it a `static` item instead + .help = for more details on interior mutability see + lint_dangling_pointers_from_locals = {$fn_kind} returns a dangling pointer to dropped local variable `{$local_var_name}` .ret_ty = return type is `{$ret_ty}` .local_var = local variable `{$local_var_name}` is dropped at the end of the {$fn_kind} diff --git a/compiler/rustc_lint/src/interior_mutable_consts.rs b/compiler/rustc_lint/src/interior_mutable_consts.rs new file mode 100644 index 0000000000000..8576698dec33e --- /dev/null +++ b/compiler/rustc_lint/src/interior_mutable_consts.rs @@ -0,0 +1,122 @@ +use rustc_hir::attrs::AttributeKind; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr}; +use rustc_session::{declare_lint, declare_lint_pass}; + +use crate::lints::{ConstItemInteriorMutationsDiag, ConstItemInteriorMutationsSuggestionStatic}; +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `const_item_interior_mutations` lint checks for calls which + /// mutates an interior mutable const-item. + /// + /// ### Example + /// + /// ```rust + /// use std::sync::Once; + /// + /// const INIT: Once = Once::new(); // using `INIT` will always create a temporary and + /// // never modify it-self on use, should be a `static` + /// // instead for shared use + /// + /// fn init() { + /// INIT.call_once(|| { + /// println!("Once::call_once first call"); + /// }); + /// INIT.call_once(|| { // this second will also print + /// println!("Once::call_once second call"); // as each call to `INIT` creates + /// }); // new temporary + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Calling a method which mutates an interior mutable type has no effect as const-item + /// are essentially inlined wherever they are used, meaning that they are copied + /// directly into the relevant context when used rendering modification through + /// interior mutability ineffective across usage of that const-item. + /// + /// The current implementation of this lint only warns on significant `std` and + /// `core` interior mutable types, like `Once`, `AtomicI32`, ... this is done out + /// of prudence to avoid false-positive and may be extended in the future. + pub CONST_ITEM_INTERIOR_MUTATIONS, + Warn, + "checks for calls which mutates a interior mutable const-item" +} + +declare_lint_pass!(InteriorMutableConsts => [CONST_ITEM_INTERIOR_MUTATIONS]); + +impl<'tcx> LateLintPass<'tcx> for InteriorMutableConsts { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { + let typeck = cx.typeck_results(); + + let (method_did, receiver) = match expr.kind { + // matching on `.method(..)` + ExprKind::MethodCall(_, receiver, _, _) => { + (typeck.type_dependent_def_id(expr.hir_id), receiver) + } + // matching on `function(&, ...)` + ExprKind::Call(path, [receiver, ..]) => match receiver.kind { + ExprKind::AddrOf(_, _, receiver) => match path.kind { + ExprKind::Path(ref qpath) => { + (cx.qpath_res(qpath, path.hir_id).opt_def_id(), receiver) + } + _ => return, + }, + _ => return, + }, + _ => return, + }; + + let Some(method_did) = method_did else { + return; + }; + + if let ExprKind::Path(qpath) = &receiver.kind + && let Res::Def(DefKind::Const | DefKind::AssocConst, const_did) = + typeck.qpath_res(qpath, receiver.hir_id) + // Let's do the attribute check after the other checks for perf reasons + && find_attr!( + cx.tcx.get_all_attrs(method_did), + AttributeKind::RustcShouldNotBeCalledOnConstItems(_) + ) + && let Some(method_name) = cx.tcx.opt_item_ident(method_did) + && let Some(const_name) = cx.tcx.opt_item_ident(const_did) + && let Some(const_ty) = typeck.node_type_opt(receiver.hir_id) + { + // Find the local `const`-item and create the suggestion to use `static` instead + let sugg_static = if let Some(Node::Item(const_item)) = + cx.tcx.hir_get_if_local(const_did) + && let ItemKind::Const(ident, _generics, _ty, _body_id) = const_item.kind + { + if let Some(vis_span) = const_item.vis_span.find_ancestor_inside(const_item.span) + && const_item.span.can_be_used_for_suggestions() + && vis_span.can_be_used_for_suggestions() + { + Some(ConstItemInteriorMutationsSuggestionStatic::Spanful { + const_: const_item.vis_span.between(ident.span), + before: if !vis_span.is_empty() { " " } else { "" }, + }) + } else { + Some(ConstItemInteriorMutationsSuggestionStatic::Spanless) + } + } else { + None + }; + + cx.emit_span_lint( + CONST_ITEM_INTERIOR_MUTATIONS, + expr.span, + ConstItemInteriorMutationsDiag { + method_name, + const_name, + const_ty, + receiver_span: receiver.span, + sugg_static, + }, + ); + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 7c3a81e891300..78b76e083d416 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -48,6 +48,7 @@ mod foreign_modules; mod function_cast_as_integer; mod if_let_rescope; mod impl_trait_overcaptures; +mod interior_mutable_consts; mod internal; mod invalid_from_utf8; mod late; @@ -93,6 +94,7 @@ use for_loops_over_fallibles::*; use function_cast_as_integer::*; use if_let_rescope::IfLetRescope; use impl_trait_overcaptures::ImplTraitOvercaptures; +use interior_mutable_consts::*; use internal::*; use invalid_from_utf8::*; use let_underscore::*; @@ -239,6 +241,7 @@ late_lint_methods!( AsyncClosureUsage: AsyncClosureUsage, AsyncFnInTrait: AsyncFnInTrait, NonLocalDefinitions: NonLocalDefinitions::default(), + InteriorMutableConsts: InteriorMutableConsts, ImplTraitOvercaptures: ImplTraitOvercaptures, IfLetRescope: IfLetRescope::default(), StaticMutRefs: StaticMutRefs, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index dc50f61f741d6..096299c16e0fe 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -784,6 +784,39 @@ pub(crate) enum InvalidFromUtf8Diag { }, } +// interior_mutable_consts.rs +#[derive(LintDiagnostic)] +#[diag(lint_const_item_interior_mutations)] +#[note(lint_temporary)] +#[note(lint_never_original)] +#[help] +pub(crate) struct ConstItemInteriorMutationsDiag<'tcx> { + pub method_name: Ident, + pub const_name: Ident, + pub const_ty: Ty<'tcx>, + #[label] + pub receiver_span: Span, + #[subdiagnostic] + pub sugg_static: Option, +} + +#[derive(Subdiagnostic)] +pub(crate) enum ConstItemInteriorMutationsSuggestionStatic { + #[suggestion( + lint_suggestion_static, + code = "{before}static ", + style = "verbose", + applicability = "maybe-incorrect" + )] + Spanful { + #[primary_span] + const_: Span, + before: &'static str, + }, + #[help(lint_suggestion_static)] + Spanless, +} + // reference_casting.rs #[derive(LintDiagnostic)] pub(crate) enum InvalidReferenceCastingDiag<'tcx> { diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 8823c83922822..ba17aef92d0d5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -25,6 +25,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Value.h" #include "llvm/Object/COFFImportFile.h" +#include "llvm/Object/OffloadBinary.h" #include "llvm/Remarks/RemarkFormat.h" #include "llvm/Remarks/RemarkSerializer.h" #include "llvm/Remarks/RemarkStreamer.h" @@ -35,6 +36,7 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/Timer.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include @@ -144,6 +146,51 @@ extern "C" void LLVMRustPrintStatistics(RustStringRef OutBuf) { llvm::PrintStatistics(OS); } +static Error writeFile(StringRef Filename, StringRef Data) { + Expected> OutputOrErr = + FileOutputBuffer::create(Filename, Data.size()); + if (!OutputOrErr) + return OutputOrErr.takeError(); + std::unique_ptr Output = std::move(*OutputOrErr); + llvm::copy(Data, Output->getBufferStart()); + if (Error E = Output->commit()) + return E; + return Error::success(); +} + +// This is the first of many steps in creating a binary using llvm offload, +// to run code on the gpu. Concrete, it replaces the following binary use: +// clang-offload-packager -o host.out +// --image=file=device.bc,triple=amdgcn-amd-amdhsa,arch=gfx90a,kind=openmp +// The input module is the rust code compiled for a gpu target like amdgpu. +// Based on clang/tools/clang-offload-packager/ClangOffloadPackager.cpp +extern "C" bool LLVMRustBundleImages(LLVMModuleRef M, TargetMachine &TM) { + std::string Storage; + llvm::raw_string_ostream OS1(Storage); + llvm::WriteBitcodeToFile(*unwrap(M), OS1); + OS1.flush(); + auto MB = llvm::MemoryBuffer::getMemBufferCopy(Storage, "module.bc"); + + SmallVector BinaryData; + raw_svector_ostream OS2(BinaryData); + + OffloadBinary::OffloadingImage ImageBinary{}; + ImageBinary.TheImageKind = object::IMG_Bitcode; + ImageBinary.Image = std::move(MB); + ImageBinary.TheOffloadKind = object::OFK_OpenMP; + ImageBinary.StringData["triple"] = TM.getTargetTriple().str(); + ImageBinary.StringData["arch"] = TM.getTargetCPU(); + llvm::SmallString<0> Buffer = OffloadBinary::write(ImageBinary); + if (Buffer.size() % OffloadBinary::getAlignment() != 0) + // Offload binary has invalid size alignment + return false; + OS2 << Buffer; + if (Error E = writeFile("host.out", + StringRef(BinaryData.begin(), BinaryData.size()))) + return false; + return true; +} + extern "C" void LLVMRustOffloadMapper(LLVMValueRef OldFn, LLVMValueRef NewFn) { llvm::Function *oldFn = llvm::unwrap(OldFn); llvm::Function *newFn = llvm::unwrap(NewFn); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 347e103af9378..30bb7d657f7a5 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -254,6 +254,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcLayoutScalarValidRangeStart(..) | AttributeKind::RustcLayoutScalarValidRangeEnd(..) | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) + | AttributeKind::RustcShouldNotBeCalledOnConstItems(..) | AttributeKind::ExportStable | AttributeKind::FfiConst(..) | AttributeKind::UnstableFeatureBound(..) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index eca4259efa7d1..cd730ede4ba1f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1986,6 +1986,7 @@ symbols! { rustc_regions, rustc_reservation_impl, rustc_serialize, + rustc_should_not_be_called_on_const_items, rustc_simd_monomorphize_lane_limit, rustc_skip_during_method_dispatch, rustc_specialization_trait, diff --git a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs index 58aff198a6601..3bd8ebd0ed3d5 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnullvm.rs @@ -1,8 +1,9 @@ use std::borrow::Cow; +use crate::spec::crt_objects::pre_mingw_self_contained; use crate::spec::{ - Abi, BinaryFormat, Cc, DebuginfoKind, Env, LinkerFlavor, Lld, Os, SplitDebuginfo, - TargetOptions, cvs, + Abi, BinaryFormat, Cc, DebuginfoKind, Env, LinkSelfContainedDefault, LinkerFlavor, Lld, Os, + SplitDebuginfo, TargetOptions, add_link_args, cvs, }; pub(crate) fn opts() -> TargetOptions { @@ -15,10 +16,11 @@ pub(crate) fn opts() -> TargetOptions { &["-nolibc", "--unwindlib=none"], ); // Order of `late_link_args*` does not matter with LLD. - let late_link_args = TargetOptions::link_args( - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"], - ); + let mingw_libs = &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"]; + + let mut late_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); + add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs); TargetOptions { os: Os::Windows, @@ -36,6 +38,8 @@ pub(crate) fn opts() -> TargetOptions { binary_format: BinaryFormat::Coff, allows_weak_linkage: false, pre_link_args, + pre_link_objects_self_contained: pre_mingw_self_contained(), + link_self_contained: LinkSelfContainedDefault::InferredForMingw, late_link_args, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index 7b3a234cd9e8e..c3dbcb78f0666 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -1,10 +1,11 @@ -use crate::spec::{Arch, FramePointer, Target, TargetMetadata, base}; +use crate::spec::{Arch, Cc, FramePointer, LinkerFlavor, Lld, Target, TargetMetadata, base}; pub(crate) fn target() -> Target { let mut base = base::windows_gnullvm::opts(); base.max_atomic_width = Some(128); base.features = "+v8a,+neon,+fp-armv8".into(); base.linker = Some("aarch64-w64-mingw32-clang".into()); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "arm64pe"]); // Microsoft recommends enabling frame pointers on Arm64 Windows. // From https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#integer-registers diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs index 0606d4508badc..b157f2620f29a 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs @@ -6,6 +6,7 @@ pub(crate) fn target() -> Target { base.features = "+cx16,+sse3,+sahf".into(); base.plt_by_default = false; base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pep"]); base.max_atomic_width = Some(128); base.linker = Some("x86_64-w64-mingw32-clang".into()); diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 27eb614bae138..c8cba30dde051 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -1,12 +1,13 @@ // ignore-tidy-filelength use core::ops::ControlFlow; use std::borrow::Cow; +use std::collections::hash_set; use std::path::PathBuf; use rustc_abi::ExternAbi; use rustc_ast::ast::LitKind; use rustc_ast::{LitIntType, TraitObjectSyntax}; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; use rustc_errors::{ @@ -1952,11 +1953,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) { // don't suggest foreign `#[doc(hidden)]` types if !did.is_local() { - while let Some(parent) = parent_map.get(&did) { + let mut previously_seen_dids: FxHashSet = Default::default(); + previously_seen_dids.insert(did); + while let Some(&parent) = parent_map.get(&did) + && let hash_set::Entry::Vacant(v) = + previously_seen_dids.entry(parent) + { if self.tcx.is_doc_hidden(did) { return false; } - did = *parent; + v.insert(); + did = parent; } } true diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index c5dfaa2a60d87..0184b2ccde784 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -17,6 +17,7 @@ #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(default_field_values)] +#![feature(hash_set_entry)] #![feature(if_let_guard)] #![feature(iter_intersperse)] #![feature(iterator_try_reduce)] diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 4dd45a09a4df3..445021801beff 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -64,7 +64,10 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { #[instrument(level = "trace", skip(self))] fn collect_taits_declared_in_body(&mut self) { - let body = self.tcx.hir_body_owned_by(self.item).value; + let Some(body) = self.tcx.hir_maybe_body_owned_by(self.item) else { + return; + }; + let body = body.value; struct TaitInBodyFinder<'a, 'tcx> { collector: &'a mut OpaqueTypeCollector<'tcx>, } diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 52e079d3ae8e6..ea9d5b128ebe4 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2479,11 +2479,11 @@ impl VecDeque { let other_len = len - at; let mut other = VecDeque::with_capacity_in(other_len, self.allocator().clone()); - unsafe { - let (first_half, second_half) = self.as_slices(); + let (first_half, second_half) = self.as_slices(); + let first_len = first_half.len(); + let second_len = second_half.len(); - let first_len = first_half.len(); - let second_len = second_half.len(); + unsafe { if at < first_len { // `at` lies in the first half. let amount_in_first = first_len - at; diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 988c50795e299..c8340c328be12 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -430,6 +430,7 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cell_traits", issue = "147787")] + #[rustc_should_not_be_called_on_const_items] pub const fn set(&self, val: T) where T: [const] Destruct, @@ -461,6 +462,7 @@ impl Cell { /// ``` #[inline] #[stable(feature = "move_cell", since = "1.17.0")] + #[rustc_should_not_be_called_on_const_items] pub fn swap(&self, other: &Self) { // This function documents that it *will* panic, and intrinsics::is_nonoverlapping doesn't // do the check in const, so trying to use it here would be inviting unnecessary fragility. @@ -505,6 +507,7 @@ impl Cell { #[stable(feature = "move_cell", since = "1.17.0")] #[rustc_const_stable(feature = "const_cell", since = "1.88.0")] #[rustc_confusables("swap")] + #[rustc_should_not_be_called_on_const_items] pub const fn replace(&self, val: T) -> T { // SAFETY: This can cause data races if called from a separate thread, // but `Cell` is `!Sync` so this won't happen. @@ -546,6 +549,7 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_cell", since = "1.88.0")] + #[rustc_should_not_be_called_on_const_items] pub const fn get(&self) -> T { // SAFETY: This can cause data races if called from a separate thread, // but `Cell` is `!Sync` so this won't happen. @@ -566,6 +570,7 @@ impl Cell { #[inline] #[stable(feature = "cell_update", since = "1.88.0")] #[rustc_const_unstable(feature = "const_cell_traits", issue = "147787")] + #[rustc_should_not_be_called_on_const_items] pub const fn update(&self, f: impl [const] FnOnce(T) -> T) where // FIXME(const-hack): `Copy` should imply `const Destruct` @@ -994,6 +999,7 @@ impl RefCell { #[track_caller] #[rustc_confusables("swap")] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_should_not_be_called_on_const_items] pub const fn replace(&self, t: T) -> T { mem::replace(&mut self.borrow_mut(), t) } @@ -1017,6 +1023,7 @@ impl RefCell { #[inline] #[stable(feature = "refcell_replace_swap", since = "1.35.0")] #[track_caller] + #[rustc_should_not_be_called_on_const_items] pub fn replace_with T>(&self, f: F) -> T { let mut_borrow = &mut *self.borrow_mut(); let replacement = f(mut_borrow); @@ -1046,6 +1053,7 @@ impl RefCell { #[inline] #[stable(feature = "refcell_swap", since = "1.24.0")] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_should_not_be_called_on_const_items] pub const fn swap(&self, other: &Self) { mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut()) } @@ -1087,6 +1095,7 @@ impl RefCell { #[inline] #[track_caller] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_should_not_be_called_on_const_items] pub const fn borrow(&self) -> Ref<'_, T> { match self.try_borrow() { Ok(b) => b, @@ -1123,6 +1132,7 @@ impl RefCell { #[inline] #[cfg_attr(feature = "debug_refcell", track_caller)] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_should_not_be_called_on_const_items] pub const fn try_borrow(&self) -> Result, BorrowError> { match BorrowRef::new(&self.borrow) { Some(b) => { @@ -1185,6 +1195,7 @@ impl RefCell { #[inline] #[track_caller] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_should_not_be_called_on_const_items] pub const fn borrow_mut(&self) -> RefMut<'_, T> { match self.try_borrow_mut() { Ok(b) => b, @@ -1218,6 +1229,7 @@ impl RefCell { #[inline] #[cfg_attr(feature = "debug_refcell", track_caller)] #[rustc_const_unstable(feature = "const_ref_cell", issue = "137844")] + #[rustc_should_not_be_called_on_const_items] pub const fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { Some(b) => { @@ -2356,6 +2368,7 @@ impl UnsafeCell { /// ``` #[inline] #[unstable(feature = "unsafe_cell_access", issue = "136327")] + #[rustc_should_not_be_called_on_const_items] pub const unsafe fn replace(&self, value: T) -> T { // SAFETY: pointer comes from `&self` so naturally satisfies invariants. unsafe { ptr::replace(self.get(), value) } @@ -2404,6 +2417,7 @@ impl UnsafeCell { #[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")] #[rustc_as_ptr] #[rustc_never_returns_null_ptr] + #[rustc_should_not_be_called_on_const_items] pub const fn get(&self) -> *mut T { // We can just cast the pointer from `UnsafeCell` to `T` because of // #[repr(transparent)]. This exploits std's special status, there is @@ -2493,6 +2507,7 @@ impl UnsafeCell { /// ``` #[inline] #[unstable(feature = "unsafe_cell_access", issue = "136327")] + #[rustc_should_not_be_called_on_const_items] pub const unsafe fn as_ref_unchecked(&self) -> &T { // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants. unsafe { self.get().as_ref_unchecked() } @@ -2521,6 +2536,7 @@ impl UnsafeCell { #[inline] #[unstable(feature = "unsafe_cell_access", issue = "136327")] #[allow(clippy::mut_from_ref)] + #[rustc_should_not_be_called_on_const_items] pub const unsafe fn as_mut_unchecked(&self) -> &mut T { // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants. unsafe { self.get().as_mut_unchecked() } @@ -2608,6 +2624,7 @@ impl SyncUnsafeCell { #[inline] #[rustc_as_ptr] #[rustc_never_returns_null_ptr] + #[rustc_should_not_be_called_on_const_items] pub const fn get(&self) -> *mut T { self.value.get() } diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index a1bd4c8571706..3dae6c64200c1 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -134,6 +134,7 @@ impl T> LazyCell { /// ``` #[inline] #[stable(feature = "lazy_cell", since = "1.80.0")] + #[rustc_should_not_be_called_on_const_items] pub fn force(this: &LazyCell) -> &T { // SAFETY: // This invalidates any mutable references to the data. The resulting diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 833be059d75f7..1e211ae66e79c 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -88,6 +88,7 @@ impl OnceCell { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_should_not_be_called_on_const_items] pub fn set(&self, value: T) -> Result<(), T> { match self.try_insert(value) { Ok(_) => Ok(()), @@ -120,6 +121,7 @@ impl OnceCell { /// ``` #[inline] #[unstable(feature = "once_cell_try_insert", issue = "116693")] + #[rustc_should_not_be_called_on_const_items] pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { if let Some(old) = self.get() { return Err((old, value)); @@ -157,6 +159,7 @@ impl OnceCell { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_should_not_be_called_on_const_items] pub fn get_or_init(&self, f: F) -> &T where F: FnOnce() -> T, @@ -231,6 +234,7 @@ impl OnceCell { /// assert_eq!(cell.get(), Some(&92)) /// ``` #[unstable(feature = "once_cell_try", issue = "109737")] + #[rustc_should_not_be_called_on_const_items] pub fn get_or_try_init(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result, diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index d7eaaf35b53a3..0c5552a0b81cc 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -749,6 +749,7 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn store(&self, val: bool, order: Ordering) { // SAFETY: any data races are prevented by atomic intrinsics and the raw // pointer passed in is valid because we got it from a reference. @@ -781,6 +782,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn swap(&self, val: bool, order: Ordering) -> bool { if EMULATE_ATOMIC_BOOL { if val { self.fetch_or(true, order) } else { self.fetch_and(false, order) } @@ -848,6 +850,7 @@ impl AtomicBool { )] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool { match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { Ok(x) => x, @@ -909,6 +912,7 @@ impl AtomicBool { #[doc(alias = "compare_and_swap")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange( &self, current: bool, @@ -1004,6 +1008,7 @@ impl AtomicBool { #[doc(alias = "compare_and_swap")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange_weak( &self, current: bool, @@ -1060,6 +1065,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } @@ -1102,6 +1108,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool { // We can't use atomic_nand here because it can result in a bool with // an invalid value. This happens because the atomic operation is done @@ -1154,6 +1161,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } @@ -1195,6 +1203,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } @@ -1232,6 +1241,7 @@ impl AtomicBool { #[stable(feature = "atomic_bool_fetch_not", since = "1.81.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_not(&self, order: Ordering) -> bool { self.fetch_xor(true, order) } @@ -1270,6 +1280,7 @@ impl AtomicBool { #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_never_returns_null_ptr] + #[rustc_should_not_be_called_on_const_items] pub const fn as_ptr(&self) -> *mut bool { self.v.get().cast() } @@ -1323,6 +1334,7 @@ impl AtomicBool { #[stable(feature = "atomic_fetch_update", since = "1.53.0")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_update( &self, set_order: Ordering, @@ -1394,6 +1406,7 @@ impl AtomicBool { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn try_update( &self, set_order: Ordering, @@ -1452,6 +1465,7 @@ impl AtomicBool { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn update( &self, set_order: Ordering, @@ -1735,6 +1749,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn store(&self, ptr: *mut T, order: Ordering) { // SAFETY: data races are prevented by atomic intrinsics. unsafe { @@ -1768,6 +1783,7 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.p.get(), ptr, order) } @@ -1830,6 +1846,7 @@ impl AtomicPtr { )] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T { match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { Ok(x) => x, @@ -1884,6 +1901,7 @@ impl AtomicPtr { #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange( &self, current: *mut T, @@ -1947,6 +1965,7 @@ impl AtomicPtr { #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange_weak( &self, current: *mut T, @@ -2020,6 +2039,7 @@ impl AtomicPtr { #[stable(feature = "atomic_fetch_update", since = "1.53.0")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_update( &self, set_order: Ordering, @@ -2100,6 +2120,7 @@ impl AtomicPtr { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "ptr")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn try_update( &self, set_order: Ordering, @@ -2163,6 +2184,7 @@ impl AtomicPtr { #[unstable(feature = "atomic_try_update", issue = "135894")] #[cfg(target_has_atomic = "8")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn update( &self, set_order: Ordering, @@ -2214,6 +2236,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T { self.fetch_byte_add(val.wrapping_mul(size_of::()), order) } @@ -2258,6 +2281,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T { self.fetch_byte_sub(val.wrapping_mul(size_of::()), order) } @@ -2292,6 +2316,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_byte_add(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_add(self.p.get(), val, order).cast() } @@ -2327,6 +2352,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_byte_sub(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_sub(self.p.get(), val, order).cast() } @@ -2377,6 +2403,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_or(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.p.get(), val, order).cast() } @@ -2426,6 +2453,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_and(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.p.get(), val, order).cast() } @@ -2473,6 +2501,7 @@ impl AtomicPtr { #[cfg(target_has_atomic = "ptr")] #[stable(feature = "strict_provenance_atomic_ptr", since = "1.91.0")] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.p.get(), val, order).cast() } @@ -2913,6 +2942,7 @@ macro_rules! atomic_int { #[inline] #[$stable] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn store(&self, val: $int_type, order: Ordering) { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_store(self.v.get(), val, order); } @@ -2941,6 +2971,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.v.get(), val, order) } @@ -3005,6 +3036,7 @@ macro_rules! atomic_int { ] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_and_swap(&self, current: $int_type, new: $int_type, @@ -3073,6 +3105,7 @@ macro_rules! atomic_int { #[$stable_cxchg] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange(&self, current: $int_type, new: $int_type, @@ -3136,6 +3169,7 @@ macro_rules! atomic_int { #[$stable_cxchg] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn compare_exchange_weak(&self, current: $int_type, new: $int_type, @@ -3172,6 +3206,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_add(self.v.get(), val, order) } @@ -3202,6 +3237,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_sub(self.v.get(), val, order) } @@ -3235,6 +3271,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val, order) } @@ -3268,6 +3305,7 @@ macro_rules! atomic_int { #[$stable_nand] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_nand(self.v.get(), val, order) } @@ -3301,6 +3339,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val, order) } @@ -3334,6 +3373,7 @@ macro_rules! atomic_int { #[$stable] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val, order) } @@ -3388,6 +3428,7 @@ macro_rules! atomic_int { #[stable(feature = "no_more_cas", since = "1.45.0")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_update(&self, set_order: Ordering, fetch_order: Ordering, @@ -3455,6 +3496,7 @@ macro_rules! atomic_int { #[unstable(feature = "atomic_try_update", issue = "135894")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn try_update( &self, set_order: Ordering, @@ -3516,6 +3558,7 @@ macro_rules! atomic_int { #[unstable(feature = "atomic_try_update", issue = "135894")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn update( &self, set_order: Ordering, @@ -3570,6 +3613,7 @@ macro_rules! atomic_int { #[stable(feature = "atomic_min_max", since = "1.45.0")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { $max_fn(self.v.get(), val, order) } @@ -3616,6 +3660,7 @@ macro_rules! atomic_int { #[stable(feature = "atomic_min_max", since = "1.45.0")] #[$cfg_cas] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[rustc_should_not_be_called_on_const_items] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { // SAFETY: data races are prevented by atomic intrinsics. unsafe { $min_fn(self.v.get(), val, order) } diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs index 6104a02c739b5..460deb490ef0b 100644 --- a/library/std/src/collections/mod.rs +++ b/library/std/src/collections/mod.rs @@ -104,7 +104,7 @@ //! unlikely, for [`HashMap`] to experience significantly worse performance than //! the expected cost. This is due to the probabilistic nature of hashing - i.e. //! it is possible to generate a duplicate hash given some input key that will -//! requires extra computation to correct. +//! require extra computation to correct. //! //! ## Cost of Collection Operations //! diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index f1cae4b207c9a..ef58b64d4967e 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -247,6 +247,7 @@ impl T> LazyLock { /// ``` #[inline] #[stable(feature = "lazy_cell", since = "1.80.0")] + #[rustc_should_not_be_called_on_const_items] pub fn force(this: &LazyLock) -> &T { this.once.call_once_force(|state| { if state.is_poisoned() { @@ -320,6 +321,7 @@ impl LazyLock { /// ``` #[inline] #[unstable(feature = "lazy_get", issue = "129333")] + #[rustc_should_not_be_called_on_const_items] pub fn get(this: &LazyLock) -> Option<&T> { if this.once.is_completed() { // SAFETY: diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 12cc32f381d18..bcfc9f581fd28 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -145,6 +145,7 @@ impl Once { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[track_caller] + #[rustc_should_not_be_called_on_const_items] pub fn call_once(&self, f: F) where F: FnOnce(), @@ -204,6 +205,7 @@ impl Once { /// ``` #[inline] #[stable(feature = "once_poison", since = "1.51.0")] + #[rustc_should_not_be_called_on_const_items] pub fn call_once_force(&self, f: F) where F: FnOnce(&OnceState), @@ -288,6 +290,7 @@ impl Once { /// panicked, this method will also panic. Use [`wait_force`](Self::wait_force) /// if this behavior is not desired. #[stable(feature = "once_wait", since = "1.86.0")] + #[rustc_should_not_be_called_on_const_items] pub fn wait(&self) { if !self.inner.is_completed() { self.inner.wait(false); @@ -300,6 +303,7 @@ impl Once { /// If this [`Once`] has been poisoned, this function blocks until it /// becomes completed, unlike [`Once::wait()`], which panics in this case. #[stable(feature = "once_wait", since = "1.86.0")] + #[rustc_should_not_be_called_on_const_items] pub fn wait_force(&self) { if !self.inner.is_completed() { self.inner.wait(true); diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index b224044cbe09c..d1bbe0ff843cf 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -150,6 +150,7 @@ impl OnceLock { /// This method never blocks. #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_should_not_be_called_on_const_items] pub fn get(&self) -> Option<&T> { if self.is_initialized() { // Safe b/c checked is_initialized @@ -197,6 +198,7 @@ impl OnceLock { /// ``` #[inline] #[stable(feature = "once_wait", since = "1.86.0")] + #[rustc_should_not_be_called_on_const_items] pub fn wait(&self) -> &T { self.once.wait_force(); @@ -231,6 +233,7 @@ impl OnceLock { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_should_not_be_called_on_const_items] pub fn set(&self, value: T) -> Result<(), T> { match self.try_insert(value) { Ok(_) => Ok(()), @@ -270,6 +273,7 @@ impl OnceLock { /// ``` #[inline] #[unstable(feature = "once_cell_try_insert", issue = "116693")] + #[rustc_should_not_be_called_on_const_items] pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> { let mut value = Some(value); let res = self.get_or_init(|| value.take().unwrap()); @@ -308,6 +312,7 @@ impl OnceLock { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] + #[rustc_should_not_be_called_on_const_items] pub fn get_or_init(&self, f: F) -> &T where F: FnOnce() -> T, @@ -388,6 +393,7 @@ impl OnceLock { /// ``` #[inline] #[unstable(feature = "once_cell_try", issue = "109737")] + #[rustc_should_not_be_called_on_const_items] pub fn get_or_try_init(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result, diff --git a/library/std/src/sync/poison/condvar.rs b/library/std/src/sync/poison/condvar.rs index de625a6cc5f63..fa9e1caada59b 100644 --- a/library/std/src/sync/poison/condvar.rs +++ b/library/std/src/sync/poison/condvar.rs @@ -121,6 +121,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> LockResult> { let poisoned = unsafe { let lock = mutex::guard_lock(&guard); @@ -177,6 +178,7 @@ impl Condvar { /// let _guard = cvar.wait_while(lock.lock().unwrap(), |pending| { *pending }).unwrap(); /// ``` #[stable(feature = "wait_until", since = "1.42.0")] + #[rustc_should_not_be_called_on_const_items] pub fn wait_while<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, @@ -245,6 +247,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] #[deprecated(since = "1.6.0", note = "replaced by `std::sync::Condvar::wait_timeout`")] pub fn wait_timeout_ms<'a, T>( &self, @@ -316,6 +319,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "wait_timeout", since = "1.5.0")] + #[rustc_should_not_be_called_on_const_items] pub fn wait_timeout<'a, T>( &self, guard: MutexGuard<'a, T>, @@ -382,6 +386,7 @@ impl Condvar { /// // access the locked mutex via result.0 /// ``` #[stable(feature = "wait_timeout_until", since = "1.42.0")] + #[rustc_should_not_be_called_on_const_items] pub fn wait_timeout_while<'a, T, F>( &self, mut guard: MutexGuard<'a, T>, @@ -442,6 +447,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn notify_one(&self) { self.inner.notify_one() } @@ -482,6 +488,7 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn notify_all(&self) { self.inner.notify_all() } diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 6fdb4f6799ee5..7f9e5fe62516f 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -401,6 +401,7 @@ impl Mutex { /// assert_eq!(mutex.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_should_not_be_called_on_const_items] pub fn set(&self, value: T) -> Result<(), PoisonError> { if mem::needs_drop::() { // If the contained value has non-trivial destructor, we @@ -438,6 +439,7 @@ impl Mutex { /// assert_eq!(mutex.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_should_not_be_called_on_const_items] pub fn replace(&self, value: T) -> LockResult { match self.lock() { Ok(mut guard) => Ok(mem::replace(&mut *guard, value)), @@ -484,6 +486,7 @@ impl Mutex { /// assert_eq!(*mutex.lock().unwrap(), 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn lock(&self) -> LockResult> { unsafe { self.inner.lock(); @@ -532,6 +535,7 @@ impl Mutex { /// assert_eq!(*mutex.lock().unwrap(), 10); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn try_lock(&self) -> TryLockResult> { unsafe { if self.inner.try_lock() { @@ -602,6 +606,7 @@ impl Mutex { /// ``` #[inline] #[stable(feature = "mutex_unpoison", since = "1.77.0")] + #[rustc_should_not_be_called_on_const_items] pub fn clear_poison(&self) { self.poison.clear(); } diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs index 10e45bc8c11a3..acfeb96900cc9 100644 --- a/library/std/src/sync/poison/rwlock.rs +++ b/library/std/src/sync/poison/rwlock.rs @@ -299,6 +299,7 @@ impl RwLock { /// assert_eq!(lock.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_should_not_be_called_on_const_items] pub fn set(&self, value: T) -> Result<(), PoisonError> { if mem::needs_drop::() { // If the contained value has non-trivial destructor, we @@ -337,6 +338,7 @@ impl RwLock { /// assert_eq!(lock.get_cloned().unwrap(), 11); /// ``` #[unstable(feature = "lock_value_accessors", issue = "133407")] + #[rustc_should_not_be_called_on_const_items] pub fn replace(&self, value: T) -> LockResult { match self.write() { Ok(mut guard) => Ok(mem::replace(&mut *guard, value)), @@ -389,6 +391,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn read(&self) -> LockResult> { unsafe { self.inner.read(); @@ -435,6 +438,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn try_read(&self) -> TryLockResult> { unsafe { if self.inner.try_read() { @@ -479,6 +483,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn write(&self) -> LockResult> { unsafe { self.inner.write(); @@ -526,6 +531,7 @@ impl RwLock { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_should_not_be_called_on_const_items] pub fn try_write(&self) -> TryLockResult> { unsafe { if self.inner.try_write() { diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 6857a40ada81b..a6704a5675a12 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -448,7 +448,7 @@ fn copy_self_contained_objects( DependencyType::TargetSelfContained, ); } - } else if target.is_windows_gnu() { + } else if target.is_windows_gnu() || target.is_windows_gnullvm() { for obj in ["crt2.o", "dllcrt2.o"].iter() { let src = compiler_file(builder, &builder.cc(target), target, CLang::C, obj); let dst = libdir_self_contained.join(obj); diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 58d89ce9662a3..4fdcdb2051f55 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -295,6 +295,44 @@ fn make_win_dist(plat_root: &Path, target: TargetSelection, builder: &Builder<'_ } } +fn make_win_llvm_dist(plat_root: &Path, target: TargetSelection, builder: &Builder<'_>) { + if builder.config.dry_run() { + return; + } + + let (_, lib_path) = get_cc_search_dirs(target, builder); + + // Libraries necessary to link the windows-gnullvm toolchains. + // System libraries will be preferred if they are available (see #67429). + let target_libs = [ + // MinGW libs + "libunwind.a", + "libunwind.dll.a", + "libmingw32.a", + "libmingwex.a", + "libmsvcrt.a", + // Windows import libs, remove them once std transitions to raw-dylib + "libkernel32.a", + "libuser32.a", + "libntdll.a", + "libuserenv.a", + "libws2_32.a", + "libdbghelp.a", + ]; + + //Find mingw artifacts we want to bundle + let target_libs = find_files(&target_libs, &lib_path); + + //Copy platform libs to platform-specific lib directory + let plat_target_lib_self_contained_dir = + plat_root.join("lib/rustlib").join(target).join("lib/self-contained"); + fs::create_dir_all(&plat_target_lib_self_contained_dir) + .expect("creating plat_target_lib_self_contained_dir failed"); + for src in target_libs { + builder.copy_link_to_folder(&src, &plat_target_lib_self_contained_dir); + } +} + fn runtime_dll_dist(rust_root: &Path, target: TargetSelection, builder: &Builder<'_>) { if builder.config.dry_run() { return; @@ -394,14 +432,20 @@ impl Step for Mingw { fn run(self, builder: &Builder<'_>) -> Option { let target = self.target; - if !target.ends_with("pc-windows-gnu") || !builder.config.dist_include_mingw_linker { + if !target.contains("pc-windows-gnu") || !builder.config.dist_include_mingw_linker { return None; } let mut tarball = Tarball::new(builder, "rust-mingw", &target.triple); tarball.set_product_name("Rust MinGW"); - make_win_dist(tarball.image_dir(), target, builder); + if target.ends_with("pc-windows-gnu") { + make_win_dist(tarball.image_dir(), target, builder); + } else if target.ends_with("pc-windows-gnullvm") { + make_win_llvm_dist(tarball.image_dir(), target, builder); + } else { + unreachable!(); + } Some(tarball.generate()) } diff --git a/src/bootstrap/src/core/config/target_selection.rs b/src/bootstrap/src/core/config/target_selection.rs index 40b63a7f9c752..47f6d6f386dfb 100644 --- a/src/bootstrap/src/core/config/target_selection.rs +++ b/src/bootstrap/src/core/config/target_selection.rs @@ -86,6 +86,10 @@ impl TargetSelection { self.ends_with("windows-gnu") } + pub fn is_windows_gnullvm(&self) -> bool { + self.ends_with("windows-gnullvm") + } + pub fn is_cygwin(&self) -> bool { self.is_windows() && // ref. https://cygwin.com/pipermail/cygwin/2022-February/250802.html diff --git a/src/doc/rustc-dev-guide/src/offload/usage.md b/src/doc/rustc-dev-guide/src/offload/usage.md index 7abf90aa6e0b6..8350fb5777fba 100644 --- a/src/doc/rustc-dev-guide/src/offload/usage.md +++ b/src/doc/rustc-dev-guide/src/offload/usage.md @@ -79,19 +79,8 @@ Now we generate the device code. Replace the target-cpu with the right code for RUSTFLAGS="-Ctarget-cpu=gfx90a --emit=llvm-bc,llvm-ir -Zoffload=Enable -Zunstable-options" cargo +offload build -Zunstable-options -r -v --target amdgcn-amd-amdhsa -Zbuild-std=core ``` -Now find the `.ll` under target/amdgcn-amd-amdhsa folder and copy it to a device.ll file (or adjust the file names below). -If you work on an NVIDIA or Intel gpu, please adjust the names acordingly and open an issue to share your results (either if you succeed or fail). -First we compile our .ll files (good for manual inspections) to .bc files and clean up leftover artifacts. The cleanup is important, otherwise caching might interfere on following runs. -``` -opt lib.ll -o lib.bc -opt device.ll -o device.bc -rm *.o -rm bare.amdgcn.gfx90a.img* -``` ``` -"clang-offload-packager" "-o" "host.out" "--image=file=device.bc,triple=amdgcn-amd-amdhsa,arch=gfx90a,kind=openmp" - "clang-21" "-cc1" "-triple" "x86_64-unknown-linux-gnu" "-S" "-save-temps=cwd" "-disable-free" "-clear-ast-before-backend" "-main-file-name" "lib.rs" "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" "-mframe-pointer=all" "-fmath-errno" "-ffp-contract=on" "-fno-rounding-math" "-mconstructor-aliases" "-funwind-tables=2" "-target-cpu" "x86-64" "-tune-cpu" "generic" "-resource-dir" "//rust/build/x86_64-unknown-linux-gnu/llvm/lib/clang/21" "-ferror-limit" "19" "-fopenmp" "-fopenmp-offload-mandatory" "-fgnuc-version=4.2.1" "-fskip-odr-check-in-gmf" "-fembed-offload-object=host.out" "-fopenmp-targets=amdgcn-amd-amdhsa" "-faddrsig" "-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o" "host.s" "-x" "ir" "lib.bc" "clang-21" "-cc1as" "-triple" "x86_64-unknown-linux-gnu" "-filetype" "obj" "-main-file-name" "lib.rs" "-target-cpu" "x86-64" "-mrelocation-model" "pic" "-o" "host.o" "host.s" @@ -99,7 +88,8 @@ rm bare.amdgcn.gfx90a.img* "clang-linker-wrapper" "--should-extract=gfx90a" "--device-compiler=amdgcn-amd-amdhsa=-g" "--device-compiler=amdgcn-amd-amdhsa=-save-temps=cwd" "--device-linker=amdgcn-amd-amdhsa=-lompdevice" "--host-triple=x86_64-unknown-linux-gnu" "--save-temps" "--linker-path=/ABSOlUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/lld/bin/ld.lld" "--hash-style=gnu" "--eh-frame-hdr" "-m" "elf_x86_64" "-pie" "-dynamic-linker" "/lib64/ld-linux-x86-64.so.2" "-o" "bare" "/lib/../lib64/Scrt1.o" "/lib/../lib64/crti.o" "/ABSOLUTE_PATH_TO/crtbeginS.o" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/bin/../lib/x86_64-unknown-linux-gnu" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/lib/clang/21/lib/x86_64-unknown-linux-gnu" "-L/lib/../lib64" "-L/usr/lib64" "-L/lib" "-L/usr/lib" "host.o" "-lstdc++" "-lm" "-lomp" "-lomptarget" "-L/ABSOLUTE_PATH_TO/rust/build/x86_64-unknown-linux-gnu/llvm/lib" "-lgcc_s" "-lgcc" "-lpthread" "-lc" "-lgcc_s" "-lgcc" "/ABSOLUTE_PATH_TO/crtendS.o" "/lib/../lib64/crtn.o" ``` -Especially for the last command I recommend to not fix the paths, but rather just re-generate them by copying a bare-mode openmp example and compiling it with your clang. By adding `-###` to your clang invocation, you can see the invidual steps. +Especially for the last three commands I recommend to not fix the paths, but rather just re-generate them by copying a bare-mode openmp example and compiling it with your clang. By adding `-###` to your clang invocation, you can see the invidual steps. +You can ignore other steps, e.g. the invocation of a "clang-offload-packager". ``` myclang++ -fuse-ld=lld -O3 -fopenmp -fopenmp-offload-mandatory --offload-arch=gfx90a omp_bare.cpp -o main -### ``` diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 5d9d63093860f..d646d9102ba3e 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -290,7 +290,7 @@ impl Builder { } // so is rust-mingw if it's available for the target PkgType::RustMingw => { - if host.ends_with("pc-windows-gnu") { + if host.contains("pc-windows-gnu") { components.push(host_component(pkg)); } } diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs index 674450a73ad23..39d6e76d5d002 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.rs @@ -4,6 +4,7 @@ #![allow( clippy::declare_interior_mutable_const, clippy::out_of_bounds_indexing, + const_item_interior_mutations, const_item_mutation, unconditional_panic )] diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr index e7c3f879b05b0..b3b1eb858e475 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const.stderr @@ -1,5 +1,5 @@ error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:35:17 + --> tests/ui/borrow_interior_mutable_const.rs:36:17 | LL | let _ = &C; | ^^ @@ -12,7 +12,7 @@ LL | #![deny(clippy::borrow_interior_mutable_const)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:37:17 + --> tests/ui/borrow_interior_mutable_const.rs:38:17 | LL | let _ = C.get(); | ^ @@ -21,7 +21,7 @@ LL | let _ = C.get(); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:42:17 + --> tests/ui/borrow_interior_mutable_const.rs:43:17 | LL | let _ = &C; | ^^ @@ -29,7 +29,7 @@ LL | let _ = &C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:43:17 + --> tests/ui/borrow_interior_mutable_const.rs:44:17 | LL | let _ = &mut C; | ^^^^^^ @@ -37,7 +37,7 @@ LL | let _ = &mut C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:47:9 + --> tests/ui/borrow_interior_mutable_const.rs:48:9 | LL | C.swap(&local) | ^ @@ -46,7 +46,7 @@ LL | C.swap(&local) = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:52:17 + --> tests/ui/borrow_interior_mutable_const.rs:53:17 | LL | let _ = &C; | ^^ @@ -54,7 +54,7 @@ LL | let _ = &C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:53:17 + --> tests/ui/borrow_interior_mutable_const.rs:54:17 | LL | let _ = &C[0]; | ^^^^^ @@ -62,7 +62,7 @@ LL | let _ = &C[0]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:54:17 + --> tests/ui/borrow_interior_mutable_const.rs:55:17 | LL | let _ = &C[0].0; | ^^^^^^^ @@ -70,7 +70,7 @@ LL | let _ = &C[0].0; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:55:9 + --> tests/ui/borrow_interior_mutable_const.rs:56:9 | LL | C[0].0.set(1); | ^^^^^^ @@ -79,7 +79,7 @@ LL | C[0].0.set(1); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:70:17 + --> tests/ui/borrow_interior_mutable_const.rs:71:17 | LL | let _ = &S::C; | ^^^^^ @@ -87,7 +87,7 @@ LL | let _ = &S::C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:71:17 + --> tests/ui/borrow_interior_mutable_const.rs:72:17 | LL | let _ = &S::C.0; | ^^^^^^^ @@ -95,7 +95,7 @@ LL | let _ = &S::C.0; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:72:9 + --> tests/ui/borrow_interior_mutable_const.rs:73:9 | LL | S::C.set(1); | ^^^^ @@ -104,7 +104,7 @@ LL | S::C.set(1); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:73:18 + --> tests/ui/borrow_interior_mutable_const.rs:74:18 | LL | let _ = &*S::C; | ^^^^^ @@ -113,7 +113,7 @@ LL | let _ = &*S::C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:74:9 + --> tests/ui/borrow_interior_mutable_const.rs:75:9 | LL | (*S::C).set(1); | ^^^^^^^ @@ -122,7 +122,7 @@ LL | (*S::C).set(1); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:85:17 + --> tests/ui/borrow_interior_mutable_const.rs:86:17 | LL | let _ = &CELL; | ^^^^^ @@ -130,7 +130,7 @@ LL | let _ = &CELL; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:109:25 + --> tests/ui/borrow_interior_mutable_const.rs:110:25 | LL | let _ = &Self::C; | ^^^^^^^^ @@ -138,7 +138,7 @@ LL | let _ = &Self::C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:112:25 + --> tests/ui/borrow_interior_mutable_const.rs:113:25 | LL | let _ = &Self::C.cell; | ^^^^^^^^^^^^^ @@ -146,7 +146,7 @@ LL | let _ = &Self::C.cell; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:113:25 + --> tests/ui/borrow_interior_mutable_const.rs:114:25 | LL | let _ = &Self::C.cell.0; | ^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | let _ = &Self::C.cell.0; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:114:17 + --> tests/ui/borrow_interior_mutable_const.rs:115:17 | LL | Self::C.cell.0.set(T::DEFAULT); | ^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ LL | Self::C.cell.0.set(T::DEFAULT); = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:128:17 + --> tests/ui/borrow_interior_mutable_const.rs:129:17 | LL | let _ = &u32::VALUE; | ^^^^^^^^^^^ @@ -171,7 +171,7 @@ LL | let _ = &u32::VALUE; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:145:21 + --> tests/ui/borrow_interior_mutable_const.rs:146:21 | LL | let _ = &>::VALUE; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -179,7 +179,7 @@ LL | let _ = &>::VALUE; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:172:17 + --> tests/ui/borrow_interior_mutable_const.rs:173:17 | LL | let _ = &C; | ^^ @@ -187,7 +187,7 @@ LL | let _ = &C; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:173:18 + --> tests/ui/borrow_interior_mutable_const.rs:174:18 | LL | let _ = &C[0]; | ^^^^ @@ -196,7 +196,7 @@ LL | let _ = &C[0]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:174:17 + --> tests/ui/borrow_interior_mutable_const.rs:175:17 | LL | let _ = &C.0[0]; | ^^^^^^^ @@ -204,7 +204,7 @@ LL | let _ = &C.0[0]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:190:17 + --> tests/ui/borrow_interior_mutable_const.rs:191:17 | LL | let _ = &C[1]; | ^^^^^ @@ -212,7 +212,7 @@ LL | let _ = &C[1]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:194:21 + --> tests/ui/borrow_interior_mutable_const.rs:195:21 | LL | let _ = &C[i]; | ^^^^^ @@ -220,7 +220,7 @@ LL | let _ = &C[i]; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:198:17 + --> tests/ui/borrow_interior_mutable_const.rs:199:17 | LL | let _ = &interior_mutable_const::WRAPPED_PRIVATE_UNFROZEN_VARIANT; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -228,7 +228,7 @@ LL | let _ = &interior_mutable_const::WRAPPED_PRIVATE_UNFROZEN_VARIANT; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:216:17 + --> tests/ui/borrow_interior_mutable_const.rs:217:17 | LL | let _ = &S::VALUE; | ^^^^^^^^^ @@ -236,7 +236,7 @@ LL | let _ = &S::VALUE; = help: this lint can be silenced by assigning the value to a local variable before borrowing error: borrow of a named constant with interior mutability - --> tests/ui/borrow_interior_mutable_const.rs:218:17 + --> tests/ui/borrow_interior_mutable_const.rs:219:17 | LL | let _ = &S::VALUE.1; | ^^^^^^^^^^^ diff --git a/tests/ui/consts/issue-17718.rs b/tests/ui/consts/issue-17718.rs index b6c676886c10d..33e2d791840e6 100644 --- a/tests/ui/consts/issue-17718.rs +++ b/tests/ui/consts/issue-17718.rs @@ -1,7 +1,9 @@ //@ run-pass -#![allow(dead_code)] //@ aux-build:issue-17718-aux.rs +#![allow(dead_code)] +#![allow(const_item_interior_mutations)] + extern crate issue_17718_aux as other; use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/tests/ui/impl-trait/ice-148622-opaque-as-const-generics.rs b/tests/ui/impl-trait/ice-148622-opaque-as-const-generics.rs new file mode 100644 index 0000000000000..03741dca32978 --- /dev/null +++ b/tests/ui/impl-trait/ice-148622-opaque-as-const-generics.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +pub type Opaque = impl std::future::Future; +//~^ ERROR: unconstrained opaque type + +trait Foo { + //~^ ERROR: `Opaque` is forbidden as the type of a const generic parameter + fn bar(&self) -> [u8; N]; + //~^ ERROR: the constant `N` is not of type `usize` +} + +fn main() {} diff --git a/tests/ui/impl-trait/ice-148622-opaque-as-const-generics.stderr b/tests/ui/impl-trait/ice-148622-opaque-as-const-generics.stderr new file mode 100644 index 0000000000000..bc76c6fe85e74 --- /dev/null +++ b/tests/ui/impl-trait/ice-148622-opaque-as-const-generics.stderr @@ -0,0 +1,31 @@ +error: `Opaque` is forbidden as the type of a const generic parameter + --> $DIR/ice-148622-opaque-as-const-generics.rs:6:20 + | +LL | trait Foo { + | ^^^^^^ + | + = note: the only supported types are integers, `bool`, and `char` + +error: the constant `N` is not of type `usize` + --> $DIR/ice-148622-opaque-as-const-generics.rs:8:22 + | +LL | fn bar(&self) -> [u8; N]; + | ^^^^^^^ expected `usize`, found future + | +note: this item must have a `#[define_opaque(Opaque)]` attribute to be able to define hidden types + --> $DIR/ice-148622-opaque-as-const-generics.rs:8:8 + | +LL | fn bar(&self) -> [u8; N]; + | ^^^ + = note: the length of array `[u8; N]` must be type `usize` + +error: unconstrained opaque type + --> $DIR/ice-148622-opaque-as-const-generics.rs:3:19 + | +LL | pub type Opaque = impl std::future::Future; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Opaque` must be used in combination with a concrete type within the same crate + +error: aborting due to 3 previous errors + diff --git a/tests/ui/lint/const-item-interior-mutations-const-atomics.fixed b/tests/ui/lint/const-item-interior-mutations-const-atomics.fixed new file mode 100644 index 0000000000000..17737e5cb8b9f --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-atomics.fixed @@ -0,0 +1,164 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(atomic_try_update)] + +use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU32, Ordering}; + +fn atomic_bool() { + static A: AtomicBool = AtomicBool::new(false); + + let _a = A.store(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(false, true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_and(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_nand(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_not(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_not` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); + //~^ WARN mutation of an interior mutable `const` item with call to `update` +} + +fn atomic_ptr() { + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + + let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.compare_exchange_weak( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_ptr_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_add` + + let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_sub` + + let _a = A.fetch_byte_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_add` + + let _a = A.fetch_byte_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_sub` + + let _a = A.fetch_and(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` +} + +fn atomic_u32() { + static A: AtomicU32 = AtomicU32::new(0); + + let _a = A.store(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_sub` + + let _a = A.fetch_add(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_nand(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_max(20, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_max` + + let _a = A.fetch_min(5, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_min` +} + +fn main() {} diff --git a/tests/ui/lint/const-item-interior-mutations-const-atomics.rs b/tests/ui/lint/const-item-interior-mutations-const-atomics.rs new file mode 100644 index 0000000000000..4180b2340df6e --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-atomics.rs @@ -0,0 +1,164 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(atomic_try_update)] + +use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicU32, Ordering}; + +fn atomic_bool() { + const A: AtomicBool = AtomicBool::new(false); + + let _a = A.store(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(false, true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_and(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_nand(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(true, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_not(Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_not` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); + //~^ WARN mutation of an interior mutable `const` item with call to `update` +} + +fn atomic_ptr() { + const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + + let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.compare_exchange_weak( + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + std::ptr::null_mut(), + std::ptr::null_mut(), + Ordering::SeqCst, + Ordering::Relaxed, + ); + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_ptr_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_add` + + let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_ptr_sub` + + let _a = A.fetch_byte_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_add` + + let _a = A.fetch_byte_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_byte_sub` + + let _a = A.fetch_and(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_and` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` +} + +fn atomic_u32() { + const A: AtomicU32 = AtomicU32::new(0); + + let _a = A.store(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `store` + + let _a = A.swap(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_and_swap` + + let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange` + + let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); + //~^ WARN mutation of an interior mutable `const` item with call to `compare_exchange_weak` + + let _a = A.fetch_add(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_sub(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_sub` + + let _a = A.fetch_add(2, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_add` + + let _a = A.fetch_nand(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_nand` + + let _a = A.fetch_or(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_or` + + let _a = A.fetch_xor(1, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_xor` + + let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_update` + + let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); + //~^ WARN mutation of an interior mutable `const` item with call to `try_update` + + let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); + //~^ WARN mutation of an interior mutable `const` item with call to `update` + + let _a = A.fetch_max(20, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_max` + + let _a = A.fetch_min(5, Ordering::SeqCst); + //~^ WARN mutation of an interior mutable `const` item with call to `fetch_min` +} + +fn main() {} diff --git a/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr b/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr new file mode 100644 index 0000000000000..17823366d406f --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-atomics.stderr @@ -0,0 +1,765 @@ +warning: mutation of an interior mutable `const` item with call to `store` + --> $DIR/const-item-interior-mutations-const-atomics.rs:13:14 + | +LL | let _a = A.store(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see + = note: `#[warn(const_item_interior_mutations)]` on by default +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/const-item-interior-mutations-const-atomics.rs:16:14 + | +LL | let _a = A.swap(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `compare_and_swap` + --> $DIR/const-item-interior-mutations-const-atomics.rs:19:14 + | +LL | let _a = A.compare_and_swap(false, true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange` + --> $DIR/const-item-interior-mutations-const-atomics.rs:22:14 + | +LL | let _a = A.compare_exchange(false, true, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` + --> $DIR/const-item-interior-mutations-const-atomics.rs:25:14 + | +LL | let _a = A.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_and` + --> $DIR/const-item-interior-mutations-const-atomics.rs:28:14 + | +LL | let _a = A.fetch_and(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_nand` + --> $DIR/const-item-interior-mutations-const-atomics.rs:31:14 + | +LL | let _a = A.fetch_nand(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_or` + --> $DIR/const-item-interior-mutations-const-atomics.rs:34:14 + | +LL | let _a = A.fetch_or(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_xor` + --> $DIR/const-item-interior-mutations-const-atomics.rs:37:14 + | +LL | let _a = A.fetch_xor(true, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_not` + --> $DIR/const-item-interior-mutations-const-atomics.rs:40:14 + | +LL | let _a = A.fetch_not(Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:43:14 + | +LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(true)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `try_update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:46:14 + | +LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(false)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:49:14 + | +LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| true); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicBool` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicBool = AtomicBool::new(false); +LL + static A: AtomicBool = AtomicBool::new(false); + | + +warning: mutation of an interior mutable `const` item with call to `store` + --> $DIR/const-item-interior-mutations-const-atomics.rs:56:14 + | +LL | let _a = A.store(std::ptr::null_mut(), Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/const-item-interior-mutations-const-atomics.rs:59:14 + | +LL | let _a = A.swap(std::ptr::null_mut(), Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `compare_and_swap` + --> $DIR/const-item-interior-mutations-const-atomics.rs:62:14 + | +LL | let _a = A.compare_and_swap(std::ptr::null_mut(), std::ptr::null_mut(), Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange` + --> $DIR/const-item-interior-mutations-const-atomics.rs:65:14 + | +LL | let _a = A.compare_exchange( + | ^ `A` is a interior mutable `const` item of type `AtomicPtr` + | ______________| + | | +LL | | +LL | | std::ptr::null_mut(), +LL | | std::ptr::null_mut(), +LL | | Ordering::SeqCst, +LL | | Ordering::Relaxed, +LL | | ); + | |_____^ + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` + --> $DIR/const-item-interior-mutations-const-atomics.rs:73:14 + | +LL | let _a = A.compare_exchange_weak( + | ^ `A` is a interior mutable `const` item of type `AtomicPtr` + | ______________| + | | +LL | | +LL | | std::ptr::null_mut(), +LL | | std::ptr::null_mut(), +LL | | Ordering::SeqCst, +LL | | Ordering::Relaxed, +LL | | ); + | |_____^ + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:81:14 + | +LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `try_update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:84:14 + | +LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(std::ptr::null_mut())); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:87:14 + | +LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| std::ptr::null_mut()); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_ptr_add` + --> $DIR/const-item-interior-mutations-const-atomics.rs:90:14 + | +LL | let _a = A.fetch_ptr_add(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_ptr_sub` + --> $DIR/const-item-interior-mutations-const-atomics.rs:93:14 + | +LL | let _a = A.fetch_ptr_sub(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_byte_add` + --> $DIR/const-item-interior-mutations-const-atomics.rs:96:14 + | +LL | let _a = A.fetch_byte_add(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_byte_sub` + --> $DIR/const-item-interior-mutations-const-atomics.rs:99:14 + | +LL | let _a = A.fetch_byte_sub(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_and` + --> $DIR/const-item-interior-mutations-const-atomics.rs:102:14 + | +LL | let _a = A.fetch_and(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_or` + --> $DIR/const-item-interior-mutations-const-atomics.rs:105:14 + | +LL | let _a = A.fetch_or(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_xor` + --> $DIR/const-item-interior-mutations-const-atomics.rs:108:14 + | +LL | let _a = A.fetch_xor(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicPtr` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); +LL + static A: AtomicPtr = AtomicPtr::new(std::ptr::null_mut()); + | + +warning: mutation of an interior mutable `const` item with call to `store` + --> $DIR/const-item-interior-mutations-const-atomics.rs:115:14 + | +LL | let _a = A.store(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/const-item-interior-mutations-const-atomics.rs:118:14 + | +LL | let _a = A.swap(2, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `compare_and_swap` + --> $DIR/const-item-interior-mutations-const-atomics.rs:121:14 + | +LL | let _a = A.compare_and_swap(2, 3, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange` + --> $DIR/const-item-interior-mutations-const-atomics.rs:124:14 + | +LL | let _a = A.compare_exchange(3, 4, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `compare_exchange_weak` + --> $DIR/const-item-interior-mutations-const-atomics.rs:127:14 + | +LL | let _a = A.compare_exchange_weak(4, 5, Ordering::SeqCst, Ordering::Relaxed); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_add` + --> $DIR/const-item-interior-mutations-const-atomics.rs:130:14 + | +LL | let _a = A.fetch_add(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_sub` + --> $DIR/const-item-interior-mutations-const-atomics.rs:133:14 + | +LL | let _a = A.fetch_sub(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_add` + --> $DIR/const-item-interior-mutations-const-atomics.rs:136:14 + | +LL | let _a = A.fetch_add(2, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_nand` + --> $DIR/const-item-interior-mutations-const-atomics.rs:139:14 + | +LL | let _a = A.fetch_nand(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_or` + --> $DIR/const-item-interior-mutations-const-atomics.rs:142:14 + | +LL | let _a = A.fetch_or(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_xor` + --> $DIR/const-item-interior-mutations-const-atomics.rs:145:14 + | +LL | let _a = A.fetch_xor(1, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:148:14 + | +LL | let _a = A.fetch_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(10)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:151:14 + | +LL | let _a = A.try_update(Ordering::SeqCst, Ordering::Relaxed, |_| Some(11)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/const-item-interior-mutations-const-atomics.rs:154:14 + | +LL | let _a = A.update(Ordering::SeqCst, Ordering::Relaxed, |_| 12); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_max` + --> $DIR/const-item-interior-mutations-const-atomics.rs:157:14 + | +LL | let _a = A.fetch_max(20, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `fetch_min` + --> $DIR/const-item-interior-mutations-const-atomics.rs:160:14 + | +LL | let _a = A.fetch_min(5, Ordering::SeqCst); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `AtomicU32` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: AtomicU32 = AtomicU32::new(0); +LL + static A: AtomicU32 = AtomicU32::new(0); + | + +warning: 44 warnings emitted + diff --git a/tests/ui/lint/const-item-interior-mutations-const-cell.rs b/tests/ui/lint/const-item-interior-mutations-const-cell.rs new file mode 100644 index 0000000000000..b4a7f54c8e7a0 --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-cell.rs @@ -0,0 +1,105 @@ +//@ check-pass + +#![feature(unsafe_cell_access)] +#![feature(sync_unsafe_cell)] +#![feature(once_cell_try_insert)] +#![feature(once_cell_try)] +#![feature(lazy_get)] + +use std::cell::{Cell, RefCell, SyncUnsafeCell, UnsafeCell}; +use std::cell::{LazyCell, OnceCell}; +use std::ops::Deref; + +fn lazy_cell() { + const A: LazyCell = LazyCell::new(|| 0); + + let _ = LazyCell::force(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `force` +} + +fn once_cell() { + const A: OnceCell = OnceCell::new(); + + let _ = A.set(10); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _ = A.try_insert(20); + //~^ WARN mutation of an interior mutable `const` item with call to `try_insert` + + let _ = A.get_or_init(|| 30); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_init` + + let _ = A.get_or_try_init(|| Ok::<_, ()>(40)); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_try_init` +} + +fn cell() { + const A: Cell = Cell::new(0); + + let _ = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _ = A.swap(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _ = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + let _ = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + let _ = A.update(|x| x + 1); + //~^ WARN mutation of an interior mutable `const` item with call to `update` +} + +fn ref_cell() { + const A: RefCell = RefCell::new(0); + + let _ = A.replace(1); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + let _ = A.replace_with(|x| *x + 2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace_with` + + let _ = A.swap(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `swap` + + let _ = A.borrow(); + //~^ WARN mutation of an interior mutable `const` item with call to `borrow` + + let _ = A.try_borrow(); + //~^ WARN mutation of an interior mutable `const` item with call to `try_borrow` + + let _ = A.borrow_mut(); + //~^ WARN mutation of an interior mutable `const` item with call to `borrow_mut` + + let _ = A.try_borrow_mut(); + //~^ WARN mutation of an interior mutable `const` item with call to `try_borrow_mut` +} + +fn unsafe_cell() { + const A: UnsafeCell = UnsafeCell::new(0); + + let _ = unsafe { A.replace(1) }; + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + let _ = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + unsafe { + let _ = A.as_ref_unchecked(); + //~^ WARN mutation of an interior mutable `const` item with call to `as_ref_unchecked` + + let _ = A.as_mut_unchecked(); + //~^ WARN mutation of an interior mutable `const` item with call to `as_mut_unchecked` + } +} + +fn sync_unsafe_cell() { + const A: SyncUnsafeCell = SyncUnsafeCell::new(0); + + let _ = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` +} + +fn main() {} diff --git a/tests/ui/lint/const-item-interior-mutations-const-cell.stderr b/tests/ui/lint/const-item-interior-mutations-const-cell.stderr new file mode 100644 index 0000000000000..d9f19c61fa773 --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const-cell.stderr @@ -0,0 +1,377 @@ +warning: mutation of an interior mutable `const` item with call to `force` + --> $DIR/const-item-interior-mutations-const-cell.rs:16:13 + | +LL | let _ = LazyCell::force(&A); + | ^^^^^^^^^^^^^^^^^-^ + | | + | `A` is a interior mutable `const` item of type `LazyCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see + = note: `#[warn(const_item_interior_mutations)]` on by default +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: LazyCell = LazyCell::new(|| 0); +LL + static A: LazyCell = LazyCell::new(|| 0); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const-cell.rs:23:13 + | +LL | let _ = A.set(10); + | -^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `try_insert` + --> $DIR/const-item-interior-mutations-const-cell.rs:26:13 + | +LL | let _ = A.try_insert(20); + | -^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_init` + --> $DIR/const-item-interior-mutations-const-cell.rs:29:13 + | +LL | let _ = A.get_or_init(|| 30); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_try_init` + --> $DIR/const-item-interior-mutations-const-cell.rs:32:13 + | +LL | let _ = A.get_or_try_init(|| Ok::<_, ()>(40)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceCell = OnceCell::new(); +LL + static A: OnceCell = OnceCell::new(); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const-cell.rs:39:13 + | +LL | let _ = A.set(1); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/const-item-interior-mutations-const-cell.rs:42:13 + | +LL | let _ = A.swap(&A); + | -^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/const-item-interior-mutations-const-cell.rs:45:13 + | +LL | let _ = A.replace(2); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const-cell.rs:48:13 + | +LL | let _ = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `update` + --> $DIR/const-item-interior-mutations-const-cell.rs:51:13 + | +LL | let _ = A.update(|x| x + 1); + | -^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `Cell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Cell = Cell::new(0); +LL + static A: Cell = Cell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/const-item-interior-mutations-const-cell.rs:58:13 + | +LL | let _ = A.replace(1); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace_with` + --> $DIR/const-item-interior-mutations-const-cell.rs:61:13 + | +LL | let _ = A.replace_with(|x| *x + 2); + | -^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `swap` + --> $DIR/const-item-interior-mutations-const-cell.rs:64:13 + | +LL | let _ = A.swap(&A); + | -^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `borrow` + --> $DIR/const-item-interior-mutations-const-cell.rs:67:13 + | +LL | let _ = A.borrow(); + | -^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_borrow` + --> $DIR/const-item-interior-mutations-const-cell.rs:70:13 + | +LL | let _ = A.try_borrow(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `borrow_mut` + --> $DIR/const-item-interior-mutations-const-cell.rs:73:13 + | +LL | let _ = A.borrow_mut(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_borrow_mut` + --> $DIR/const-item-interior-mutations-const-cell.rs:76:13 + | +LL | let _ = A.try_borrow_mut(); + | -^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `RefCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RefCell = RefCell::new(0); +LL + static A: RefCell = RefCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/const-item-interior-mutations-const-cell.rs:83:22 + | +LL | let _ = unsafe { A.replace(1) }; + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const-cell.rs:86:13 + | +LL | let _ = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `as_ref_unchecked` + --> $DIR/const-item-interior-mutations-const-cell.rs:90:17 + | +LL | let _ = A.as_ref_unchecked(); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `as_mut_unchecked` + --> $DIR/const-item-interior-mutations-const-cell.rs:93:17 + | +LL | let _ = A.as_mut_unchecked(); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `UnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: UnsafeCell = UnsafeCell::new(0); +LL + static A: UnsafeCell = UnsafeCell::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const-cell.rs:101:13 + | +LL | let _ = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `SyncUnsafeCell` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: SyncUnsafeCell = SyncUnsafeCell::new(0); +LL + static A: SyncUnsafeCell = SyncUnsafeCell::new(0); + | + +warning: 22 warnings emitted + diff --git a/tests/ui/lint/const-item-interior-mutations-const.fixed b/tests/ui/lint/const-item-interior-mutations-const.fixed new file mode 100644 index 0000000000000..82f3fdac43a3a --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const.fixed @@ -0,0 +1,139 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(lock_value_accessors)] +#![feature(once_cell_try_insert)] +#![feature(once_cell_try)] +#![feature(lazy_get)] + +use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; +use std::time::Duration; + +fn mutex() { + static A: Mutex = Mutex::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `lock` + + drop(A.try_lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_lock` + + let _a = A.clear_poison(); + //~^ WARN mutation of an interior mutable `const` item with call to `clear_poison` +} + +fn once() { + static A: Once = Once::new(); + + let _a = A.call_once(|| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once` + + let _a = A.call_once_force(|_| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once_force` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.wait_force(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_force` +} + +fn rwlock() { + static A: RwLock = RwLock::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.read()); + //~^ WARN mutation of an interior mutable `const` item with call to `read` + + drop(A.try_read()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_read` + + drop(A.write()); + //~^ WARN mutation of an interior mutable `const` item with call to `write` + + drop(A.try_write()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_write` +} + +fn lazy_lock() { + static A: LazyLock = LazyLock::new(|| 0); + + let _a = LazyLock::force(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `force` + + let _a = LazyLock::get(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `get` +} + +fn once_lock() { + static A: OnceLock = OnceLock::new(); + + let _a = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.set(10); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.try_insert(20); + //~^ WARN mutation of an interior mutable `const` item with call to `try_insert` + + let _a = A.get_or_init(|| 30); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_init` + + let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_try_init` +} + +fn condvar() { + static A: Condvar = Condvar::new(); + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + + let _a = A.wait(guard); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_while(guard, |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_while` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_ms(guard, 10); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_ms` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout(guard, Duration::from_millis(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_while` + + let _a = A.notify_one(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_one` + + let _a = A.notify_all(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_all` +} + +fn main() {} diff --git a/tests/ui/lint/const-item-interior-mutations-const.rs b/tests/ui/lint/const-item-interior-mutations-const.rs new file mode 100644 index 0000000000000..5dbbfd8ca32f2 --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const.rs @@ -0,0 +1,139 @@ +//@ check-pass +//@ run-rustfix + +#![allow(deprecated)] +#![allow(dead_code)] +#![feature(lock_value_accessors)] +#![feature(once_cell_try_insert)] +#![feature(once_cell_try)] +#![feature(lazy_get)] + +use std::sync::{Condvar, LazyLock, Mutex, Once, OnceLock, RwLock}; +use std::time::Duration; + +fn mutex() { + const A: Mutex = Mutex::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `lock` + + drop(A.try_lock()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_lock` + + let _a = A.clear_poison(); + //~^ WARN mutation of an interior mutable `const` item with call to `clear_poison` +} + +fn once() { + const A: Once = Once::new(); + + let _a = A.call_once(|| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once` + + let _a = A.call_once_force(|_| {}); + //~^ WARN mutation of an interior mutable `const` item with call to `call_once_force` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.wait_force(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_force` +} + +fn rwlock() { + const A: RwLock = RwLock::new(0); + + let _a = A.set(1); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.replace(2); + //~^ WARN mutation of an interior mutable `const` item with call to `replace` + + drop(A.read()); + //~^ WARN mutation of an interior mutable `const` item with call to `read` + + drop(A.try_read()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_read` + + drop(A.write()); + //~^ WARN mutation of an interior mutable `const` item with call to `write` + + drop(A.try_write()); + //~^ WARN mutation of an interior mutable `const` item with call to `try_write` +} + +fn lazy_lock() { + const A: LazyLock = LazyLock::new(|| 0); + + let _a = LazyLock::force(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `force` + + let _a = LazyLock::get(&A); + //~^ WARN mutation of an interior mutable `const` item with call to `get` +} + +fn once_lock() { + const A: OnceLock = OnceLock::new(); + + let _a = A.get(); + //~^ WARN mutation of an interior mutable `const` item with call to `get` + + let _a = A.wait(); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let _a = A.set(10); + //~^ WARN mutation of an interior mutable `const` item with call to `set` + + let _a = A.try_insert(20); + //~^ WARN mutation of an interior mutable `const` item with call to `try_insert` + + let _a = A.get_or_init(|| 30); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_init` + + let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); + //~^ WARN mutation of an interior mutable `const` item with call to `get_or_try_init` +} + +fn condvar() { + const A: Condvar = Condvar::new(); + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + + let _a = A.wait(guard); + //~^ WARN mutation of an interior mutable `const` item with call to `wait` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_while(guard, |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_while` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_ms(guard, 10); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_ms` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout(guard, Duration::from_millis(10)); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout` + + let mutex = Mutex::new(0); + let guard = mutex.lock().unwrap(); + let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); + //~^ WARN mutation of an interior mutable `const` item with call to `wait_timeout_while` + + let _a = A.notify_one(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_one` + + let _a = A.notify_all(); + //~^ WARN mutation of an interior mutable `const` item with call to `notify_all` +} + +fn main() {} diff --git a/tests/ui/lint/const-item-interior-mutations-const.stderr b/tests/ui/lint/const-item-interior-mutations-const.stderr new file mode 100644 index 0000000000000..7d3e7bee7fbb0 --- /dev/null +++ b/tests/ui/lint/const-item-interior-mutations-const.stderr @@ -0,0 +1,513 @@ +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const.rs:17:14 + | +LL | let _a = A.set(1); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see + = note: `#[warn(const_item_interior_mutations)]` on by default +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/const-item-interior-mutations-const.rs:20:14 + | +LL | let _a = A.replace(2); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `lock` + --> $DIR/const-item-interior-mutations-const.rs:23:10 + | +LL | drop(A.lock()); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_lock` + --> $DIR/const-item-interior-mutations-const.rs:26:10 + | +LL | drop(A.try_lock()); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `clear_poison` + --> $DIR/const-item-interior-mutations-const.rs:29:14 + | +LL | let _a = A.clear_poison(); + | -^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Mutex` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Mutex = Mutex::new(0); +LL + static A: Mutex = Mutex::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `call_once` + --> $DIR/const-item-interior-mutations-const.rs:36:14 + | +LL | let _a = A.call_once(|| {}); + | -^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `call_once_force` + --> $DIR/const-item-interior-mutations-const.rs:39:14 + | +LL | let _a = A.call_once_force(|_| {}); + | -^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait` + --> $DIR/const-item-interior-mutations-const.rs:42:14 + | +LL | let _a = A.wait(); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_force` + --> $DIR/const-item-interior-mutations-const.rs:45:14 + | +LL | let _a = A.wait_force(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Once` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Once = Once::new(); +LL + static A: Once = Once::new(); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const.rs:52:14 + | +LL | let _a = A.set(1); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `replace` + --> $DIR/const-item-interior-mutations-const.rs:55:14 + | +LL | let _a = A.replace(2); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `read` + --> $DIR/const-item-interior-mutations-const.rs:58:10 + | +LL | drop(A.read()); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_read` + --> $DIR/const-item-interior-mutations-const.rs:61:10 + | +LL | drop(A.try_read()); + | -^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `write` + --> $DIR/const-item-interior-mutations-const.rs:64:10 + | +LL | drop(A.write()); + | -^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `try_write` + --> $DIR/const-item-interior-mutations-const.rs:67:10 + | +LL | drop(A.try_write()); + | -^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::RwLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: RwLock = RwLock::new(0); +LL + static A: RwLock = RwLock::new(0); + | + +warning: mutation of an interior mutable `const` item with call to `force` + --> $DIR/const-item-interior-mutations-const.rs:74:14 + | +LL | let _a = LazyLock::force(&A); + | ^^^^^^^^^^^^^^^^^-^ + | | + | `A` is a interior mutable `const` item of type `LazyLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: LazyLock = LazyLock::new(|| 0); +LL + static A: LazyLock = LazyLock::new(|| 0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const.rs:77:14 + | +LL | let _a = LazyLock::get(&A); + | ^^^^^^^^^^^^^^^-^ + | | + | `A` is a interior mutable `const` item of type `LazyLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: LazyLock = LazyLock::new(|| 0); +LL + static A: LazyLock = LazyLock::new(|| 0); + | + +warning: mutation of an interior mutable `const` item with call to `get` + --> $DIR/const-item-interior-mutations-const.rs:84:14 + | +LL | let _a = A.get(); + | -^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait` + --> $DIR/const-item-interior-mutations-const.rs:87:14 + | +LL | let _a = A.wait(); + | -^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `set` + --> $DIR/const-item-interior-mutations-const.rs:90:14 + | +LL | let _a = A.set(10); + | -^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `try_insert` + --> $DIR/const-item-interior-mutations-const.rs:93:14 + | +LL | let _a = A.try_insert(20); + | -^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_init` + --> $DIR/const-item-interior-mutations-const.rs:96:14 + | +LL | let _a = A.get_or_init(|| 30); + | -^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `get_or_try_init` + --> $DIR/const-item-interior-mutations-const.rs:99:14 + | +LL | let _a = A.get_or_try_init(|| Ok::<_, ()>(40)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `OnceLock` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: OnceLock = OnceLock::new(); +LL + static A: OnceLock = OnceLock::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait` + --> $DIR/const-item-interior-mutations-const.rs:109:14 + | +LL | let _a = A.wait(guard); + | -^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_while` + --> $DIR/const-item-interior-mutations-const.rs:114:14 + | +LL | let _a = A.wait_while(guard, |x| *x == 0); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_timeout_ms` + --> $DIR/const-item-interior-mutations-const.rs:119:14 + | +LL | let _a = A.wait_timeout_ms(guard, 10); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_timeout` + --> $DIR/const-item-interior-mutations-const.rs:124:14 + | +LL | let _a = A.wait_timeout(guard, Duration::from_millis(10)); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `wait_timeout_while` + --> $DIR/const-item-interior-mutations-const.rs:129:14 + | +LL | let _a = A.wait_timeout_while(guard, Duration::from_millis(10), |x| *x == 0); + | -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `notify_one` + --> $DIR/const-item-interior-mutations-const.rs:132:14 + | +LL | let _a = A.notify_one(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: mutation of an interior mutable `const` item with call to `notify_all` + --> $DIR/const-item-interior-mutations-const.rs:135:14 + | +LL | let _a = A.notify_all(); + | -^^^^^^^^^^^^^ + | | + | `A` is a interior mutable `const` item of type `std::sync::Condvar` + | + = note: each usage of a `const` item creates a new temporary + = note: only the temporaries and never the original `const A` will be modified + = help: for more details on interior mutability see +help: for a shared instance of `A`, consider making it a `static` item instead + | +LL - const A: Condvar = Condvar::new(); +LL + static A: Condvar = Condvar::new(); + | + +warning: 30 warnings emitted + diff --git a/tests/ui/suggestions/auxiliary/hidden-struct.rs b/tests/ui/suggestions/auxiliary/hidden-struct.rs index 1f495a9f2224a..ee24389bebd7c 100644 --- a/tests/ui/suggestions/auxiliary/hidden-struct.rs +++ b/tests/ui/suggestions/auxiliary/hidden-struct.rs @@ -33,3 +33,6 @@ impl Marker for hidden::Foo {} impl Marker for hidden1::Bar {} impl Marker for Baz {} impl Marker for Quux {} + + +pub use crate as library; diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs index a83e496f2703d..0716e4e2e143b 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs @@ -21,7 +21,12 @@ pub fn test4(_: Quux) {} fn test5() {} +fn test6() {} + fn main() { test5::(); //~^ ERROR [E0277] + + test6::(); + //~^ ERROR [E0277] } diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr index e0444c93eeece..a111d0e5aa95a 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr @@ -38,7 +38,7 @@ LL + use hidden_struct::Quux; | error[E0277]: the trait bound `i32: Marker` is not satisfied - --> $DIR/dont-suggest-foreign-doc-hidden.rs:25:13 + --> $DIR/dont-suggest-foreign-doc-hidden.rs:27:13 | LL | test5::(); | ^^^ the trait `Marker` is not implemented for `i32` @@ -59,7 +59,29 @@ note: required by a bound in `test5` LL | fn test5() {} | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5` -error: aborting due to 5 previous errors +error[E0277]: the trait bound `i32: Marker` is not satisfied + --> $DIR/dont-suggest-foreign-doc-hidden.rs:30:13 + | +LL | test6::(); + | ^^^ the trait `Marker` is not implemented for `i32` + | +help: the following other types implement trait `Marker` + --> $DIR/auxiliary/hidden-struct.rs:31:1 + | +LL | impl Marker for Option {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Option` +... +LL | impl Marker for Baz {} + | ^^^^^^^^^^^^^^^^^^^ `Baz` +LL | impl Marker for Quux {} + | ^^^^^^^^^^^^^^^^^^^^ `Quux` +note: required by a bound in `test6` + --> $DIR/dont-suggest-foreign-doc-hidden.rs:24:13 + | +LL | fn test6() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test6` + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0277, E0412. For more information about an error, try `rustc --explain E0277`.