diff --git a/compiler/rustc_codegen_cranelift/example/example.rs b/compiler/rustc_codegen_cranelift/example/example.rs index 1ef2aa5dd8ea4..aeb38331edb02 100644 --- a/compiler/rustc_codegen_cranelift/example/example.rs +++ b/compiler/rustc_codegen_cranelift/example/example.rs @@ -1,6 +1,6 @@ #![feature(no_core, unboxed_closures)] #![no_core] -#![allow(dead_code)] +#![allow(dead_code, unnecessary_transmutes)] extern crate mini_core; diff --git a/compiler/rustc_codegen_gcc/example/example.rs b/compiler/rustc_codegen_gcc/example/example.rs index 03470b74d0a13..888fa89201e13 100644 --- a/compiler/rustc_codegen_gcc/example/example.rs +++ b/compiler/rustc_codegen_gcc/example/example.rs @@ -1,6 +1,6 @@ #![feature(no_core, unboxed_closures)] #![no_core] -#![allow(dead_code)] +#![allow(dead_code, unnecessary_transmutes)] extern crate mini_core; @@ -11,11 +11,7 @@ fn abc(a: u8) -> u8 { } fn bcd(b: bool, a: u8) -> u8 { - if b { - a * 2 - } else { - a * 3 - } + if b { a * 2 } else { a * 3 } } fn call() { diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index a8b49e9552c30..925898d817371 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -584,12 +584,10 @@ fn thin_lto( } } -fn enable_autodiff_settings(ad: &[config::AutoDiff], module: &mut ModuleCodegen) { +fn enable_autodiff_settings(ad: &[config::AutoDiff]) { for &val in ad { + // We intentionally don't use a wildcard, to not forget handling anything new. match val { - config::AutoDiff::PrintModBefore => { - unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) }; - } config::AutoDiff::PrintPerf => { llvm::set_print_perf(true); } @@ -603,17 +601,23 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff], module: &mut ModuleCodegen< llvm::set_inline(true); } config::AutoDiff::LooseTypes => { - llvm::set_loose_types(false); + llvm::set_loose_types(true); } config::AutoDiff::PrintSteps => { llvm::set_print(true); } - // We handle this below + // We handle this in the PassWrapper.cpp + config::AutoDiff::PrintPasses => {} + // We handle this in the PassWrapper.cpp + config::AutoDiff::PrintModBefore => {} + // We handle this in the PassWrapper.cpp config::AutoDiff::PrintModAfter => {} - // We handle this below + // We handle this in the PassWrapper.cpp config::AutoDiff::PrintModFinal => {} // This is required and already checked config::AutoDiff::Enable => {} + // We handle this below + config::AutoDiff::NoPostopt => {} } } // This helps with handling enums for now. @@ -647,27 +651,27 @@ pub(crate) fn run_pass_manager( // We then run the llvm_optimize function a second time, to optimize the code which we generated // in the enzyme differentiation pass. let enable_ad = config.autodiff.contains(&config::AutoDiff::Enable); - let stage = - if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD }; + let stage = if thin { + write::AutodiffStage::PreAD + } else { + if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD } + }; if enable_ad { - enable_autodiff_settings(&config.autodiff, module); + enable_autodiff_settings(&config.autodiff); } unsafe { write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?; } - if cfg!(llvm_enzyme) && enable_ad { - // This is the post-autodiff IR, mainly used for testing and educational purposes. - if config.autodiff.contains(&config::AutoDiff::PrintModAfter) { - unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) }; - } - + if cfg!(llvm_enzyme) && enable_ad && !thin { let opt_stage = llvm::OptStage::FatLTO; let stage = write::AutodiffStage::PostAD; - unsafe { - write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?; + if !config.autodiff.contains(&config::AutoDiff::NoPostopt) { + unsafe { + write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?; + } } // This is the final IR, so people should be able to inspect the optimized autodiff output, diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 18d221d232e82..4ac77c8f7f165 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -572,6 +572,10 @@ pub(crate) unsafe fn llvm_optimize( let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); let run_enzyme = autodiff_stage == AutodiffStage::DuringAD; + let print_before_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModBefore); + let print_after_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModAfter); + let print_passes = config.autodiff.contains(&config::AutoDiff::PrintPasses); + let merge_functions; let unroll_loops; let vectorize_slp; let vectorize_loop; @@ -579,13 +583,20 @@ pub(crate) unsafe fn llvm_optimize( // When we build rustc with enzyme/autodiff support, we want to postpone size-increasing // optimizations until after differentiation. Our pipeline is thus: (opt + enzyme), (full opt). // We therefore have two calls to llvm_optimize, if autodiff is used. + // + // We also must disable merge_functions, since autodiff placeholder/dummy bodies tend to be + // identical. We run opts before AD, so there is a chance that LLVM will merge our dummies. + // In that case, we lack some dummy bodies and can't replace them with the real AD code anymore. + // We then would need to abort compilation. This was especially common in test cases. if consider_ad && autodiff_stage != AutodiffStage::PostAD { + merge_functions = false; unroll_loops = false; vectorize_slp = false; vectorize_loop = false; } else { unroll_loops = opt_level != config::OptLevel::Size && opt_level != config::OptLevel::SizeMin; + merge_functions = config.merge_functions; vectorize_slp = config.vectorize_slp; vectorize_loop = config.vectorize_loop; } @@ -663,13 +674,16 @@ pub(crate) unsafe fn llvm_optimize( thin_lto_buffer, config.emit_thin_lto, config.emit_thin_lto_summary, - config.merge_functions, + merge_functions, unroll_loops, vectorize_slp, vectorize_loop, config.no_builtins, config.emit_lifetime_markers, run_enzyme, + print_before_enzyme, + print_after_enzyme, + print_passes, sanitizer_options.as_ref(), pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index e7c071d05aa8f..0147bd5a66581 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -473,7 +473,7 @@ pub(crate) fn differentiate<'ll>( return Err(diag_handler.handle().emit_almost_fatal(AutoDiffWithoutEnable)); } - // Before dumping the module, we want all the TypeTrees to become part of the module. + // Here we replace the placeholder code with the actual autodiff code, which calls Enzyme. for item in diff_items.iter() { let name = item.source.clone(); let fn_def: Option<&llvm::Value> = cx.get_function(&name); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 9ff04f729030c..ffb490dcdc22b 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2454,6 +2454,9 @@ unsafe extern "C" { DisableSimplifyLibCalls: bool, EmitLifetimeMarkers: bool, RunEnzyme: bool, + PrintBeforeEnzyme: bool, + PrintAfterEnzyme: bool, + PrintPasses: bool, SanitizerOptions: Option<&SanitizerOptions>, PGOGenPath: *const c_char, PGOUsePath: *const c_char, diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 4ca317e3a1e53..40c63f2b250f5 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -158,6 +158,31 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.copy_op(&val, dest)?; } + sym::fadd_algebraic + | sym::fsub_algebraic + | sym::fmul_algebraic + | sym::fdiv_algebraic + | sym::frem_algebraic => { + let a = self.read_immediate(&args[0])?; + let b = self.read_immediate(&args[1])?; + + let op = match intrinsic_name { + sym::fadd_algebraic => BinOp::Add, + sym::fsub_algebraic => BinOp::Sub, + sym::fmul_algebraic => BinOp::Mul, + sym::fdiv_algebraic => BinOp::Div, + sym::frem_algebraic => BinOp::Rem, + + _ => bug!(), + }; + + let res = self.binary_op(op, &a, &b)?; + // `binary_op` already called `generate_nan` if needed. + + // FIXME: Miri should add some non-determinism to the result here to catch any dependences on exact computations. This has previously been done, but the behaviour was removed as part of constification. + self.write_immediate(*res, dest)?; + } + sym::ctpop | sym::cttz | sym::cttz_nonzero diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index a084dacfb5be8..f9dce5a5198d0 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1,7 +1,9 @@ use std::iter; use std::ops::ControlFlow; -use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange}; +use rustc_abi::{ + BackendRepr, Integer, IntegerType, TagEncoding, VariantIdx, Variants, WrappingRange, +}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagMessage; use rustc_hir::intravisit::VisitorExt; @@ -1243,6 +1245,14 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { }; } + if let Some(IntegerType::Fixed(Integer::I128, _)) = def.repr().int { + return FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_128bit, + help: None, + }; + } + use improper_ctypes::check_non_exhaustive_variant; let non_exhaustive = def.variant_list_has_applicable_non_exhaustive(); diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a49eb76734fb9..17d501c5730b8 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -117,6 +117,7 @@ declare_lint_pass! { UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNNAMEABLE_TEST_ITEMS, UNNAMEABLE_TYPES, + UNNECESSARY_TRANSMUTES, UNREACHABLE_CODE, UNREACHABLE_PATTERNS, UNSAFE_ATTR_OUTSIDE_UNSAFE, @@ -4909,6 +4910,30 @@ declare_lint! { "detects pointer to integer transmutes in const functions and associated constants", } +declare_lint! { + /// The `unnecessary_transmutes` lint detects transmutations that have safer alternatives. + /// + /// ### Example + /// + /// ```rust + /// fn bytes_at_home(x: [u8; 4]) -> u32 { + /// unsafe { std::mem::transmute(x) } + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Using an explicit method is preferable over calls to + /// [`transmute`](https://doc.rust-lang.org/std/mem/fn.transmute.html) as + /// they more clearly communicate the intent, are easier to review, and + /// are less likely to accidentally result in unsoundness. + pub UNNECESSARY_TRANSMUTES, + Warn, + "detects transmutes that are shadowed by std methods" +} + declare_lint! { /// The `tail_expr_drop_order` lint looks for those values generated at the tail expression location, /// that runs a custom `Drop` destructor. diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index e02c80c50b14a..8bee051dd4c3c 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/Verifier.h" +#include "llvm/IRPrinter/IRPrintingPasses.h" #include "llvm/LTO/LTO.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/TargetRegistry.h" @@ -703,7 +704,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef, bool EmitThinLTO, bool EmitThinLTOSummary, bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, - bool EmitLifetimeMarkers, bool RunEnzyme, + bool EmitLifetimeMarkers, bool RunEnzyme, bool PrintBeforeEnzyme, + bool PrintAfterEnzyme, bool PrintPasses, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, const char *InstrProfileOutput, const char *PGOSampleUsePath, @@ -1048,14 +1050,38 @@ extern "C" LLVMRustResult LLVMRustOptimize( // now load "-enzyme" pass: #ifdef ENZYME if (RunEnzyme) { - registerEnzymeAndPassPipeline(PB, true); + + if (PrintBeforeEnzyme) { + // Handle the Rust flag `-Zautodiff=PrintModBefore`. + std::string Banner = "Module before EnzymeNewPM"; + MPM.addPass(PrintModulePass(outs(), Banner, true, false)); + } + + registerEnzymeAndPassPipeline(PB, false); if (auto Err = PB.parsePassPipeline(MPM, "enzyme")) { std::string ErrMsg = toString(std::move(Err)); LLVMRustSetLastError(ErrMsg.c_str()); return LLVMRustResult::Failure; } + + if (PrintAfterEnzyme) { + // Handle the Rust flag `-Zautodiff=PrintModAfter`. + std::string Banner = "Module after EnzymeNewPM"; + MPM.addPass(PrintModulePass(outs(), Banner, true, false)); + } } #endif + if (PrintPasses) { + // Print all passes from the PM: + std::string Pipeline; + raw_string_ostream SOS(Pipeline); + MPM.printPipeline(SOS, [&PIC](StringRef ClassName) { + auto PassName = PIC.getPassNameForClassName(ClassName); + return PassName.empty() ? ClassName : PassName; + }); + outs() << Pipeline; + outs() << "\n"; + } // Upgrade all calls to old intrinsics first. for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;) diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl index 5628f4c9381b3..a1264471a2df5 100644 --- a/compiler/rustc_mir_transform/messages.ftl +++ b/compiler/rustc_mir_transform/messages.ftl @@ -84,3 +84,4 @@ mir_transform_undefined_transmute = pointers cannot be transmuted to integers du .help = for more information, see https://doc.rust-lang.org/std/mem/fn.transmute.html mir_transform_unknown_pass_name = MIR pass `{$name}` is unknown and will be ignored +mir_transform_unnecessary_transmute = unnecessary transmute diff --git a/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs new file mode 100644 index 0000000000000..8be782dcbf0ad --- /dev/null +++ b/compiler/rustc_mir_transform/src/check_unnecessary_transmutes.rs @@ -0,0 +1,100 @@ +use rustc_middle::mir::visit::Visitor; +use rustc_middle::mir::{Body, Location, Operand, Terminator, TerminatorKind}; +use rustc_middle::ty::*; +use rustc_session::lint::builtin::UNNECESSARY_TRANSMUTES; +use rustc_span::source_map::Spanned; +use rustc_span::{Span, sym}; + +use crate::errors::UnnecessaryTransmute as Error; + +/// Check for transmutes that overlap with stdlib methods. +/// For example, transmuting `[u8; 4]` to `u32`. +pub(super) struct CheckUnnecessaryTransmutes; + +impl<'tcx> crate::MirLint<'tcx> for CheckUnnecessaryTransmutes { + fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { + let mut checker = UnnecessaryTransmuteChecker { body, tcx }; + checker.visit_body(body); + } +} + +struct UnnecessaryTransmuteChecker<'a, 'tcx> { + body: &'a Body<'tcx>, + tcx: TyCtxt<'tcx>, +} + +impl<'a, 'tcx> UnnecessaryTransmuteChecker<'a, 'tcx> { + fn is_unnecessary_transmute( + &self, + function: &Operand<'tcx>, + arg: String, + span: Span, + ) -> Option { + let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder(); + let [input] = fn_sig.inputs() else { return None }; + + let err = |sugg| Error { span, sugg, help: None }; + + Some(match (input.kind(), fn_sig.output().kind()) { + // dont check the length; transmute does that for us. + // [u8; _] => primitive + (Array(t, _), Uint(_) | Float(_) | Int(_)) if *t.kind() == Uint(UintTy::U8) => Error { + sugg: format!("{}::from_ne_bytes({arg})", fn_sig.output()), + help: Some( + "there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order", + ), + span, + }, + // primitive => [u8; _] + (Uint(_) | Float(_) | Int(_), Array(t, _)) if *t.kind() == Uint(UintTy::U8) => Error { + sugg: format!("{input}::to_ne_bytes({arg})"), + help: Some( + "there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order", + ), + span, + }, + // char → u32 + (Char, Uint(UintTy::U32)) => err(format!("u32::from({arg})")), + // u32 → char + (Uint(UintTy::U32), Char) => Error { + sugg: format!("char::from_u32_unchecked({arg})"), + help: Some("consider `char::from_u32(…).unwrap()`"), + span, + }, + // uNN → iNN + (Uint(ty), Int(_)) => err(format!("{}::cast_signed({arg})", ty.name_str())), + // iNN → uNN + (Int(ty), Uint(_)) => err(format!("{}::cast_unsigned({arg})", ty.name_str())), + // fNN → uNN + (Float(ty), Uint(..)) => err(format!("{}::to_bits({arg})", ty.name_str())), + // uNN → fNN + (Uint(_), Float(ty)) => err(format!("{}::from_bits({arg})", ty.name_str())), + // bool → { x8 } + (Bool, Int(..) | Uint(..)) => err(format!("({arg}) as {}", fn_sig.output())), + // u8 → bool + (Uint(_), Bool) => err(format!("({arg} == 1)")), + _ => return None, + }) + } +} + +impl<'tcx> Visitor<'tcx> for UnnecessaryTransmuteChecker<'_, 'tcx> { + // Check each block's terminator for calls to pointer to integer transmutes + // in const functions or associated constants and emit a lint. + fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { + if let TerminatorKind::Call { func, args, .. } = &terminator.kind + && let [Spanned { span: arg, .. }] = **args + && let Some((func_def_id, _)) = func.const_fn_def() + && self.tcx.is_intrinsic(func_def_id, sym::transmute) + && let span = self.body.source_info(location).span + && let Some(lint) = self.is_unnecessary_transmute( + func, + self.tcx.sess.source_map().span_to_snippet(arg).expect("ok"), + span, + ) + && let Some(hir_id) = terminator.source_info.scope.lint_root(&self.body.source_scopes) + { + self.tcx.emit_node_span_lint(UNNECESSARY_TRANSMUTES, hir_id, span, lint); + } + } +} diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs index 29698b0c2e445..5b03a4987ed71 100644 --- a/compiler/rustc_mir_transform/src/errors.rs +++ b/compiler/rustc_mir_transform/src/errors.rs @@ -158,6 +158,26 @@ pub(crate) struct MustNotSuspendReason { pub reason: String, } +pub(crate) struct UnnecessaryTransmute { + pub span: Span, + pub sugg: String, + pub help: Option<&'static str>, +} + +// Needed for def_path_str +impl<'a> LintDiagnostic<'a, ()> for UnnecessaryTransmute { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.primary_message(fluent::mir_transform_unnecessary_transmute); + diag.span_suggestion( + self.span, + "replace this with", + self.sugg, + lint::Applicability::MachineApplicable, + ); + self.help.map(|help| diag.help(help)); + } +} + #[derive(LintDiagnostic)] #[diag(mir_transform_undefined_transmute)] #[note] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 4d74ecddfb057..6977d23bd0e29 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -125,6 +125,7 @@ declare_passes! { mod check_null : CheckNull; mod check_packed_ref : CheckPackedRef; mod check_undefined_transmutes : CheckUndefinedTransmutes; + mod check_unnecessary_transmutes: CheckUnnecessaryTransmutes; // This pass is public to allow external drivers to perform MIR cleanup pub mod cleanup_post_borrowck : CleanupPostBorrowck; @@ -391,6 +392,7 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal> { &Lint(check_const_item_mutation::CheckConstItemMutation), &Lint(function_item_references::FunctionItemReferences), &Lint(check_undefined_transmutes::CheckUndefinedTransmutes), + &Lint(check_unnecessary_transmutes::CheckUnnecessaryTransmutes), // What we need to do constant evaluation. &simplify::SimplifyCfg::Initial, &Lint(sanity_check::SanityCheck), diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index bc92b95ce7116..02c164a706cd8 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -246,6 +246,10 @@ pub enum AutoDiff { /// Print the module after running autodiff and optimizations. PrintModFinal, + /// Print all passes scheduled by LLVM + PrintPasses, + /// Disable extra opt run after running autodiff + NoPostopt, /// Enzyme's loose type debug helper (can cause incorrect gradients!!) /// Usable in cases where Enzyme errors with `can not deduce type of X`. LooseTypes, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 36eee5f308656..5f4695fb1841b 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -711,7 +711,7 @@ mod desc { pub(crate) const parse_list: &str = "a space-separated list of strings"; pub(crate) const parse_list_with_polarity: &str = "a comma-separated list of strings, with elements beginning with + or -"; - pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `PrintModFinal`, `LooseTypes`, `Inline`"; + pub(crate) const parse_autodiff: &str = "a comma separated list of settings: `Enable`, `PrintSteps`, `PrintTA`, `PrintAA`, `PrintPerf`, `PrintModBefore`, `PrintModAfter`, `PrintModFinal`, `PrintPasses`, `NoPostopt`, `LooseTypes`, `Inline`"; pub(crate) const parse_comma_list: &str = "a comma-separated list of strings"; pub(crate) const parse_opt_comma_list: &str = parse_comma_list; pub(crate) const parse_number: &str = "a number"; @@ -1360,6 +1360,8 @@ pub mod parse { "PrintModBefore" => AutoDiff::PrintModBefore, "PrintModAfter" => AutoDiff::PrintModAfter, "PrintModFinal" => AutoDiff::PrintModFinal, + "NoPostopt" => AutoDiff::NoPostopt, + "PrintPasses" => AutoDiff::PrintPasses, "LooseTypes" => AutoDiff::LooseTypes, "Inline" => AutoDiff::Inline, _ => { @@ -2098,6 +2100,8 @@ options! { `=PrintModBefore` `=PrintModAfter` `=PrintModFinal` + `=PrintPasses`, + `=NoPostopt` `=LooseTypes` `=Inline` Multiple options can be combined with commas."), diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 07005215e4f32..69c8b9119ab23 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -516,7 +516,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zawrs", Unstable(sym::riscv_target_feature), &[]), ("zba", Stable, &[]), ("zbb", Stable, &[]), - ("zbc", Stable, &[]), + ("zbc", Stable, &["zbkc"]), // Zbc ⊃ Zbkc ("zbkb", Stable, &[]), ("zbkc", Stable, &[]), ("zbkx", Stable, &[]), @@ -545,20 +545,20 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zknd", Stable, &[]), ("zkne", Stable, &[]), ("zknh", Stable, &[]), - ("zkr", Stable, &["zicsr"]), + ("zkr", Stable, &[]), ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]), ("zksed", Stable, &[]), ("zksh", Stable, &[]), ("zkt", Stable, &[]), ("ztso", Unstable(sym::riscv_target_feature), &[]), - ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), + ("zvbb", Unstable(sym::riscv_target_feature), &["zvkb"]), // Zvbb ⊃ Zvkb ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]), ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]), ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]), ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]), ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]), ("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]), - ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zfhmin"]), + ("zvfh", Unstable(sym::riscv_target_feature), &["zvfhmin", "zve32f", "zfhmin"]), // Zvfh ⊃ Zvfhmin ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]), ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]), ("zvkg", Unstable(sym::riscv_target_feature), &["zve32x"]), @@ -567,7 +567,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]), ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]), ("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]), - ("zvknhb", Unstable(sym::riscv_target_feature), &["zve64x"]), + ("zvknhb", Unstable(sym::riscv_target_feature), &["zvknha", "zve64x"]), // Zvknhb ⊃ Zvknha ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]), ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]), ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]), diff --git a/library/alloctests/tests/fmt.rs b/library/alloctests/tests/fmt.rs index c13074c53b73d..a20e8c623360f 100644 --- a/library/alloctests/tests/fmt.rs +++ b/library/alloctests/tests/fmt.rs @@ -1,6 +1,7 @@ #![deny(warnings)] // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint #![allow(static_mut_refs)] +#![cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] use std::cell::RefCell; use std::fmt::{self, Write}; diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index ac808038f8900..d820965a7463e 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -21,6 +21,7 @@ pub(super) const fn from_u32(i: u32) -> Option { /// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`]. #[inline] #[must_use] +#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { // SAFETY: the caller must guarantee that `i` is a valid char value. unsafe { @@ -221,6 +222,7 @@ impl FromStr for char { } #[inline] +#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] const fn char_try_from_u32(i: u32) -> Result { // This is an optimized version of the check // (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF), diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index a01efb2adebe3..a7563f918a241 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1497,6 +1497,7 @@ pub const fn forget(_: T); /// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.: /// /// ``` +/// # #![cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] /// let raw_bytes = [0x78, 0x56, 0x34, 0x12]; /// /// let num = unsafe { @@ -2429,35 +2430,35 @@ pub unsafe fn float_to_int_unchecked(value: Float) -> In /// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`]. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fadd_algebraic(a: T, b: T) -> T; +pub const fn fadd_algebraic(a: T, b: T) -> T; /// Float subtraction that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`]. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fsub_algebraic(a: T, b: T) -> T; +pub const fn fsub_algebraic(a: T, b: T) -> T; /// Float multiplication that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`]. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fmul_algebraic(a: T, b: T) -> T; +pub const fn fmul_algebraic(a: T, b: T) -> T; /// Float division that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`]. #[rustc_nounwind] #[rustc_intrinsic] -pub fn fdiv_algebraic(a: T, b: T) -> T; +pub const fn fdiv_algebraic(a: T, b: T) -> T; /// Float remainder that allows optimizations based on algebraic rules. /// /// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`]. #[rustc_nounwind] #[rustc_intrinsic] -pub fn frem_algebraic(a: T, b: T) -> T; +pub const fn frem_algebraic(a: T, b: T) -> T; /// Returns the number of bits set in an integer type `T` /// diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index e25f7091c933c..b1119d4899bab 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -197,16 +197,22 @@ impl f128 { #[unstable(feature = "f128", issue = "116909")] pub const MAX: f128 = 1.18973149535723176508575932662800702e+4932_f128; - /// One greater than the minimum possible normal power of 2 exponent. + /// One greater than the minimum possible *normal* power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MIN_EXP`, then normal numbers - /// ≥ 0.5 × 2x. + /// This corresponds to the exact minimum possible *normal* power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all normal numbers representable by this type are + /// greater than or equal to 0.5 × 2MIN_EXP. #[unstable(feature = "f128", issue = "116909")] pub const MIN_EXP: i32 = -16_381; - /// Maximum possible power of 2 exponent. + /// One greater than the maximum possible power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MAX_EXP`, then normal numbers - /// < 1 × 2x. + /// This corresponds to the exact maximum possible power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all numbers representable by this type are + /// strictly less than 2MAX_EXP. #[unstable(feature = "f128", issue = "116909")] pub const MAX_EXP: i32 = 16_384; @@ -904,6 +910,7 @@ impl f128 { #[inline] #[unstable(feature = "f128", issue = "116909")] #[must_use = "this returns the result of the operation, without modifying the original"] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub const fn to_bits(self) -> u128 { // SAFETY: `u128` is a plain old datatype so we can always transmute to it. unsafe { mem::transmute(self) } @@ -951,6 +958,7 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub const fn from_bits(v: u128) -> Self { // It turns out the safety issues with sNaN were overblown! Hooray! // SAFETY: `u128` is a plain old datatype so we can always transmute from it. @@ -1374,8 +1382,9 @@ impl f128 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_add(self, rhs: f128) -> f128 { + pub const fn algebraic_add(self, rhs: f128) -> f128 { intrinsics::fadd_algebraic(self, rhs) } @@ -1384,8 +1393,9 @@ impl f128 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_sub(self, rhs: f128) -> f128 { + pub const fn algebraic_sub(self, rhs: f128) -> f128 { intrinsics::fsub_algebraic(self, rhs) } @@ -1394,8 +1404,9 @@ impl f128 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_mul(self, rhs: f128) -> f128 { + pub const fn algebraic_mul(self, rhs: f128) -> f128 { intrinsics::fmul_algebraic(self, rhs) } @@ -1404,8 +1415,9 @@ impl f128 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_div(self, rhs: f128) -> f128 { + pub const fn algebraic_div(self, rhs: f128) -> f128 { intrinsics::fdiv_algebraic(self, rhs) } @@ -1414,8 +1426,9 @@ impl f128 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_rem(self, rhs: f128) -> f128 { + pub const fn algebraic_rem(self, rhs: f128) -> f128 { intrinsics::frem_algebraic(self, rhs) } } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index bd00ed0f4ede0..54e38d9e1a6f1 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -192,16 +192,22 @@ impl f16 { #[unstable(feature = "f16", issue = "116909")] pub const MAX: f16 = 6.5504e+4_f16; - /// One greater than the minimum possible normal power of 2 exponent. + /// One greater than the minimum possible *normal* power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MIN_EXP`, then normal numbers - /// ≥ 0.5 × 2x. + /// This corresponds to the exact minimum possible *normal* power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all normal numbers representable by this type are + /// greater than or equal to 0.5 × 2MIN_EXP. #[unstable(feature = "f16", issue = "116909")] pub const MIN_EXP: i32 = -13; - /// Maximum possible power of 2 exponent. + /// One greater than the maximum possible power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MAX_EXP`, then normal numbers - /// < 1 × 2x. + /// This corresponds to the exact maximum possible power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all numbers representable by this type are + /// strictly less than 2MAX_EXP. #[unstable(feature = "f16", issue = "116909")] pub const MAX_EXP: i32 = 16; @@ -892,6 +898,7 @@ impl f16 { #[inline] #[unstable(feature = "f16", issue = "116909")] #[must_use = "this returns the result of the operation, without modifying the original"] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub const fn to_bits(self) -> u16 { // SAFETY: `u16` is a plain old datatype so we can always transmute to it. unsafe { mem::transmute(self) } @@ -938,6 +945,7 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub const fn from_bits(v: u16) -> Self { // It turns out the safety issues with sNaN were overblown! Hooray! // SAFETY: `u16` is a plain old datatype so we can always transmute from it. @@ -1350,8 +1358,9 @@ impl f16 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_add(self, rhs: f16) -> f16 { + pub const fn algebraic_add(self, rhs: f16) -> f16 { intrinsics::fadd_algebraic(self, rhs) } @@ -1360,8 +1369,9 @@ impl f16 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_sub(self, rhs: f16) -> f16 { + pub const fn algebraic_sub(self, rhs: f16) -> f16 { intrinsics::fsub_algebraic(self, rhs) } @@ -1370,8 +1380,9 @@ impl f16 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_mul(self, rhs: f16) -> f16 { + pub const fn algebraic_mul(self, rhs: f16) -> f16 { intrinsics::fmul_algebraic(self, rhs) } @@ -1380,8 +1391,9 @@ impl f16 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_div(self, rhs: f16) -> f16 { + pub const fn algebraic_div(self, rhs: f16) -> f16 { intrinsics::fdiv_algebraic(self, rhs) } @@ -1390,8 +1402,9 @@ impl f16 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_rem(self, rhs: f16) -> f16 { + pub const fn algebraic_rem(self, rhs: f16) -> f16 { intrinsics::frem_algebraic(self, rhs) } } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index c95ad2d0f35ad..e66fd3bb52b86 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -443,16 +443,22 @@ impl f32 { #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX: f32 = 3.40282347e+38_f32; - /// One greater than the minimum possible normal power of 2 exponent. + /// One greater than the minimum possible *normal* power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MIN_EXP`, then normal numbers - /// ≥ 0.5 × 2x. + /// This corresponds to the exact minimum possible *normal* power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all normal numbers representable by this type are + /// greater than or equal to 0.5 × 2MIN_EXP. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_EXP: i32 = -125; - /// Maximum possible power of 2 exponent. + /// One greater than the maximum possible power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MAX_EXP`, then normal numbers - /// < 1 × 2x. + /// This corresponds to the exact maximum possible power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all numbers representable by this type are + /// strictly less than 2MAX_EXP. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX_EXP: i32 = 128; @@ -710,8 +716,7 @@ impl f32 { pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // applies to zeros and NaNs as well. - // SAFETY: This is just transmuting to get the sign bit, it's fine. - unsafe { mem::transmute::(self) & 0x8000_0000 != 0 } + self.to_bits() & 0x8000_0000 != 0 } /// Returns the least number greater than `self`. @@ -1097,6 +1102,7 @@ impl f32 { #[stable(feature = "float_bits_conv", since = "1.20.0")] #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[inline] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub const fn to_bits(self) -> u32 { // SAFETY: `u32` is a plain old datatype so we can always transmute to it. unsafe { mem::transmute(self) } @@ -1142,6 +1148,7 @@ impl f32 { #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub const fn from_bits(v: u32) -> Self { // It turns out the safety issues with sNaN were overblown! Hooray! // SAFETY: `u32` is a plain old datatype so we can always transmute from it. @@ -1516,8 +1523,9 @@ impl f32 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_add(self, rhs: f32) -> f32 { + pub const fn algebraic_add(self, rhs: f32) -> f32 { intrinsics::fadd_algebraic(self, rhs) } @@ -1526,8 +1534,9 @@ impl f32 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_sub(self, rhs: f32) -> f32 { + pub const fn algebraic_sub(self, rhs: f32) -> f32 { intrinsics::fsub_algebraic(self, rhs) } @@ -1536,8 +1545,9 @@ impl f32 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_mul(self, rhs: f32) -> f32 { + pub const fn algebraic_mul(self, rhs: f32) -> f32 { intrinsics::fmul_algebraic(self, rhs) } @@ -1546,8 +1556,9 @@ impl f32 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_div(self, rhs: f32) -> f32 { + pub const fn algebraic_div(self, rhs: f32) -> f32 { intrinsics::fdiv_algebraic(self, rhs) } @@ -1556,8 +1567,9 @@ impl f32 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_rem(self, rhs: f32) -> f32 { + pub const fn algebraic_rem(self, rhs: f32) -> f32 { intrinsics::frem_algebraic(self, rhs) } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 16b762ed6f0c9..2d791437b2825 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -442,16 +442,22 @@ impl f64 { #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX: f64 = 1.7976931348623157e+308_f64; - /// One greater than the minimum possible normal power of 2 exponent. + /// One greater than the minimum possible *normal* power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MIN_EXP`, then normal numbers - /// ≥ 0.5 × 2x. + /// This corresponds to the exact minimum possible *normal* power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all normal numbers representable by this type are + /// greater than or equal to 0.5 × 2MIN_EXP. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MIN_EXP: i32 = -1021; - /// Maximum possible power of 2 exponent. + /// One greater than the maximum possible power of 2 exponent + /// for a significand bounded by 1 ≤ x < 2 (i.e. the IEEE definition). /// - /// If x = `MAX_EXP`, then normal numbers - /// < 1 × 2x. + /// This corresponds to the exact maximum possible power of 2 exponent + /// for a significand bounded by 0.5 ≤ x < 1 (i.e. the C definition). + /// In other words, all numbers representable by this type are + /// strictly less than 2MAX_EXP. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const MAX_EXP: i32 = 1024; @@ -718,8 +724,7 @@ impl f64 { pub const fn is_sign_negative(self) -> bool { // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // applies to zeros and NaNs as well. - // SAFETY: This is just transmuting to get the sign bit, it's fine. - unsafe { mem::transmute::(self) & Self::SIGN_MASK != 0 } + self.to_bits() & Self::SIGN_MASK != 0 } #[must_use] @@ -1095,6 +1100,7 @@ impl f64 { without modifying the original"] #[stable(feature = "float_bits_conv", since = "1.20.0")] #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] #[inline] pub const fn to_bits(self) -> u64 { // SAFETY: `u64` is a plain old datatype so we can always transmute to it. @@ -1141,6 +1147,7 @@ impl f64 { #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[must_use] #[inline] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] pub const fn from_bits(v: u64) -> Self { // It turns out the safety issues with sNaN were overblown! Hooray! // SAFETY: `u64` is a plain old datatype so we can always transmute from it. @@ -1515,8 +1522,9 @@ impl f64 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_add(self, rhs: f64) -> f64 { + pub const fn algebraic_add(self, rhs: f64) -> f64 { intrinsics::fadd_algebraic(self, rhs) } @@ -1525,8 +1533,9 @@ impl f64 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_sub(self, rhs: f64) -> f64 { + pub const fn algebraic_sub(self, rhs: f64) -> f64 { intrinsics::fsub_algebraic(self, rhs) } @@ -1535,8 +1544,9 @@ impl f64 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_mul(self, rhs: f64) -> f64 { + pub const fn algebraic_mul(self, rhs: f64) -> f64 { intrinsics::fmul_algebraic(self, rhs) } @@ -1545,8 +1555,9 @@ impl f64 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_div(self, rhs: f64) -> f64 { + pub const fn algebraic_div(self, rhs: f64) -> f64 { intrinsics::fdiv_algebraic(self, rhs) } @@ -1555,8 +1566,9 @@ impl f64 { /// See [algebraic operators](primitive@f32#algebraic-operators) for more info. #[must_use = "method returns a new number and does not mutate the original value"] #[unstable(feature = "float_algebraic", issue = "136469")] + #[rustc_const_unstable(feature = "float_algebraic", issue = "136469")] #[inline] - pub fn algebraic_rem(self, rhs: f64) -> f64 { + pub const fn algebraic_rem(self, rhs: f64) -> f64 { intrinsics::frem_algebraic(self, rhs) } } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 05d8216ac27eb..8d31a7b697a80 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -3675,6 +3675,7 @@ macro_rules! int_impl { /// ``` #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] // SAFETY: const sound because integers are plain old datatypes so we can always // transmute them to arrays of bytes #[must_use = "this returns the result of the operation, \ @@ -3778,6 +3779,7 @@ macro_rules! int_impl { /// ``` #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] #[must_use] // SAFETY: const sound because integers are plain old datatypes so we can always // transmute to them diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 3678bb091e7d0..bc6cb9508167d 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3523,6 +3523,7 @@ macro_rules! uint_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] // SAFETY: const sound because integers are plain old datatypes so we can always // transmute them to arrays of bytes #[inline] @@ -3624,6 +3625,7 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] + #[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))] #[must_use] // SAFETY: const sound because integers are plain old datatypes so we can always // transmute to them diff --git a/library/std/src/sys/env_consts.rs b/library/std/src/sys/env_consts.rs index 018d7954db26a..9683fd47cf96b 100644 --- a/library/std/src/sys/env_consts.rs +++ b/library/std/src/sys/env_consts.rs @@ -389,6 +389,17 @@ pub mod os { pub const EXE_EXTENSION: &str = "exe"; } +#[cfg(target_os = "zkvm")] +pub mod os { + pub const FAMILY: &str = ""; + pub const OS: &str = ""; + pub const DLL_PREFIX: &str = ""; + pub const DLL_SUFFIX: &str = ".elf"; + pub const DLL_EXTENSION: &str = "elf"; + pub const EXE_SUFFIX: &str = ".elf"; + pub const EXE_EXTENSION: &str = "elf"; +} + // The fallback when none of the other gates match. #[else] pub mod os { diff --git a/library/std/src/sys/pal/zkvm/env.rs b/library/std/src/sys/pal/zkvm/env.rs deleted file mode 100644 index b85153642b1c9..0000000000000 --- a/library/std/src/sys/pal/zkvm/env.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub mod os { - pub const FAMILY: &str = ""; - pub const OS: &str = ""; - pub const DLL_PREFIX: &str = ""; - pub const DLL_SUFFIX: &str = ".elf"; - pub const DLL_EXTENSION: &str = "elf"; - pub const EXE_SUFFIX: &str = ".elf"; - pub const EXE_EXTENSION: &str = "elf"; -} diff --git a/library/stdarch b/library/stdarch index 4666c7376f25a..1245618ccf5b2 160000 --- a/library/stdarch +++ b/library/stdarch @@ -1 +1 @@ -Subproject commit 4666c7376f25a265c74535585d622da3da6dfeb1 +Subproject commit 1245618ccf5b2df7ab1ebb0279b9f3f726670161 diff --git a/src/bootstrap/src/core/build_steps/suggest.rs b/src/bootstrap/src/core/build_steps/suggest.rs index 6a6731cafc54a..fd4918961adba 100644 --- a/src/bootstrap/src/core/build_steps/suggest.rs +++ b/src/bootstrap/src/core/build_steps/suggest.rs @@ -13,7 +13,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) { let git_config = builder.config.git_config(); let suggestions = builder .tool_cmd(Tool::SuggestTests) - .env("SUGGEST_TESTS_GIT_REPOSITORY", git_config.git_repository) .env("SUGGEST_TESTS_NIGHTLY_BRANCH", git_config.nightly_branch) .env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL", git_config.git_merge_commit_email) .run_capture_stdout(builder) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 096f7de65975a..d4fccc535a6b0 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2064,7 +2064,6 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } let git_config = builder.config.git_config(); - cmd.arg("--git-repository").arg(git_config.git_repository); cmd.arg("--nightly-branch").arg(git_config.nightly_branch); cmd.arg("--git-merge-commit-email").arg(git_config.git_merge_commit_email); cmd.force_coloring_in_ci(); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 419976c83b1d0..23b623d9bab23 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2963,7 +2963,6 @@ impl Config { pub fn git_config(&self) -> GitConfig<'_> { GitConfig { - git_repository: &self.stage0_metadata.config.git_repository, nightly_branch: &self.stage0_metadata.config.nightly_branch, git_merge_commit_email: &self.stage0_metadata.config.git_merge_commit_email, } diff --git a/src/bootstrap/src/utils/tests/git.rs b/src/bootstrap/src/utils/tests/git.rs index 99e0793af4666..bd40f398c7b10 100644 --- a/src/bootstrap/src/utils/tests/git.rs +++ b/src/bootstrap/src/utils/tests/git.rs @@ -135,7 +135,6 @@ impl GitCtx { fn git_config(&self) -> GitConfig<'_> { GitConfig { - git_repository: &self.git_repo, nightly_branch: &self.nightly_branch, git_merge_commit_email: &self.merge_bot_email, } diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs index 8d53a83ea3170..438cd14389c1c 100644 --- a/src/build_helper/src/git.rs +++ b/src/build_helper/src/git.rs @@ -5,7 +5,6 @@ use crate::ci::CiEnv; #[derive(Debug)] pub struct GitConfig<'a> { - pub git_repository: &'a str, pub nightly_branch: &'a str, pub git_merge_commit_email: &'a str, } diff --git a/src/build_helper/src/stage0_parser.rs b/src/build_helper/src/stage0_parser.rs index 2a0c12a1c91c7..2723f4aa7b914 100644 --- a/src/build_helper/src/stage0_parser.rs +++ b/src/build_helper/src/stage0_parser.rs @@ -20,7 +20,6 @@ pub struct Stage0Config { pub artifacts_server: String, pub artifacts_with_llvm_assertions_server: String, pub git_merge_commit_email: String, - pub git_repository: String, pub nightly_branch: String, } @@ -49,7 +48,6 @@ pub fn parse_stage0_file() -> Stage0 { stage0.config.artifacts_with_llvm_assertions_server = value.to_owned() } "git_merge_commit_email" => stage0.config.git_merge_commit_email = value.to_owned(), - "git_repository" => stage0.config.git_repository = value.to_owned(), "nightly_branch" => stage0.config.nightly_branch = value.to_owned(), "compiler_date" => stage0.compiler.date = value.to_owned(), diff --git a/src/stage0 b/src/stage0 index 6e86501a72ab4..06080e3a8c161 100644 --- a/src/stage0 +++ b/src/stage0 @@ -2,7 +2,6 @@ dist_server=https://static.rust-lang.org artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt git_merge_commit_email=bors@rust-lang.org -git_repository=rust-lang/rust nightly_branch=master # The configuration above this comment is editable, and can be changed diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs index d679084ae44bc..680437cce4faa 100644 --- a/src/tools/bump-stage0/src/main.rs +++ b/src/tools/bump-stage0/src/main.rs @@ -61,7 +61,6 @@ impl Tool { artifacts_server, artifacts_with_llvm_assertions_server, git_merge_commit_email, - git_repository, nightly_branch, } = &self.config; @@ -72,7 +71,6 @@ impl Tool { artifacts_with_llvm_assertions_server )); file_content.push_str(&format!("git_merge_commit_email={}\n", git_merge_commit_email)); - file_content.push_str(&format!("git_repository={}\n", git_repository)); file_content.push_str(&format!("nightly_branch={}\n", nightly_branch)); file_content.push_str("\n"); diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed index c82276b358e1d..e696896538e54 100644 --- a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed +++ b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed @@ -1,7 +1,13 @@ //@aux-build:proc_macro_attr.rs #![warn(clippy::blocks_in_conditions)] -#![allow(unused, clippy::needless_if, clippy::missing_transmute_annotations)] +#![allow( + unused, + unnecessary_transmutes, + clippy::let_and_return, + clippy::needless_if, + clippy::missing_transmute_annotations +)] #![warn(clippy::nonminimal_bool)] macro_rules! blocky { diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_conditions.rs index 6a4a7c6210686..8c8f3249b8a74 100644 --- a/src/tools/clippy/tests/ui/blocks_in_conditions.rs +++ b/src/tools/clippy/tests/ui/blocks_in_conditions.rs @@ -1,7 +1,13 @@ //@aux-build:proc_macro_attr.rs #![warn(clippy::blocks_in_conditions)] -#![allow(unused, clippy::needless_if, clippy::missing_transmute_annotations)] +#![allow( + unused, + unnecessary_transmutes, + clippy::let_and_return, + clippy::needless_if, + clippy::missing_transmute_annotations +)] #![warn(clippy::nonminimal_bool)] macro_rules! blocky { diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr index e57eca5dceef5..41ff59c683e84 100644 --- a/src/tools/clippy/tests/ui/blocks_in_conditions.stderr +++ b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr @@ -1,5 +1,5 @@ error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let` - --> tests/ui/blocks_in_conditions.rs:25:5 + --> tests/ui/blocks_in_conditions.rs:31:5 | LL | / if { LL | | @@ -20,13 +20,13 @@ LL ~ }; if res { | error: omit braces around single expression condition - --> tests/ui/blocks_in_conditions.rs:37:8 + --> tests/ui/blocks_in_conditions.rs:43:8 | LL | if { true } { 6 } else { 10 } | ^^^^^^^^ help: try: `true` error: this boolean expression can be simplified - --> tests/ui/blocks_in_conditions.rs:43:8 + --> tests/ui/blocks_in_conditions.rs:49:8 | LL | if true && x == 3 { 6 } else { 10 } | ^^^^^^^^^^^^^^ help: try: `x == 3` diff --git a/src/tools/clippy/tests/ui/crashes/ice-1782.rs b/src/tools/clippy/tests/ui/crashes/ice-1782.rs index 4a1886c08af6a..776b0a93bf7c7 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-1782.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-1782.rs @@ -1,6 +1,6 @@ //@ check-pass -#![allow(dead_code, unused_variables, invalid_null_arguments)] +#![allow(dead_code, unused_variables, invalid_null_arguments, unnecessary_transmutes)] #![allow(clippy::unnecessary_cast, clippy::missing_transmute_annotations)] /// Should not trigger an ICE in `SpanlessEq` / `consts::constant` diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs index 8c8674ac356de..2b8b6c539ad3c 100644 --- a/src/tools/clippy/tests/ui/transmute.rs +++ b/src/tools/clippy/tests/ui/transmute.rs @@ -3,6 +3,7 @@ #![allow( dead_code, clippy::borrow_as_ptr, + unnecessary_transmutes, clippy::needless_lifetimes, clippy::missing_transmute_annotations )] diff --git a/src/tools/clippy/tests/ui/transmute.stderr b/src/tools/clippy/tests/ui/transmute.stderr index 4219e09d2aba9..1bb70151965cd 100644 --- a/src/tools/clippy/tests/ui/transmute.stderr +++ b/src/tools/clippy/tests/ui/transmute.stderr @@ -1,5 +1,5 @@ error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:32:27 + --> tests/ui/transmute.rs:33:27 | LL | let _: *const T = core::mem::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T` @@ -8,61 +8,61 @@ LL | let _: *const T = core::mem::transmute(t); = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:35:25 + --> tests/ui/transmute.rs:36:25 | LL | let _: *mut T = core::mem::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T` error: transmute from a reference to a pointer - --> tests/ui/transmute.rs:38:27 + --> tests/ui/transmute.rs:39:27 | LL | let _: *const U = core::mem::transmute(t); | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U` error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:46:27 + --> tests/ui/transmute.rs:47:27 | LL | let _: Vec = core::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:49:27 + --> tests/ui/transmute.rs:50:27 | LL | let _: Vec = core::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:52:27 + --> tests/ui/transmute.rs:53:27 | LL | let _: Vec = std::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:55:27 + --> tests/ui/transmute.rs:56:27 | LL | let _: Vec = std::mem::transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`std::vec::Vec`) to itself - --> tests/ui/transmute.rs:58:27 + --> tests/ui/transmute.rs:59:27 | LL | let _: Vec = my_transmute(my_vec()); | ^^^^^^^^^^^^^^^^^^^^^^ error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:61:31 + --> tests/ui/transmute.rs:62:31 | LL | let _: *const usize = std::mem::transmute(5_isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize` error: transmute from an integer to a pointer - --> tests/ui/transmute.rs:66:31 + --> tests/ui/transmute.rs:67:31 | LL | let _: *const usize = std::mem::transmute(1 + 1usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize` error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:98:24 + --> tests/ui/transmute.rs:99:24 | LL | let _: Usize = core::mem::transmute(int_const_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,25 +71,25 @@ LL | let _: Usize = core::mem::transmute(int_const_ptr); = help: to override `-D warnings` add `#[allow(clippy::crosspointer_transmute)]` error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`) - --> tests/ui/transmute.rs:101:24 + --> tests/ui/transmute.rs:102:24 | LL | let _: Usize = core::mem::transmute(int_mut_ptr); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`) - --> tests/ui/transmute.rs:104:31 + --> tests/ui/transmute.rs:105:31 | LL | let _: *const Usize = core::mem::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`) - --> tests/ui/transmute.rs:107:29 + --> tests/ui/transmute.rs:108:29 | LL | let _: *mut Usize = core::mem::transmute(my_int()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: transmute from a `u8` to a `bool` - --> tests/ui/transmute.rs:114:28 + --> tests/ui/transmute.rs:115:28 | LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0` @@ -98,7 +98,7 @@ LL | let _: bool = unsafe { std::mem::transmute(0_u8) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]` error: transmute from a `u16` to a `f16` - --> tests/ui/transmute.rs:121:31 + --> tests/ui/transmute.rs:122:31 | LL | let _: f16 = unsafe { std::mem::transmute(0_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` @@ -107,97 +107,97 @@ LL | let _: f16 = unsafe { std::mem::transmute(0_u16) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]` error: transmute from a `i16` to a `f16` - --> tests/ui/transmute.rs:124:31 + --> tests/ui/transmute.rs:125:31 | LL | let _: f16 = unsafe { std::mem::transmute(0_i16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_i16 as u16)` error: transmute from a `u32` to a `f32` - --> tests/ui/transmute.rs:127:31 + --> tests/ui/transmute.rs:128:31 | LL | let _: f32 = unsafe { std::mem::transmute(0_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` error: transmute from a `i32` to a `f32` - --> tests/ui/transmute.rs:130:31 + --> tests/ui/transmute.rs:131:31 | LL | let _: f32 = unsafe { std::mem::transmute(0_i32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)` error: transmute from a `u64` to a `f64` - --> tests/ui/transmute.rs:133:31 + --> tests/ui/transmute.rs:134:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_u64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)` error: transmute from a `i64` to a `f64` - --> tests/ui/transmute.rs:136:31 + --> tests/ui/transmute.rs:137:31 | LL | let _: f64 = unsafe { std::mem::transmute(0_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` error: transmute from a `u128` to a `f128` - --> tests/ui/transmute.rs:139:32 + --> tests/ui/transmute.rs:140:32 | LL | let _: f128 = unsafe { std::mem::transmute(0_u128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_u128)` error: transmute from a `i128` to a `f128` - --> tests/ui/transmute.rs:142:32 + --> tests/ui/transmute.rs:143:32 | LL | let _: f128 = unsafe { std::mem::transmute(0_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` error: transmute from a `u16` to a `f16` - --> tests/ui/transmute.rs:147:39 + --> tests/ui/transmute.rs:148:39 | LL | const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` error: transmute from a `u32` to a `f32` - --> tests/ui/transmute.rs:150:39 + --> tests/ui/transmute.rs:151:39 | LL | const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` error: transmute from a `i64` to a `f64` - --> tests/ui/transmute.rs:153:39 + --> tests/ui/transmute.rs:154:39 | LL | const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` error: transmute from a `i128` to a `f128` - --> tests/ui/transmute.rs:156:41 + --> tests/ui/transmute.rs:157:41 | LL | const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` error: transmute from a `i16` to a `f16` - --> tests/ui/transmute.rs:160:22 + --> tests/ui/transmute.rs:161:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)` error: transmute from a `i32` to a `f32` - --> tests/ui/transmute.rs:165:22 + --> tests/ui/transmute.rs:166:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)` error: transmute from a `u64` to a `f64` - --> tests/ui/transmute.rs:170:22 + --> tests/ui/transmute.rs:171:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)` error: transmute from a `u128` to a `f128` - --> tests/ui/transmute.rs:175:22 + --> tests/ui/transmute.rs:176:22 | LL | unsafe { std::mem::transmute(v) } | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)` error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:184:30 + --> tests/ui/transmute.rs:185:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` @@ -206,121 +206,121 @@ LL | let _: [u8; 1] = std::mem::transmute(0u8); = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:187:30 + --> tests/ui/transmute.rs:188:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:190:31 + --> tests/ui/transmute.rs:191:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:193:30 + --> tests/ui/transmute.rs:194:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:196:30 + --> tests/ui/transmute.rs:197:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:199:31 + --> tests/ui/transmute.rs:200:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` error: transmute from a `f16` to a `[u8; 2]` - --> tests/ui/transmute.rs:202:30 + --> tests/ui/transmute.rs:203:30 | LL | let _: [u8; 2] = std::mem::transmute(0.0f16); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` error: transmute from a `f32` to a `[u8; 4]` - --> tests/ui/transmute.rs:205:30 + --> tests/ui/transmute.rs:206:30 | LL | let _: [u8; 4] = std::mem::transmute(0.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` error: transmute from a `f64` to a `[u8; 8]` - --> tests/ui/transmute.rs:208:30 + --> tests/ui/transmute.rs:209:30 | LL | let _: [u8; 8] = std::mem::transmute(0.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` error: transmute from a `f128` to a `[u8; 16]` - --> tests/ui/transmute.rs:211:31 + --> tests/ui/transmute.rs:212:31 | LL | let _: [u8; 16] = std::mem::transmute(0.0f128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` error: transmute from a `u8` to a `[u8; 1]` - --> tests/ui/transmute.rs:217:30 + --> tests/ui/transmute.rs:218:30 | LL | let _: [u8; 1] = std::mem::transmute(0u8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` error: transmute from a `u32` to a `[u8; 4]` - --> tests/ui/transmute.rs:220:30 + --> tests/ui/transmute.rs:221:30 | LL | let _: [u8; 4] = std::mem::transmute(0u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` error: transmute from a `u128` to a `[u8; 16]` - --> tests/ui/transmute.rs:223:31 + --> tests/ui/transmute.rs:224:31 | LL | let _: [u8; 16] = std::mem::transmute(0u128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` error: transmute from a `i8` to a `[u8; 1]` - --> tests/ui/transmute.rs:226:30 + --> tests/ui/transmute.rs:227:30 | LL | let _: [u8; 1] = std::mem::transmute(0i8); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` error: transmute from a `i32` to a `[u8; 4]` - --> tests/ui/transmute.rs:229:30 + --> tests/ui/transmute.rs:230:30 | LL | let _: [u8; 4] = std::mem::transmute(0i32); | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` error: transmute from a `i128` to a `[u8; 16]` - --> tests/ui/transmute.rs:232:31 + --> tests/ui/transmute.rs:233:31 | LL | let _: [u8; 16] = std::mem::transmute(0i128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` error: transmute from a `f16` to a `[u8; 2]` - --> tests/ui/transmute.rs:235:30 + --> tests/ui/transmute.rs:236:30 | LL | let _: [u8; 2] = std::mem::transmute(0.0f16); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` error: transmute from a `f32` to a `[u8; 4]` - --> tests/ui/transmute.rs:238:30 + --> tests/ui/transmute.rs:239:30 | LL | let _: [u8; 4] = std::mem::transmute(0.0f32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` error: transmute from a `f64` to a `[u8; 8]` - --> tests/ui/transmute.rs:241:30 + --> tests/ui/transmute.rs:242:30 | LL | let _: [u8; 8] = std::mem::transmute(0.0f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` error: transmute from a `f128` to a `[u8; 16]` - --> tests/ui/transmute.rs:244:31 + --> tests/ui/transmute.rs:245:31 | LL | let _: [u8; 16] = std::mem::transmute(0.0f128); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:253:28 + --> tests/ui/transmute.rs:254:28 | LL | let _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()` @@ -329,13 +329,13 @@ LL | let _: &str = unsafe { std::mem::transmute(B) }; = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]` error: transmute from a `&mut [u8]` to a `&mut str` - --> tests/ui/transmute.rs:256:32 + --> tests/ui/transmute.rs:257:32 | LL | let _: &mut str = unsafe { std::mem::transmute(mb) }; | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()` error: transmute from a `&[u8]` to a `&str` - --> tests/ui/transmute.rs:259:30 + --> tests/ui/transmute.rs:260:30 | LL | const _: &str = unsafe { std::mem::transmute(B) }; | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)` diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed index 1f97b997eaa0e..844445907d7c2 100644 --- a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed +++ b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed @@ -1,5 +1,5 @@ #![warn(clippy::transmute_float_to_int)] -#![allow(clippy::missing_transmute_annotations)] +#![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)] #![feature(f128)] #![feature(f16)] diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.rs b/src/tools/clippy/tests/ui/transmute_float_to_int.rs index 788a7e1026c67..a1f3b15bbfee4 100644 --- a/src/tools/clippy/tests/ui/transmute_float_to_int.rs +++ b/src/tools/clippy/tests/ui/transmute_float_to_int.rs @@ -1,5 +1,5 @@ #![warn(clippy::transmute_float_to_int)] -#![allow(clippy::missing_transmute_annotations)] +#![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)] #![feature(f128)] #![feature(f16)] diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.fixed b/src/tools/clippy/tests/ui/transmute_int_to_char.fixed index b5425a2e9e854..28644aa9ebbb7 100644 --- a/src/tools/clippy/tests/ui/transmute_int_to_char.fixed +++ b/src/tools/clippy/tests/ui/transmute_int_to_char.fixed @@ -1,5 +1,5 @@ #![warn(clippy::transmute_int_to_char)] -#![allow(clippy::missing_transmute_annotations)] +#![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)] fn int_to_char() { let _: char = unsafe { std::char::from_u32(0_u32).unwrap() }; diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.rs b/src/tools/clippy/tests/ui/transmute_int_to_char.rs index b24bb177c9fc0..8c83ecc8914b6 100644 --- a/src/tools/clippy/tests/ui/transmute_int_to_char.rs +++ b/src/tools/clippy/tests/ui/transmute_int_to_char.rs @@ -1,5 +1,5 @@ #![warn(clippy::transmute_int_to_char)] -#![allow(clippy::missing_transmute_annotations)] +#![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)] fn int_to_char() { let _: char = unsafe { std::mem::transmute(0_u32) }; diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed index e525751e306ea..e6e09a2be4bf5 100644 --- a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed +++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed @@ -1,7 +1,7 @@ #![no_std] #![feature(lang_items)] #![warn(clippy::transmute_int_to_char)] -#![allow(clippy::missing_transmute_annotations)] +#![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)] use core::panic::PanicInfo; diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs index 7cb508ceaf3bc..0f2106df00e6c 100644 --- a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs +++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs @@ -1,7 +1,7 @@ #![no_std] #![feature(lang_items)] #![warn(clippy::transmute_int_to_char)] -#![allow(clippy::missing_transmute_annotations)] +#![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)] use core::panic::PanicInfo; diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index de93e2b99eede..e0132056d6c4a 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -399,7 +399,6 @@ pub struct Config { pub nocapture: bool, // Needed both to construct build_helper::git::GitConfig - pub git_repository: String, pub nightly_branch: String, pub git_merge_commit_email: String, @@ -514,7 +513,6 @@ impl Config { pub fn git_config(&self) -> GitConfig<'_> { GitConfig { - git_repository: &self.git_repository, nightly_branch: &self.nightly_branch, git_merge_commit_email: &self.git_merge_commit_email, } diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 2525e0adc8385..e7e5ff0ab0093 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -175,7 +175,6 @@ impl ConfigBuilder { self.host.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), "--target", self.target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), - "--git-repository=", "--nightly-branch=", "--git-merge-commit-email=", "--minicore-path=", diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 7948a273c1e86..0a3888a7d50ae 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -188,7 +188,6 @@ pub fn parse_config(args: Vec) -> Config { "run tests which rely on commit version being compiled into the binaries", ) .optopt("", "edition", "default Rust edition", "EDITION") - .reqopt("", "git-repository", "name of the git repository", "ORG/REPO") .reqopt("", "nightly-branch", "name of the git branch for nightly", "BRANCH") .reqopt( "", @@ -440,7 +439,6 @@ pub fn parse_config(args: Vec) -> Config { nocapture: matches.opt_present("no-capture"), - git_repository: matches.opt_str("git-repository").unwrap(), nightly_branch: matches.opt_str("nightly-branch").unwrap(), git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(), diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index a3525dcc77ae6..7d60a7e5c4895 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -391,32 +391,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_scalar(res, dest)?; } - #[rustfmt::skip] - | "fadd_algebraic" - | "fsub_algebraic" - | "fmul_algebraic" - | "fdiv_algebraic" - | "frem_algebraic" - => { - let [a, b] = check_intrinsic_arg_count(args)?; - let a = this.read_immediate(a)?; - let b = this.read_immediate(b)?; - let op = match intrinsic_name { - "fadd_algebraic" => mir::BinOp::Add, - "fsub_algebraic" => mir::BinOp::Sub, - "fmul_algebraic" => mir::BinOp::Mul, - "fdiv_algebraic" => mir::BinOp::Div, - "frem_algebraic" => mir::BinOp::Rem, - _ => bug!(), - }; - let res = this.binary_op(op, &a, &b)?; - // `binary_op` already called `generate_nan` if needed. - // Apply a relative error of 4ULP to simulate non-deterministic precision loss - // due to optimizations. - let res = apply_random_float_error_to_imm(this, res, 2 /* log2(4) */)?; - this.write_immediate(*res, dest)?; - } - #[rustfmt::skip] | "fadd_fast" | "fsub_fast" diff --git a/src/tools/miri/tests/fail/validity/invalid_bool.rs b/src/tools/miri/tests/fail/validity/invalid_bool.rs index 4f11bb2629f5f..bd448af834df7 100644 --- a/src/tools/miri/tests/fail/validity/invalid_bool.rs +++ b/src/tools/miri/tests/fail/validity/invalid_bool.rs @@ -1,3 +1,4 @@ +#![allow(unnecessary_transmutes)] fn main() { let _b = unsafe { std::mem::transmute::(2) }; //~ ERROR: expected a boolean } diff --git a/src/tools/miri/tests/fail/validity/invalid_bool_op.rs b/src/tools/miri/tests/fail/validity/invalid_bool_op.rs index fe9bb3bed7f01..0cbe2d76dc6ca 100644 --- a/src/tools/miri/tests/fail/validity/invalid_bool_op.rs +++ b/src/tools/miri/tests/fail/validity/invalid_bool_op.rs @@ -2,6 +2,7 @@ // Make sure we find these even with many checks disabled. //@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +#![allow(unnecessary_transmutes)] fn main() { let b = unsafe { std::mem::transmute::(2) }; let _x = b == std::hint::black_box(true); //~ ERROR: interpreting an invalid 8-bit value as a bool diff --git a/src/tools/miri/tests/fail/validity/invalid_char.rs b/src/tools/miri/tests/fail/validity/invalid_char.rs index 568892e591096..d57c933dac17e 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char.rs +++ b/src/tools/miri/tests/fail/validity/invalid_char.rs @@ -1,3 +1,4 @@ +#![allow(unnecessary_transmutes)] fn main() { assert!(std::char::from_u32(-1_i32 as u32).is_none()); let _val = match unsafe { std::mem::transmute::(-1) } { diff --git a/src/tools/miri/tests/fail/validity/invalid_char_op.rs b/src/tools/miri/tests/fail/validity/invalid_char_op.rs index 699248229445f..e3a5f837e1891 100644 --- a/src/tools/miri/tests/fail/validity/invalid_char_op.rs +++ b/src/tools/miri/tests/fail/validity/invalid_char_op.rs @@ -2,6 +2,7 @@ // Make sure we find these even with many checks disabled. //@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +#![allow(unnecessary_transmutes)] fn main() { let c = 0xFFFFFFu32; assert!(std::char::from_u32(c).is_none()); diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index cd60b6bd563d7..575d70579a4e3 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -6,6 +6,7 @@ #![feature(f16)] #![allow(arithmetic_overflow)] #![allow(internal_features)] +#![allow(unnecessary_transmutes)] use std::any::type_name; use std::cmp::min; diff --git a/src/tools/miri/tests/pass/issues/issue-miri-184.rs b/src/tools/miri/tests/pass/issues/issue-miri-184.rs index 39c841403ef0c..964d850298fbf 100644 --- a/src/tools/miri/tests/pass/issues/issue-miri-184.rs +++ b/src/tools/miri/tests/pass/issues/issue-miri-184.rs @@ -1,3 +1,4 @@ +#![allow(unnecessary_transmutes)] pub fn main() { let bytes: [u8; 8] = unsafe { ::std::mem::transmute(0u64) }; let _val: &[u8] = &bytes; diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs index a629e2acfe998..882b5e3f79524 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-gfni.rs @@ -368,7 +368,7 @@ unsafe fn load_m256i_word(data: &[T], word_index: usize) -> __m256i { #[target_feature(enable = "avx512f")] unsafe fn load_m512i_word(data: &[T], word_index: usize) -> __m512i { let byte_offset = word_index * 64 / size_of::(); - let pointer = data.as_ptr().add(byte_offset) as *const i32; + let pointer = data.as_ptr().add(byte_offset) as *const __m512i; _mm512_loadu_si512(black_box(pointer)) } diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs index 6f7ab3b3c9fb9..be3f961e10ffa 100644 --- a/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs +++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-x86-sse.rs @@ -1,5 +1,6 @@ // We're testing x86 target specific features //@only-target: x86_64 i686 +#![allow(unnecessary_transmutes)] #[cfg(target_arch = "x86")] use std::arch::x86::*; diff --git a/src/tools/suggest-tests/src/main.rs b/src/tools/suggest-tests/src/main.rs index ee212af36260a..d84f8e9fa1bab 100644 --- a/src/tools/suggest-tests/src/main.rs +++ b/src/tools/suggest-tests/src/main.rs @@ -6,7 +6,6 @@ use suggest_tests::get_suggestions; fn main() -> ExitCode { let modified_files = get_git_modified_files( &GitConfig { - git_repository: &env("SUGGEST_TESTS_GIT_REPOSITORY"), nightly_branch: &env("SUGGEST_TESTS_NIGHTLY_BRANCH"), git_merge_commit_email: &env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL"), }, diff --git a/tests/codegen/autodiff/identical_fnc.rs b/tests/codegen/autodiff/identical_fnc.rs new file mode 100644 index 0000000000000..1c3277f52b488 --- /dev/null +++ b/tests/codegen/autodiff/identical_fnc.rs @@ -0,0 +1,45 @@ +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme +// +// Each autodiff invocation creates a new placeholder function, which we will replace on llvm-ir +// level. If a user tries to differentiate two identical functions within the same compilation unit, +// then LLVM might merge them in release mode before AD. In that case we can't rewrite one of the +// merged placeholder function anymore, and compilation would fail. We prevent this by disabling +// LLVM's merge_function pass before AD. Here we implicetely test that our solution keeps working. +// We also explicetly test that we keep running merge_function after AD, by checking for two +// identical function calls in the LLVM-IR, while having two different calls in the Rust code. +#![feature(autodiff)] + +use std::autodiff::autodiff; + +#[autodiff(d_square, Reverse, Duplicated, Active)] +fn square(x: &f64) -> f64 { + x * x +} + +#[autodiff(d_square2, Reverse, Duplicated, Active)] +fn square2(x: &f64) -> f64 { + x * x +} + +// CHECK:; identical_fnc::main +// CHECK-NEXT:; Function Attrs: +// CHECK-NEXT:define internal void @_ZN13identical_fnc4main17hf4dbc69c8d2f9130E() +// CHECK-NEXT:start: +// CHECK-NOT:br +// CHECK-NOT:ret +// CHECK:; call identical_fnc::d_square +// CHECK-NEXT: call fastcc void @_ZN13identical_fnc8d_square17h4c364207a2f8e06dE(double %x.val, ptr noalias noundef nonnull align 8 dereferenceable(8) %dx1) +// CHECK-NEXT:; call identical_fnc::d_square +// CHECK-NEXT: call fastcc void @_ZN13identical_fnc8d_square17h4c364207a2f8e06dE(double %x.val, ptr noalias noundef nonnull align 8 dereferenceable(8) %dx2) + +fn main() { + let x = std::hint::black_box(3.0); + let mut dx1 = std::hint::black_box(1.0); + let mut dx2 = std::hint::black_box(1.0); + let _ = d_square(&x, &mut dx1, 1.0); + let _ = d_square2(&x, &mut dx2, 1.0); + assert_eq!(dx1, 6.0); + assert_eq!(dx2, 6.0); +} diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs index 9187de5636202..20f1a9aae70ae 100644 --- a/tests/ui/consts/const-eval/raw-bytes.rs +++ b/tests/ui/consts/const-eval/raw-bytes.rs @@ -2,7 +2,7 @@ //@ ignore-endian-big // ignore-tidy-linelength //@ normalize-stderr: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼" -> "╾ALLOC_ID$1╼" -#![allow(invalid_value)] +#![allow(invalid_value, unnecessary_transmutes)] #![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)] use std::mem; diff --git a/tests/ui/consts/const-eval/transmute-const-promotion.rs b/tests/ui/consts/const-eval/transmute-const-promotion.rs index 1f0240d4b5ac7..840334f43c09c 100644 --- a/tests/ui/consts/const-eval/transmute-const-promotion.rs +++ b/tests/ui/consts/const-eval/transmute-const-promotion.rs @@ -1,3 +1,4 @@ +#![allow(unnecessary_transmutes)] use std::mem; fn main() { diff --git a/tests/ui/consts/const-eval/transmute-const-promotion.stderr b/tests/ui/consts/const-eval/transmute-const-promotion.stderr index 3603db03bb204..eb2fed091c34a 100644 --- a/tests/ui/consts/const-eval/transmute-const-promotion.stderr +++ b/tests/ui/consts/const-eval/transmute-const-promotion.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/transmute-const-promotion.rs:4:37 + --> $DIR/transmute-const-promotion.rs:5:37 | LL | let x: &'static u32 = unsafe { &mem::transmute(3.0f32) }; | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use diff --git a/tests/ui/consts/const-eval/transmute-const.rs b/tests/ui/consts/const-eval/transmute-const.rs index 1cfad00ca76df..fb6cb77675fa6 100644 --- a/tests/ui/consts/const-eval/transmute-const.rs +++ b/tests/ui/consts/const-eval/transmute-const.rs @@ -1,3 +1,4 @@ +#![allow(unnecessary_transmutes)] use std::mem; static FOO: bool = unsafe { mem::transmute(3u8) }; diff --git a/tests/ui/consts/const-eval/transmute-const.stderr b/tests/ui/consts/const-eval/transmute-const.stderr index d72289487d7bf..35a5cabaa6710 100644 --- a/tests/ui/consts/const-eval/transmute-const.stderr +++ b/tests/ui/consts/const-eval/transmute-const.stderr @@ -1,5 +1,5 @@ error[E0080]: it is undefined behavior to use this value - --> $DIR/transmute-const.rs:3:1 + --> $DIR/transmute-const.rs:4:1 | LL | static FOO: bool = unsafe { mem::transmute(3u8) }; | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs index 5be444e667a1f..a5255ef95aa5b 100644 --- a/tests/ui/consts/const-eval/ub-enum.rs +++ b/tests/ui/consts/const-eval/ub-enum.rs @@ -3,7 +3,7 @@ //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr: "0x0+" -> "0x0" #![feature(never_type)] -#![allow(invalid_value)] +#![allow(invalid_value, unnecessary_transmutes)] use std::mem; diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs index a071a44272b4d..4e2defc1a0907 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.rs +++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs @@ -1,5 +1,5 @@ // ignore-tidy-linelength -#![allow(unused)] +#![allow(unused, unnecessary_transmutes)] #![feature(ptr_metadata)] use std::{ptr, mem}; diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs index 481f2ff88df67..c3bd8301d5ce4 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -2,6 +2,7 @@ //@ [no_flag] check-pass //@ [with_flag] compile-flags: -Zextra-const-ub-checks #![feature(never_type)] +#![allow(unnecessary_transmutes)] use std::mem::transmute; use std::ptr::addr_of; diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 0100aafb6b7c6..ea3b0e70b8285 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:29:20 + --> $DIR/detect-extra-ub.rs:30:20 | LL | let _x: bool = transmute(3u8); | ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:35:21 + --> $DIR/detect-extra-ub.rs:36:21 | LL | let _x: usize = transmute(&3u8); | ^^^^^^^^^^^^^^^ constructing invalid value: encountered a pointer, but expected an integer @@ -14,7 +14,7 @@ LL | let _x: usize = transmute(&3u8); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:41:28 + --> $DIR/detect-extra-ub.rs:42:28 | LL | let _x: PtrSizedEnum = transmute(&3u8); | ^^^^^^^^^^^^^^^ constructing invalid value at .: encountered a pointer, but expected an integer @@ -23,7 +23,7 @@ LL | let _x: PtrSizedEnum = transmute(&3u8); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:48:30 + --> $DIR/detect-extra-ub.rs:49:30 | LL | let _x: (usize, usize) = transmute(x); | ^^^^^^^^^^^^ constructing invalid value at .0: encountered a pointer, but expected an integer @@ -32,19 +32,19 @@ LL | let _x: (usize, usize) = transmute(x); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:54:20 + --> $DIR/detect-extra-ub.rs:55:20 | LL | let _x: &u32 = transmute(&[0u8; 4]); | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1) error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:62:13 + --> $DIR/detect-extra-ub.rs:63:13 | LL | let v = *addr_of!(data).cast::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered an uninhabited enum variant error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:82:16 + --> $DIR/detect-extra-ub.rs:83:16 | LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a partial pointer or a mix of pointers @@ -53,7 +53,7 @@ LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: evaluation of constant value failed - --> $DIR/detect-extra-ub.rs:97:16 + --> $DIR/detect-extra-ub.rs:98:16 | LL | let _val = &*slice; | ^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object diff --git a/tests/ui/consts/issue-69532.rs b/tests/ui/consts/issue-69532.rs index 285cfe7213bae..43ab1d6cca743 100644 --- a/tests/ui/consts/issue-69532.rs +++ b/tests/ui/consts/issue-69532.rs @@ -1,8 +1,8 @@ //@ run-pass const fn make_nans() -> (f64, f64, f32, f32) { - let nan1: f64 = unsafe { std::mem::transmute(0x7FF0_0001_0000_0001u64) }; - let nan2: f64 = unsafe { std::mem::transmute(0x7FF0_0000_0000_0001u64) }; + let nan1 = f64::from_bits(0x7FF0_0001_0000_0001); + let nan2 = f64::from_bits(0x7FF0_0000_0000_0001); let nan1_32 = nan1 as f32; let nan2_32 = nan2 as f32; diff --git a/tests/ui/issues/issue-25746-bool-transmute.rs b/tests/ui/issues/issue-25746-bool-transmute.rs index f8cdc980daa48..046dcf83f62d6 100644 --- a/tests/ui/issues/issue-25746-bool-transmute.rs +++ b/tests/ui/issues/issue-25746-bool-transmute.rs @@ -1,4 +1,5 @@ //@ run-pass +#![allow(unnecessary_transmutes)] use std::mem::transmute; fn main() { diff --git a/tests/ui/lint/invalid_null_args.rs b/tests/ui/lint/invalid_null_args.rs index 7948f0d86d09f..f40f06a0d3624 100644 --- a/tests/ui/lint/invalid_null_args.rs +++ b/tests/ui/lint/invalid_null_args.rs @@ -1,19 +1,19 @@ // check-fail // run-rustfix +#![allow(unnecessary_transmutes)] -use std::ptr; -use std::mem; +use std::{mem, ptr}; unsafe fn null_ptr() { ptr::write( - //~^ ERROR calling this function with a null pointer is undefined behavior + //~^ ERROR calling this function with a null pointer is undefined behavior ptr::null_mut() as *mut u32, mem::transmute::<[u8; 4], _>([0, 0, 0, 255]), ); let null_ptr = ptr::null_mut(); ptr::write( - //~^ ERROR calling this function with a null pointer is undefined behavior + //~^ ERROR calling this function with a null pointer is undefined behavior null_ptr as *mut u32, mem::transmute::<[u8; 4], _>([0, 0, 0, 255]), ); @@ -38,10 +38,10 @@ unsafe fn null_ptr() { ptr::copy_nonoverlapping::(ptr::null(), ptr::NonNull::dangling().as_ptr(), 0); //~^ ERROR calling this function with a null pointer is undefined behavior ptr::copy_nonoverlapping::( - //~^ ERROR calling this function with a null pointer is undefined behavior + //~^ ERROR calling this function with a null pointer is undefined behavior ptr::NonNull::dangling().as_ptr(), ptr::null_mut(), - 0 + 0, ); #[derive(Copy, Clone)] diff --git a/tests/ui/lint/invalid_null_args.stderr b/tests/ui/lint/invalid_null_args.stderr index f95bc2afa829e..11c6270cfb78e 100644 --- a/tests/ui/lint/invalid_null_args.stderr +++ b/tests/ui/lint/invalid_null_args.stderr @@ -117,7 +117,7 @@ LL | | LL | | ptr::NonNull::dangling().as_ptr(), LL | | ptr::null_mut(), | | --------------- null pointer originates from here -LL | | 0 +LL | | 0, LL | | ); | |_____^ | diff --git a/tests/ui/lint/lint-ctypes-enum.rs b/tests/ui/lint/lint-ctypes-enum.rs index 0d19d5b534713..b2ef27b833bdb 100644 --- a/tests/ui/lint/lint-ctypes-enum.rs +++ b/tests/ui/lint/lint-ctypes-enum.rs @@ -2,6 +2,8 @@ #![deny(improper_ctypes)] #![feature(ptr_internals)] #![feature(transparent_unions)] +#![feature(repr128)] +#![allow(incomplete_features)] use std::num; @@ -40,6 +42,20 @@ enum Isize { C, } +#[repr(u128)] +enum U128 { + A, + B, + C, +} + +#[repr(i128)] +enum I128 { + A, + B, + C, +} + #[repr(transparent)] struct TransparentStruct(T, std::marker::PhantomData); @@ -71,6 +87,8 @@ extern "C" { fn repr_c(x: ReprC); fn repr_u8(x: U8); fn repr_isize(x: Isize); + fn repr_u128(x: U128); //~ ERROR `extern` block uses type `U128` + fn repr_i128(x: I128); //~ ERROR `extern` block uses type `I128` fn option_ref(x: Option<&'static u8>); fn option_fn(x: Option); fn option_nonnull(x: Option>); diff --git a/tests/ui/lint/lint-ctypes-enum.stderr b/tests/ui/lint/lint-ctypes-enum.stderr index a491bd1960563..d5fc844f75607 100644 --- a/tests/ui/lint/lint-ctypes-enum.stderr +++ b/tests/ui/lint/lint-ctypes-enum.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `U`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:68:14 + --> $DIR/lint-ctypes-enum.rs:84:14 | LL | fn uf(x: U); | ^ not FFI-safe @@ -7,7 +7,7 @@ LL | fn uf(x: U); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:9:1 + --> $DIR/lint-ctypes-enum.rs:11:1 | LL | enum U { | ^^^^^^ @@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ error: `extern` block uses type `B`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:69:14 + --> $DIR/lint-ctypes-enum.rs:85:14 | LL | fn bf(x: B); | ^ not FFI-safe @@ -26,13 +26,13 @@ LL | fn bf(x: B); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:12:1 + --> $DIR/lint-ctypes-enum.rs:14:1 | LL | enum B { | ^^^^^^ error: `extern` block uses type `T`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:70:14 + --> $DIR/lint-ctypes-enum.rs:86:14 | LL | fn tf(x: T); | ^ not FFI-safe @@ -40,13 +40,39 @@ LL | fn tf(x: T); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here - --> $DIR/lint-ctypes-enum.rs:16:1 + --> $DIR/lint-ctypes-enum.rs:18:1 | LL | enum T { | ^^^^^^ +error: `extern` block uses type `U128`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:90:21 + | +LL | fn repr_u128(x: U128); + | ^^^^ not FFI-safe + | + = note: 128-bit integers don't currently have a known stable ABI +note: the type is defined here + --> $DIR/lint-ctypes-enum.rs:46:1 + | +LL | enum U128 { + | ^^^^^^^^^ + +error: `extern` block uses type `I128`, which is not FFI-safe + --> $DIR/lint-ctypes-enum.rs:91:21 + | +LL | fn repr_i128(x: I128); + | ^^^^ not FFI-safe + | + = note: 128-bit integers don't currently have a known stable ABI +note: the type is defined here + --> $DIR/lint-ctypes-enum.rs:53:1 + | +LL | enum I128 { + | ^^^^^^^^^ + error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:82:31 + --> $DIR/lint-ctypes-enum.rs:100:31 | LL | fn option_nonzero_u128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -54,7 +80,7 @@ LL | fn option_nonzero_u128(x: Option>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:89:31 + --> $DIR/lint-ctypes-enum.rs:107:31 | LL | fn option_nonzero_i128(x: Option>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -62,7 +88,7 @@ LL | fn option_nonzero_i128(x: Option>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:94:36 + --> $DIR/lint-ctypes-enum.rs:112:36 | LL | fn option_transparent_union(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -71,7 +97,7 @@ LL | fn option_transparent_union(x: Option = note: enum has no representation hint error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:96:28 + --> $DIR/lint-ctypes-enum.rs:114:28 | LL | fn option_repr_rust(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -80,7 +106,7 @@ LL | fn option_repr_rust(x: Option>>); = note: enum has no representation hint error: `extern` block uses type `Option`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:97:21 + --> $DIR/lint-ctypes-enum.rs:115:21 | LL | fn option_u8(x: Option); | ^^^^^^^^^^ not FFI-safe @@ -89,7 +115,7 @@ LL | fn option_u8(x: Option); = note: enum has no representation hint error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:107:33 + --> $DIR/lint-ctypes-enum.rs:125:33 | LL | fn result_nonzero_u128_t(x: Result, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -97,7 +123,7 @@ LL | fn result_nonzero_u128_t(x: Result, ()>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:114:33 + --> $DIR/lint-ctypes-enum.rs:132:33 | LL | fn result_nonzero_i128_t(x: Result, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -105,7 +131,7 @@ LL | fn result_nonzero_i128_t(x: Result, ()>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:119:38 + --> $DIR/lint-ctypes-enum.rs:137:38 | LL | fn result_transparent_union_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -114,7 +140,7 @@ LL | fn result_transparent_union_t(x: Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:121:30 + --> $DIR/lint-ctypes-enum.rs:139:30 | LL | fn result_repr_rust_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -123,7 +149,7 @@ LL | fn result_repr_rust_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `Result, U>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:125:51 + --> $DIR/lint-ctypes-enum.rs:143:51 | LL | fn result_1zst_exhaustive_single_variant_t(x: Result, U>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -132,7 +158,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, B>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:127:53 + --> $DIR/lint-ctypes-enum.rs:145:53 | LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -141,7 +167,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result = note: enum has no representation hint error: `extern` block uses type `Result, NonExhaustive>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:129:51 + --> $DIR/lint-ctypes-enum.rs:147:51 | LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -150,7 +176,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, Field>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:132:49 + --> $DIR/lint-ctypes-enum.rs:150:49 | LL | fn result_1zst_exhaustive_single_field_t(x: Result, Field>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -159,7 +185,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result, Fi = note: enum has no representation hint error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:134:30 + --> $DIR/lint-ctypes-enum.rs:152:30 | LL | fn result_cascading_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -168,7 +194,7 @@ LL | fn result_cascading_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `u128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:145:33 + --> $DIR/lint-ctypes-enum.rs:163:33 | LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -176,7 +202,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `i128`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:152:33 + --> $DIR/lint-ctypes-enum.rs:170:33 | LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -184,7 +210,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero>); = note: 128-bit integers don't currently have a known stable ABI error: `extern` block uses type `Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:157:38 + --> $DIR/lint-ctypes-enum.rs:175:38 | LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -193,7 +219,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:159:30 + --> $DIR/lint-ctypes-enum.rs:177:30 | LL | fn result_repr_rust_e(x: Result<(), Rust>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -202,7 +228,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust>>); = note: enum has no representation hint error: `extern` block uses type `Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:163:51 + --> $DIR/lint-ctypes-enum.rs:181:51 | LL | fn result_1zst_exhaustive_single_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -211,7 +237,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:165:53 + --> $DIR/lint-ctypes-enum.rs:183:53 | LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -220,7 +246,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:167:51 + --> $DIR/lint-ctypes-enum.rs:185:51 | LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -229,7 +255,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:170:49 + --> $DIR/lint-ctypes-enum.rs:188:49 | LL | fn result_1zst_exhaustive_single_field_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -238,7 +264,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result>>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:172:30 + --> $DIR/lint-ctypes-enum.rs:190:30 | LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -247,7 +273,7 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); = note: enum has no representation hint error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe - --> $DIR/lint-ctypes-enum.rs:174:27 + --> $DIR/lint-ctypes-enum.rs:192:27 | LL | fn result_unit_t_e(x: Result<(), ()>); | ^^^^^^^^^^^^^^ not FFI-safe @@ -255,5 +281,5 @@ LL | fn result_unit_t_e(x: Result<(), ()>); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: aborting due to 27 previous errors +error: aborting due to 29 previous errors diff --git a/tests/ui/transmute/unnecessary-transmutation.fixed b/tests/ui/transmute/unnecessary-transmutation.fixed new file mode 100644 index 0000000000000..1a0df143cc5ff --- /dev/null +++ b/tests/ui/transmute/unnecessary-transmutation.fixed @@ -0,0 +1,85 @@ +//@ run-rustfix +#![deny(unnecessary_transmutes)] +#![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] +use std::mem::transmute; + +pub fn bytes_at_home(x: u32) -> [u8; 4] { + unsafe { u32::to_ne_bytes(x) } + //~^ ERROR +} + +fn main() { + unsafe { + let x: u16 = u16::from_ne_bytes(*b"01"); + //~^ ERROR + let x: [u8; 2] = u16::to_ne_bytes(x); + //~^ ERROR + let x: u32 = u32::from_ne_bytes(*b"0123"); + //~^ ERROR + let x: [u8; 4] = u32::to_ne_bytes(x); + //~^ ERROR + let x: u64 = u64::from_ne_bytes(*b"feriscat"); + //~^ ERROR + let x: [u8; 8] = u64::to_ne_bytes(x); + //~^ ERROR + + let y: i16 = i16::from_ne_bytes(*b"01"); + //~^ ERROR + let y: [u8; 2] = i16::to_ne_bytes(y); + //~^ ERROR + let y: i32 = i32::from_ne_bytes(*b"0123"); + //~^ ERROR + let y: [u8; 4] = i32::to_ne_bytes(y); + //~^ ERROR + let y: i64 = i64::from_ne_bytes(*b"feriscat"); + //~^ ERROR + let y: [u8; 8] = i64::to_ne_bytes(y); + //~^ ERROR + + let z: f32 = f32::from_ne_bytes(*b"0123"); + //~^ ERROR + let z: [u8; 4] = f32::to_ne_bytes(z); + //~^ ERROR + let z: f64 = f64::from_ne_bytes(*b"feriscat"); + //~^ ERROR + let z: [u8; 8] = f64::to_ne_bytes(z); + //~^ ERROR + + let y: u32 = u32::from('🦀'); + //~^ ERROR + let y: char = char::from_u32_unchecked(y); + //~^ ERROR + + let x: u16 = i16::cast_unsigned(8i16); + //~^ ERROR + let x: i16 = u16::cast_signed(x); + //~^ ERROR + let x: u32 = i32::cast_unsigned(4i32); + //~^ ERROR + let x: i32 = u32::cast_signed(x); + //~^ ERROR + let x: u64 = i64::cast_unsigned(7i64); + //~^ ERROR + let x: i64 = u64::cast_signed(x); + //~^ ERROR + + let y: f32 = f32::from_bits(1u32); + //~^ ERROR + let y: u32 = f32::to_bits(y); + //~^ ERROR + let y: f64 = f64::from_bits(3u64); + //~^ ERROR + let y: u64 = f64::to_bits(2.0); + //~^ ERROR + + let z: bool = (1u8 == 1); + //~^ ERROR + let z: u8 = (z) as u8; + //~^ ERROR + + let z: bool = transmute(1i8); + // no error! + let z: i8 = (z) as i8; + //~^ ERROR + } +} diff --git a/tests/ui/transmute/unnecessary-transmutation.rs b/tests/ui/transmute/unnecessary-transmutation.rs new file mode 100644 index 0000000000000..6b979263c56ca --- /dev/null +++ b/tests/ui/transmute/unnecessary-transmutation.rs @@ -0,0 +1,85 @@ +//@ run-rustfix +#![deny(unnecessary_transmutes)] +#![allow(unused_unsafe, unused_imports, unused_variables, unused_parens)] +use std::mem::transmute; + +pub fn bytes_at_home(x: u32) -> [u8; 4] { + unsafe { transmute(x) } + //~^ ERROR +} + +fn main() { + unsafe { + let x: u16 = transmute(*b"01"); + //~^ ERROR + let x: [u8; 2] = transmute(x); + //~^ ERROR + let x: u32 = transmute(*b"0123"); + //~^ ERROR + let x: [u8; 4] = transmute(x); + //~^ ERROR + let x: u64 = transmute(*b"feriscat"); + //~^ ERROR + let x: [u8; 8] = transmute(x); + //~^ ERROR + + let y: i16 = transmute(*b"01"); + //~^ ERROR + let y: [u8; 2] = transmute(y); + //~^ ERROR + let y: i32 = transmute(*b"0123"); + //~^ ERROR + let y: [u8; 4] = transmute(y); + //~^ ERROR + let y: i64 = transmute(*b"feriscat"); + //~^ ERROR + let y: [u8; 8] = transmute(y); + //~^ ERROR + + let z: f32 = transmute(*b"0123"); + //~^ ERROR + let z: [u8; 4] = transmute(z); + //~^ ERROR + let z: f64 = transmute(*b"feriscat"); + //~^ ERROR + let z: [u8; 8] = transmute(z); + //~^ ERROR + + let y: u32 = transmute('🦀'); + //~^ ERROR + let y: char = transmute(y); + //~^ ERROR + + let x: u16 = transmute(8i16); + //~^ ERROR + let x: i16 = transmute(x); + //~^ ERROR + let x: u32 = transmute(4i32); + //~^ ERROR + let x: i32 = transmute(x); + //~^ ERROR + let x: u64 = transmute(7i64); + //~^ ERROR + let x: i64 = transmute(x); + //~^ ERROR + + let y: f32 = transmute(1u32); + //~^ ERROR + let y: u32 = transmute(y); + //~^ ERROR + let y: f64 = transmute(3u64); + //~^ ERROR + let y: u64 = transmute(2.0); + //~^ ERROR + + let z: bool = transmute(1u8); + //~^ ERROR + let z: u8 = transmute(z); + //~^ ERROR + + let z: bool = transmute(1i8); + // no error! + let z: i8 = transmute(z); + //~^ ERROR + } +} diff --git a/tests/ui/transmute/unnecessary-transmutation.stderr b/tests/ui/transmute/unnecessary-transmutation.stderr new file mode 100644 index 0000000000000..b661aa13c985d --- /dev/null +++ b/tests/ui/transmute/unnecessary-transmutation.stderr @@ -0,0 +1,235 @@ +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:7:14 + | +LL | unsafe { transmute(x) } + | ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order +note: the lint level is defined here + --> $DIR/unnecessary-transmutation.rs:2:9 + | +LL | #![deny(unnecessary_transmutes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:13:22 + | +LL | let x: u16 = transmute(*b"01"); + | ^^^^^^^^^^^^^^^^^ help: replace this with: `u16::from_ne_bytes(*b"01")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:15:26 + | +LL | let x: [u8; 2] = transmute(x); + | ^^^^^^^^^^^^ help: replace this with: `u16::to_ne_bytes(x)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:17:22 + | +LL | let x: u32 = transmute(*b"0123"); + | ^^^^^^^^^^^^^^^^^^^ help: replace this with: `u32::from_ne_bytes(*b"0123")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:19:26 + | +LL | let x: [u8; 4] = transmute(x); + | ^^^^^^^^^^^^ help: replace this with: `u32::to_ne_bytes(x)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:21:22 + | +LL | let x: u64 = transmute(*b"feriscat"); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `u64::from_ne_bytes(*b"feriscat")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:23:26 + | +LL | let x: [u8; 8] = transmute(x); + | ^^^^^^^^^^^^ help: replace this with: `u64::to_ne_bytes(x)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:26:22 + | +LL | let y: i16 = transmute(*b"01"); + | ^^^^^^^^^^^^^^^^^ help: replace this with: `i16::from_ne_bytes(*b"01")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:28:26 + | +LL | let y: [u8; 2] = transmute(y); + | ^^^^^^^^^^^^ help: replace this with: `i16::to_ne_bytes(y)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:30:22 + | +LL | let y: i32 = transmute(*b"0123"); + | ^^^^^^^^^^^^^^^^^^^ help: replace this with: `i32::from_ne_bytes(*b"0123")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:32:26 + | +LL | let y: [u8; 4] = transmute(y); + | ^^^^^^^^^^^^ help: replace this with: `i32::to_ne_bytes(y)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:34:22 + | +LL | let y: i64 = transmute(*b"feriscat"); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `i64::from_ne_bytes(*b"feriscat")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:36:26 + | +LL | let y: [u8; 8] = transmute(y); + | ^^^^^^^^^^^^ help: replace this with: `i64::to_ne_bytes(y)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:39:22 + | +LL | let z: f32 = transmute(*b"0123"); + | ^^^^^^^^^^^^^^^^^^^ help: replace this with: `f32::from_ne_bytes(*b"0123")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:41:26 + | +LL | let z: [u8; 4] = transmute(z); + | ^^^^^^^^^^^^ help: replace this with: `f32::to_ne_bytes(z)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:43:22 + | +LL | let z: f64 = transmute(*b"feriscat"); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `f64::from_ne_bytes(*b"feriscat")` + | + = help: there's also `from_le_bytes` and `from_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:45:26 + | +LL | let z: [u8; 8] = transmute(z); + | ^^^^^^^^^^^^ help: replace this with: `f64::to_ne_bytes(z)` + | + = help: there's also `to_le_bytes` and `to_be_bytes` if you expect a particular byte order + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:48:22 + | +LL | let y: u32 = transmute('🦀'); + | ^^^^^^^^^^^^^^^ help: replace this with: `u32::from('🦀')` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:50:23 + | +LL | let y: char = transmute(y); + | ^^^^^^^^^^^^ help: replace this with: `char::from_u32_unchecked(y)` + | + = help: consider `char::from_u32(…).unwrap()` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:53:22 + | +LL | let x: u16 = transmute(8i16); + | ^^^^^^^^^^^^^^^ help: replace this with: `i16::cast_unsigned(8i16)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:55:22 + | +LL | let x: i16 = transmute(x); + | ^^^^^^^^^^^^ help: replace this with: `u16::cast_signed(x)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:57:22 + | +LL | let x: u32 = transmute(4i32); + | ^^^^^^^^^^^^^^^ help: replace this with: `i32::cast_unsigned(4i32)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:59:22 + | +LL | let x: i32 = transmute(x); + | ^^^^^^^^^^^^ help: replace this with: `u32::cast_signed(x)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:61:22 + | +LL | let x: u64 = transmute(7i64); + | ^^^^^^^^^^^^^^^ help: replace this with: `i64::cast_unsigned(7i64)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:63:22 + | +LL | let x: i64 = transmute(x); + | ^^^^^^^^^^^^ help: replace this with: `u64::cast_signed(x)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:66:22 + | +LL | let y: f32 = transmute(1u32); + | ^^^^^^^^^^^^^^^ help: replace this with: `f32::from_bits(1u32)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:68:22 + | +LL | let y: u32 = transmute(y); + | ^^^^^^^^^^^^ help: replace this with: `f32::to_bits(y)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:70:22 + | +LL | let y: f64 = transmute(3u64); + | ^^^^^^^^^^^^^^^ help: replace this with: `f64::from_bits(3u64)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:72:22 + | +LL | let y: u64 = transmute(2.0); + | ^^^^^^^^^^^^^^ help: replace this with: `f64::to_bits(2.0)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:75:23 + | +LL | let z: bool = transmute(1u8); + | ^^^^^^^^^^^^^^ help: replace this with: `(1u8 == 1)` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:77:21 + | +LL | let z: u8 = transmute(z); + | ^^^^^^^^^^^^ help: replace this with: `(z) as u8` + +error: unnecessary transmute + --> $DIR/unnecessary-transmutation.rs:82:21 + | +LL | let z: i8 = transmute(z); + | ^^^^^^^^^^^^ help: replace this with: `(z) as i8` + +error: aborting due to 32 previous errors +