Auto merge of #140256 - matthiaskrgr:rollup-8if58zf, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #136083 (Suggest {to,from}_ne_bytes for transmutations between arrays and integers, etc)
 - #138282 (Add `#[repr(u128)]`/`#[repr(i128)]` enums to `improper_ctypes_definitions`)
 - #139700 (Autodiff flags)
 - #140139 (rustc_target: Adjust RISC-V feature implication)
 - #140141 (Move zkVM constants into `sys::env_consts`)
 - #140150 (fix MAX_EXP and MIN_EXP docs)
 - #140172 (Make algebraic functions into `const fn` items.)
 - #140191 (Remove git repository from git config)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-04-24 19:48:38 +00:00
commit d7ea436a02
81 changed files with 1031 additions and 261 deletions

View File

@ -1,6 +1,6 @@
#![feature(no_core, unboxed_closures)] #![feature(no_core, unboxed_closures)]
#![no_core] #![no_core]
#![allow(dead_code)] #![allow(dead_code, unnecessary_transmutes)]
extern crate mini_core; extern crate mini_core;

View File

@ -1,6 +1,6 @@
#![feature(no_core, unboxed_closures)] #![feature(no_core, unboxed_closures)]
#![no_core] #![no_core]
#![allow(dead_code)] #![allow(dead_code, unnecessary_transmutes)]
extern crate mini_core; extern crate mini_core;
@ -11,11 +11,7 @@ fn abc(a: u8) -> u8 {
} }
fn bcd(b: bool, a: u8) -> u8 { fn bcd(b: bool, a: u8) -> u8 {
if b { if b { a * 2 } else { a * 3 }
a * 2
} else {
a * 3
}
} }
fn call() { fn call() {

View File

@ -584,12 +584,10 @@ fn thin_lto(
} }
} }
fn enable_autodiff_settings(ad: &[config::AutoDiff], module: &mut ModuleCodegen<ModuleLlvm>) { fn enable_autodiff_settings(ad: &[config::AutoDiff]) {
for &val in ad { for &val in ad {
// We intentionally don't use a wildcard, to not forget handling anything new.
match val { match val {
config::AutoDiff::PrintModBefore => {
unsafe { llvm::LLVMDumpModule(module.module_llvm.llmod()) };
}
config::AutoDiff::PrintPerf => { config::AutoDiff::PrintPerf => {
llvm::set_print_perf(true); llvm::set_print_perf(true);
} }
@ -603,17 +601,23 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff], module: &mut ModuleCodegen<
llvm::set_inline(true); llvm::set_inline(true);
} }
config::AutoDiff::LooseTypes => { config::AutoDiff::LooseTypes => {
llvm::set_loose_types(false); llvm::set_loose_types(true);
} }
config::AutoDiff::PrintSteps => { config::AutoDiff::PrintSteps => {
llvm::set_print(true); 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 => {} config::AutoDiff::PrintModAfter => {}
// We handle this below // We handle this in the PassWrapper.cpp
config::AutoDiff::PrintModFinal => {} config::AutoDiff::PrintModFinal => {}
// This is required and already checked // This is required and already checked
config::AutoDiff::Enable => {} config::AutoDiff::Enable => {}
// We handle this below
config::AutoDiff::NoPostopt => {}
} }
} }
// This helps with handling enums for now. // This helps with handling enums for now.
@ -647,28 +651,28 @@ pub(crate) fn run_pass_manager(
// We then run the llvm_optimize function a second time, to optimize the code which we generated // We then run the llvm_optimize function a second time, to optimize the code which we generated
// in the enzyme differentiation pass. // in the enzyme differentiation pass.
let enable_ad = config.autodiff.contains(&config::AutoDiff::Enable); let enable_ad = config.autodiff.contains(&config::AutoDiff::Enable);
let stage = let stage = if thin {
if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD }; write::AutodiffStage::PreAD
} else {
if enable_ad { write::AutodiffStage::DuringAD } else { write::AutodiffStage::PostAD }
};
if enable_ad { if enable_ad {
enable_autodiff_settings(&config.autodiff, module); enable_autodiff_settings(&config.autodiff);
} }
unsafe { unsafe {
write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?; write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?;
} }
if cfg!(llvm_enzyme) && enable_ad { if cfg!(llvm_enzyme) && enable_ad && !thin {
// 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()) };
}
let opt_stage = llvm::OptStage::FatLTO; let opt_stage = llvm::OptStage::FatLTO;
let stage = write::AutodiffStage::PostAD; let stage = write::AutodiffStage::PostAD;
if !config.autodiff.contains(&config::AutoDiff::NoPostopt) {
unsafe { unsafe {
write::llvm_optimize(cgcx, dcx, module, None, config, opt_level, opt_stage, stage)?; 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, // This is the final IR, so people should be able to inspect the optimized autodiff output,
// for manual inspection. // for manual inspection.

View File

@ -572,6 +572,10 @@ pub(crate) unsafe fn llvm_optimize(
let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable);
let run_enzyme = autodiff_stage == AutodiffStage::DuringAD; 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 unroll_loops;
let vectorize_slp; let vectorize_slp;
let vectorize_loop; 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 // 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). // 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 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 { if consider_ad && autodiff_stage != AutodiffStage::PostAD {
merge_functions = false;
unroll_loops = false; unroll_loops = false;
vectorize_slp = false; vectorize_slp = false;
vectorize_loop = false; vectorize_loop = false;
} else { } else {
unroll_loops = unroll_loops =
opt_level != config::OptLevel::Size && opt_level != config::OptLevel::SizeMin; opt_level != config::OptLevel::Size && opt_level != config::OptLevel::SizeMin;
merge_functions = config.merge_functions;
vectorize_slp = config.vectorize_slp; vectorize_slp = config.vectorize_slp;
vectorize_loop = config.vectorize_loop; vectorize_loop = config.vectorize_loop;
} }
@ -663,13 +674,16 @@ pub(crate) unsafe fn llvm_optimize(
thin_lto_buffer, thin_lto_buffer,
config.emit_thin_lto, config.emit_thin_lto,
config.emit_thin_lto_summary, config.emit_thin_lto_summary,
config.merge_functions, merge_functions,
unroll_loops, unroll_loops,
vectorize_slp, vectorize_slp,
vectorize_loop, vectorize_loop,
config.no_builtins, config.no_builtins,
config.emit_lifetime_markers, config.emit_lifetime_markers,
run_enzyme, run_enzyme,
print_before_enzyme,
print_after_enzyme,
print_passes,
sanitizer_options.as_ref(), sanitizer_options.as_ref(),
pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), 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()), pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),

View File

@ -473,7 +473,7 @@ pub(crate) fn differentiate<'ll>(
return Err(diag_handler.handle().emit_almost_fatal(AutoDiffWithoutEnable)); 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() { for item in diff_items.iter() {
let name = item.source.clone(); let name = item.source.clone();
let fn_def: Option<&llvm::Value> = cx.get_function(&name); let fn_def: Option<&llvm::Value> = cx.get_function(&name);

View File

@ -2454,6 +2454,9 @@ unsafe extern "C" {
DisableSimplifyLibCalls: bool, DisableSimplifyLibCalls: bool,
EmitLifetimeMarkers: bool, EmitLifetimeMarkers: bool,
RunEnzyme: bool, RunEnzyme: bool,
PrintBeforeEnzyme: bool,
PrintAfterEnzyme: bool,
PrintPasses: bool,
SanitizerOptions: Option<&SanitizerOptions>, SanitizerOptions: Option<&SanitizerOptions>,
PGOGenPath: *const c_char, PGOGenPath: *const c_char,
PGOUsePath: *const c_char, PGOUsePath: *const c_char,

View File

@ -158,6 +158,31 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.copy_op(&val, dest)?; 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::ctpop
| sym::cttz | sym::cttz
| sym::cttz_nonzero | sym::cttz_nonzero

View File

@ -1,7 +1,9 @@
use std::iter; use std::iter;
use std::ops::ControlFlow; 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_data_structures::fx::FxHashSet;
use rustc_errors::DiagMessage; use rustc_errors::DiagMessage;
use rustc_hir::intravisit::VisitorExt; 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; use improper_ctypes::check_non_exhaustive_variant;
let non_exhaustive = def.variant_list_has_applicable_non_exhaustive(); let non_exhaustive = def.variant_list_has_applicable_non_exhaustive();

View File

@ -117,6 +117,7 @@ declare_lint_pass! {
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
UNNAMEABLE_TEST_ITEMS, UNNAMEABLE_TEST_ITEMS,
UNNAMEABLE_TYPES, UNNAMEABLE_TYPES,
UNNECESSARY_TRANSMUTES,
UNREACHABLE_CODE, UNREACHABLE_CODE,
UNREACHABLE_PATTERNS, UNREACHABLE_PATTERNS,
UNSAFE_ATTR_OUTSIDE_UNSAFE, UNSAFE_ATTR_OUTSIDE_UNSAFE,
@ -4909,6 +4910,30 @@ declare_lint! {
"detects pointer to integer transmutes in const functions and associated constants", "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! { declare_lint! {
/// The `tail_expr_drop_order` lint looks for those values generated at the tail expression location, /// The `tail_expr_drop_order` lint looks for those values generated at the tail expression location,
/// that runs a custom `Drop` destructor. /// that runs a custom `Drop` destructor.

View File

@ -14,6 +14,7 @@
#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/IR/Verifier.h" #include "llvm/IR/Verifier.h"
#include "llvm/IRPrinter/IRPrintingPasses.h"
#include "llvm/LTO/LTO.h" #include "llvm/LTO/LTO.h"
#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h" #include "llvm/MC/TargetRegistry.h"
@ -703,7 +704,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef, bool EmitThinLTO, bool LintIR, LLVMRustThinLTOBuffer **ThinLTOBufferRef, bool EmitThinLTO,
bool EmitThinLTOSummary, bool MergeFunctions, bool UnrollLoops, bool EmitThinLTOSummary, bool MergeFunctions, bool UnrollLoops,
bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, 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, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath,
const char *PGOUsePath, bool InstrumentCoverage, const char *PGOUsePath, bool InstrumentCoverage,
const char *InstrProfileOutput, const char *PGOSampleUsePath, const char *InstrProfileOutput, const char *PGOSampleUsePath,
@ -1048,14 +1050,38 @@ extern "C" LLVMRustResult LLVMRustOptimize(
// now load "-enzyme" pass: // now load "-enzyme" pass:
#ifdef ENZYME #ifdef ENZYME
if (RunEnzyme) { 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")) { if (auto Err = PB.parsePassPipeline(MPM, "enzyme")) {
std::string ErrMsg = toString(std::move(Err)); std::string ErrMsg = toString(std::move(Err));
LLVMRustSetLastError(ErrMsg.c_str()); LLVMRustSetLastError(ErrMsg.c_str());
return LLVMRustResult::Failure; 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 #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. // Upgrade all calls to old intrinsics first.
for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;) for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)

View File

@ -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 .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_unknown_pass_name = MIR pass `{$name}` is unknown and will be ignored
mir_transform_unnecessary_transmute = unnecessary transmute

View File

@ -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<Error> {
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);
}
}
}

View File

@ -158,6 +158,26 @@ pub(crate) struct MustNotSuspendReason {
pub reason: String, 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)] #[derive(LintDiagnostic)]
#[diag(mir_transform_undefined_transmute)] #[diag(mir_transform_undefined_transmute)]
#[note] #[note]

View File

@ -125,6 +125,7 @@ declare_passes! {
mod check_null : CheckNull; mod check_null : CheckNull;
mod check_packed_ref : CheckPackedRef; mod check_packed_ref : CheckPackedRef;
mod check_undefined_transmutes : CheckUndefinedTransmutes; mod check_undefined_transmutes : CheckUndefinedTransmutes;
mod check_unnecessary_transmutes: CheckUnnecessaryTransmutes;
// This pass is public to allow external drivers to perform MIR cleanup // This pass is public to allow external drivers to perform MIR cleanup
pub mod cleanup_post_borrowck : CleanupPostBorrowck; pub mod cleanup_post_borrowck : CleanupPostBorrowck;
@ -391,6 +392,7 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
&Lint(check_const_item_mutation::CheckConstItemMutation), &Lint(check_const_item_mutation::CheckConstItemMutation),
&Lint(function_item_references::FunctionItemReferences), &Lint(function_item_references::FunctionItemReferences),
&Lint(check_undefined_transmutes::CheckUndefinedTransmutes), &Lint(check_undefined_transmutes::CheckUndefinedTransmutes),
&Lint(check_unnecessary_transmutes::CheckUnnecessaryTransmutes),
// What we need to do constant evaluation. // What we need to do constant evaluation.
&simplify::SimplifyCfg::Initial, &simplify::SimplifyCfg::Initial,
&Lint(sanity_check::SanityCheck), &Lint(sanity_check::SanityCheck),

View File

@ -246,6 +246,10 @@ pub enum AutoDiff {
/// Print the module after running autodiff and optimizations. /// Print the module after running autodiff and optimizations.
PrintModFinal, 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!!) /// Enzyme's loose type debug helper (can cause incorrect gradients!!)
/// Usable in cases where Enzyme errors with `can not deduce type of X`. /// Usable in cases where Enzyme errors with `can not deduce type of X`.
LooseTypes, LooseTypes,

View File

@ -711,7 +711,7 @@ mod desc {
pub(crate) const parse_list: &str = "a space-separated list of strings"; pub(crate) const parse_list: &str = "a space-separated list of strings";
pub(crate) const parse_list_with_polarity: &str = pub(crate) const parse_list_with_polarity: &str =
"a comma-separated list of strings, with elements beginning with + or -"; "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_comma_list: &str = "a comma-separated list of strings";
pub(crate) const parse_opt_comma_list: &str = parse_comma_list; pub(crate) const parse_opt_comma_list: &str = parse_comma_list;
pub(crate) const parse_number: &str = "a number"; pub(crate) const parse_number: &str = "a number";
@ -1360,6 +1360,8 @@ pub mod parse {
"PrintModBefore" => AutoDiff::PrintModBefore, "PrintModBefore" => AutoDiff::PrintModBefore,
"PrintModAfter" => AutoDiff::PrintModAfter, "PrintModAfter" => AutoDiff::PrintModAfter,
"PrintModFinal" => AutoDiff::PrintModFinal, "PrintModFinal" => AutoDiff::PrintModFinal,
"NoPostopt" => AutoDiff::NoPostopt,
"PrintPasses" => AutoDiff::PrintPasses,
"LooseTypes" => AutoDiff::LooseTypes, "LooseTypes" => AutoDiff::LooseTypes,
"Inline" => AutoDiff::Inline, "Inline" => AutoDiff::Inline,
_ => { _ => {
@ -2098,6 +2100,8 @@ options! {
`=PrintModBefore` `=PrintModBefore`
`=PrintModAfter` `=PrintModAfter`
`=PrintModFinal` `=PrintModFinal`
`=PrintPasses`,
`=NoPostopt`
`=LooseTypes` `=LooseTypes`
`=Inline` `=Inline`
Multiple options can be combined with commas."), Multiple options can be combined with commas."),

View File

@ -516,7 +516,7 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("zawrs", Unstable(sym::riscv_target_feature), &[]), ("zawrs", Unstable(sym::riscv_target_feature), &[]),
("zba", Stable, &[]), ("zba", Stable, &[]),
("zbb", Stable, &[]), ("zbb", Stable, &[]),
("zbc", Stable, &[]), ("zbc", Stable, &["zbkc"]), // Zbc ⊃ Zbkc
("zbkb", Stable, &[]), ("zbkb", Stable, &[]),
("zbkc", Stable, &[]), ("zbkc", Stable, &[]),
("zbkx", Stable, &[]), ("zbkx", Stable, &[]),
@ -545,20 +545,20 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
("zknd", Stable, &[]), ("zknd", Stable, &[]),
("zkne", Stable, &[]), ("zkne", Stable, &[]),
("zknh", Stable, &[]), ("zknh", Stable, &[]),
("zkr", Stable, &["zicsr"]), ("zkr", Stable, &[]),
("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]), ("zks", Stable, &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
("zksed", Stable, &[]), ("zksed", Stable, &[]),
("zksh", Stable, &[]), ("zksh", Stable, &[]),
("zkt", Stable, &[]), ("zkt", Stable, &[]),
("ztso", Unstable(sym::riscv_target_feature), &[]), ("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"]), ("zvbc", Unstable(sym::riscv_target_feature), &["zve64x"]),
("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]), ("zve32f", Unstable(sym::riscv_target_feature), &["zve32x", "f"]),
("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]), ("zve32x", Unstable(sym::riscv_target_feature), &["zvl32b", "zicsr"]),
("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]), ("zve64d", Unstable(sym::riscv_target_feature), &["zve64f", "d"]),
("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]), ("zve64f", Unstable(sym::riscv_target_feature), &["zve32f", "zve64x"]),
("zve64x", Unstable(sym::riscv_target_feature), &["zve32x", "zvl64b"]), ("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"]), ("zvfhmin", Unstable(sym::riscv_target_feature), &["zve32f"]),
("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]), ("zvkb", Unstable(sym::riscv_target_feature), &["zve32x"]),
("zvkg", 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"]), ("zvkned", Unstable(sym::riscv_target_feature), &["zve32x"]),
("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]), ("zvkng", Unstable(sym::riscv_target_feature), &["zvkn", "zvkg"]),
("zvknha", Unstable(sym::riscv_target_feature), &["zve32x"]), ("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"]), ("zvks", Unstable(sym::riscv_target_feature), &["zvksed", "zvksh", "zvkb", "zvkt"]),
("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]), ("zvksc", Unstable(sym::riscv_target_feature), &["zvks", "zvbc"]),
("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]), ("zvksed", Unstable(sym::riscv_target_feature), &["zve32x"]),

View File

@ -1,6 +1,7 @@
#![deny(warnings)] #![deny(warnings)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)] #![allow(static_mut_refs)]
#![cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::{self, Write}; use std::fmt::{self, Write};

View File

@ -21,6 +21,7 @@ pub(super) const fn from_u32(i: u32) -> Option<char> {
/// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`]. /// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`].
#[inline] #[inline]
#[must_use] #[must_use]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
// SAFETY: the caller must guarantee that `i` is a valid char value. // SAFETY: the caller must guarantee that `i` is a valid char value.
unsafe { unsafe {
@ -221,6 +222,7 @@ impl FromStr for char {
} }
#[inline] #[inline]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> { const fn char_try_from_u32(i: u32) -> Result<char, CharTryFromError> {
// This is an optimized version of the check // This is an optimized version of the check
// (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF), // (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF),

View File

@ -1497,6 +1497,7 @@ pub const fn forget<T: ?Sized>(_: T);
/// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.: /// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.:
/// ///
/// ``` /// ```
/// # #![cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
/// let raw_bytes = [0x78, 0x56, 0x34, 0x12]; /// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
/// ///
/// let num = unsafe { /// let num = unsafe {
@ -2429,35 +2430,35 @@ pub unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> In
/// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`]. /// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`].
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
pub fn fadd_algebraic<T: Copy>(a: T, b: T) -> T; pub const fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
/// Float subtraction that allows optimizations based on algebraic rules. /// Float subtraction that allows optimizations based on algebraic rules.
/// ///
/// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`]. /// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`].
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
pub fn fsub_algebraic<T: Copy>(a: T, b: T) -> T; pub const fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
/// Float multiplication that allows optimizations based on algebraic rules. /// Float multiplication that allows optimizations based on algebraic rules.
/// ///
/// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`]. /// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`].
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
pub fn fmul_algebraic<T: Copy>(a: T, b: T) -> T; pub const fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
/// Float division that allows optimizations based on algebraic rules. /// Float division that allows optimizations based on algebraic rules.
/// ///
/// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`]. /// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`].
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
pub fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T; pub const fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
/// Float remainder that allows optimizations based on algebraic rules. /// Float remainder that allows optimizations based on algebraic rules.
/// ///
/// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`]. /// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`].
#[rustc_nounwind] #[rustc_nounwind]
#[rustc_intrinsic] #[rustc_intrinsic]
pub fn frem_algebraic<T: Copy>(a: T, b: T) -> T; pub const fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
/// Returns the number of bits set in an integer type `T` /// Returns the number of bits set in an integer type `T`
/// ///

View File

@ -197,16 +197,22 @@ impl f128 {
#[unstable(feature = "f128", issue = "116909")] #[unstable(feature = "f128", issue = "116909")]
pub const MAX: f128 = 1.18973149535723176508575932662800702e+4932_f128; 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 <i>x</i>&nbsp;=&nbsp;`MIN_EXP`, then normal numbers /// This corresponds to the exact minimum possible *normal* power of 2 exponent
/// ≥&nbsp;0.5&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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&nbsp;×&nbsp;2<sup><i>MIN_EXP</i></sup>.
#[unstable(feature = "f128", issue = "116909")] #[unstable(feature = "f128", issue = "116909")]
pub const MIN_EXP: i32 = -16_381; 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 <i>x</i>&nbsp;=&nbsp;`MAX_EXP`, then normal numbers /// This corresponds to the exact maximum possible power of 2 exponent
/// &lt;&nbsp;1&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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 2<sup><i>MAX_EXP</i></sup>.
#[unstable(feature = "f128", issue = "116909")] #[unstable(feature = "f128", issue = "116909")]
pub const MAX_EXP: i32 = 16_384; pub const MAX_EXP: i32 = 16_384;
@ -904,6 +910,7 @@ impl f128 {
#[inline] #[inline]
#[unstable(feature = "f128", issue = "116909")] #[unstable(feature = "f128", issue = "116909")]
#[must_use = "this returns the result of the operation, without modifying the original"] #[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 { pub const fn to_bits(self) -> u128 {
// SAFETY: `u128` is a plain old datatype so we can always transmute to it. // SAFETY: `u128` is a plain old datatype so we can always transmute to it.
unsafe { mem::transmute(self) } unsafe { mem::transmute(self) }
@ -951,6 +958,7 @@ impl f128 {
#[inline] #[inline]
#[must_use] #[must_use]
#[unstable(feature = "f128", issue = "116909")] #[unstable(feature = "f128", issue = "116909")]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
pub const fn from_bits(v: u128) -> Self { pub const fn from_bits(v: u128) -> Self {
// It turns out the safety issues with sNaN were overblown! Hooray! // 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. // 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. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_add(self, rhs: f128) -> f128 { pub const fn algebraic_add(self, rhs: f128) -> f128 {
intrinsics::fadd_algebraic(self, rhs) intrinsics::fadd_algebraic(self, rhs)
} }
@ -1384,8 +1393,9 @@ impl f128 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_sub(self, rhs: f128) -> f128 { pub const fn algebraic_sub(self, rhs: f128) -> f128 {
intrinsics::fsub_algebraic(self, rhs) intrinsics::fsub_algebraic(self, rhs)
} }
@ -1394,8 +1404,9 @@ impl f128 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_mul(self, rhs: f128) -> f128 { pub const fn algebraic_mul(self, rhs: f128) -> f128 {
intrinsics::fmul_algebraic(self, rhs) intrinsics::fmul_algebraic(self, rhs)
} }
@ -1404,8 +1415,9 @@ impl f128 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_div(self, rhs: f128) -> f128 { pub const fn algebraic_div(self, rhs: f128) -> f128 {
intrinsics::fdiv_algebraic(self, rhs) intrinsics::fdiv_algebraic(self, rhs)
} }
@ -1414,8 +1426,9 @@ impl f128 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_rem(self, rhs: f128) -> f128 { pub const fn algebraic_rem(self, rhs: f128) -> f128 {
intrinsics::frem_algebraic(self, rhs) intrinsics::frem_algebraic(self, rhs)
} }
} }

View File

@ -192,16 +192,22 @@ impl f16 {
#[unstable(feature = "f16", issue = "116909")] #[unstable(feature = "f16", issue = "116909")]
pub const MAX: f16 = 6.5504e+4_f16; 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 <i>x</i>&nbsp;=&nbsp;`MIN_EXP`, then normal numbers /// This corresponds to the exact minimum possible *normal* power of 2 exponent
/// ≥&nbsp;0.5&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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&nbsp;×&nbsp;2<sup><i>MIN_EXP</i></sup>.
#[unstable(feature = "f16", issue = "116909")] #[unstable(feature = "f16", issue = "116909")]
pub const MIN_EXP: i32 = -13; 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 <i>x</i>&nbsp;=&nbsp;`MAX_EXP`, then normal numbers /// This corresponds to the exact maximum possible power of 2 exponent
/// &lt;&nbsp;1&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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 2<sup><i>MAX_EXP</i></sup>.
#[unstable(feature = "f16", issue = "116909")] #[unstable(feature = "f16", issue = "116909")]
pub const MAX_EXP: i32 = 16; pub const MAX_EXP: i32 = 16;
@ -892,6 +898,7 @@ impl f16 {
#[inline] #[inline]
#[unstable(feature = "f16", issue = "116909")] #[unstable(feature = "f16", issue = "116909")]
#[must_use = "this returns the result of the operation, without modifying the original"] #[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 { pub const fn to_bits(self) -> u16 {
// SAFETY: `u16` is a plain old datatype so we can always transmute to it. // SAFETY: `u16` is a plain old datatype so we can always transmute to it.
unsafe { mem::transmute(self) } unsafe { mem::transmute(self) }
@ -938,6 +945,7 @@ impl f16 {
#[inline] #[inline]
#[must_use] #[must_use]
#[unstable(feature = "f16", issue = "116909")] #[unstable(feature = "f16", issue = "116909")]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
pub const fn from_bits(v: u16) -> Self { pub const fn from_bits(v: u16) -> Self {
// It turns out the safety issues with sNaN were overblown! Hooray! // 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. // 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. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_add(self, rhs: f16) -> f16 { pub const fn algebraic_add(self, rhs: f16) -> f16 {
intrinsics::fadd_algebraic(self, rhs) intrinsics::fadd_algebraic(self, rhs)
} }
@ -1360,8 +1369,9 @@ impl f16 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_sub(self, rhs: f16) -> f16 { pub const fn algebraic_sub(self, rhs: f16) -> f16 {
intrinsics::fsub_algebraic(self, rhs) intrinsics::fsub_algebraic(self, rhs)
} }
@ -1370,8 +1380,9 @@ impl f16 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_mul(self, rhs: f16) -> f16 { pub const fn algebraic_mul(self, rhs: f16) -> f16 {
intrinsics::fmul_algebraic(self, rhs) intrinsics::fmul_algebraic(self, rhs)
} }
@ -1380,8 +1391,9 @@ impl f16 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_div(self, rhs: f16) -> f16 { pub const fn algebraic_div(self, rhs: f16) -> f16 {
intrinsics::fdiv_algebraic(self, rhs) intrinsics::fdiv_algebraic(self, rhs)
} }
@ -1390,8 +1402,9 @@ impl f16 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_rem(self, rhs: f16) -> f16 { pub const fn algebraic_rem(self, rhs: f16) -> f16 {
intrinsics::frem_algebraic(self, rhs) intrinsics::frem_algebraic(self, rhs)
} }
} }

View File

@ -443,16 +443,22 @@ impl f32 {
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MAX: f32 = 3.40282347e+38_f32; 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 <i>x</i>&nbsp;=&nbsp;`MIN_EXP`, then normal numbers /// This corresponds to the exact minimum possible *normal* power of 2 exponent
/// ≥&nbsp;0.5&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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&nbsp;×&nbsp;2<sup><i>MIN_EXP</i></sup>.
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MIN_EXP: i32 = -125; 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 <i>x</i>&nbsp;=&nbsp;`MAX_EXP`, then normal numbers /// This corresponds to the exact maximum possible power of 2 exponent
/// &lt;&nbsp;1&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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 2<sup><i>MAX_EXP</i></sup>.
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MAX_EXP: i32 = 128; pub const MAX_EXP: i32 = 128;
@ -710,8 +716,7 @@ impl f32 {
pub const fn is_sign_negative(self) -> bool { pub const fn is_sign_negative(self) -> bool {
// IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
// applies to zeros and NaNs as well. // applies to zeros and NaNs as well.
// SAFETY: This is just transmuting to get the sign bit, it's fine. self.to_bits() & 0x8000_0000 != 0
unsafe { mem::transmute::<f32, u32>(self) & 0x8000_0000 != 0 }
} }
/// Returns the least number greater than `self`. /// Returns the least number greater than `self`.
@ -1097,6 +1102,7 @@ impl f32 {
#[stable(feature = "float_bits_conv", since = "1.20.0")] #[stable(feature = "float_bits_conv", since = "1.20.0")]
#[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
#[inline] #[inline]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
pub const fn to_bits(self) -> u32 { pub const fn to_bits(self) -> u32 {
// SAFETY: `u32` is a plain old datatype so we can always transmute to it. // SAFETY: `u32` is a plain old datatype so we can always transmute to it.
unsafe { mem::transmute(self) } unsafe { mem::transmute(self) }
@ -1142,6 +1148,7 @@ impl f32 {
#[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
#[must_use] #[must_use]
#[inline] #[inline]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
pub const fn from_bits(v: u32) -> Self { pub const fn from_bits(v: u32) -> Self {
// It turns out the safety issues with sNaN were overblown! Hooray! // 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. // 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. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_add(self, rhs: f32) -> f32 { pub const fn algebraic_add(self, rhs: f32) -> f32 {
intrinsics::fadd_algebraic(self, rhs) intrinsics::fadd_algebraic(self, rhs)
} }
@ -1526,8 +1534,9 @@ impl f32 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_sub(self, rhs: f32) -> f32 { pub const fn algebraic_sub(self, rhs: f32) -> f32 {
intrinsics::fsub_algebraic(self, rhs) intrinsics::fsub_algebraic(self, rhs)
} }
@ -1536,8 +1545,9 @@ impl f32 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_mul(self, rhs: f32) -> f32 { pub const fn algebraic_mul(self, rhs: f32) -> f32 {
intrinsics::fmul_algebraic(self, rhs) intrinsics::fmul_algebraic(self, rhs)
} }
@ -1546,8 +1556,9 @@ impl f32 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_div(self, rhs: f32) -> f32 { pub const fn algebraic_div(self, rhs: f32) -> f32 {
intrinsics::fdiv_algebraic(self, rhs) intrinsics::fdiv_algebraic(self, rhs)
} }
@ -1556,8 +1567,9 @@ impl f32 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_rem(self, rhs: f32) -> f32 { pub const fn algebraic_rem(self, rhs: f32) -> f32 {
intrinsics::frem_algebraic(self, rhs) intrinsics::frem_algebraic(self, rhs)
} }
} }

View File

@ -442,16 +442,22 @@ impl f64 {
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MAX: f64 = 1.7976931348623157e+308_f64; 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 <i>x</i>&nbsp;=&nbsp;`MIN_EXP`, then normal numbers /// This corresponds to the exact minimum possible *normal* power of 2 exponent
/// ≥&nbsp;0.5&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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&nbsp;×&nbsp;2<sup><i>MIN_EXP</i></sup>.
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MIN_EXP: i32 = -1021; 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 <i>x</i>&nbsp;=&nbsp;`MAX_EXP`, then normal numbers /// This corresponds to the exact maximum possible power of 2 exponent
/// &lt;&nbsp;1&nbsp;×&nbsp;2<sup><i>x</i></sup>. /// 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 2<sup><i>MAX_EXP</i></sup>.
#[stable(feature = "assoc_int_consts", since = "1.43.0")] #[stable(feature = "assoc_int_consts", since = "1.43.0")]
pub const MAX_EXP: i32 = 1024; pub const MAX_EXP: i32 = 1024;
@ -718,8 +724,7 @@ impl f64 {
pub const fn is_sign_negative(self) -> bool { pub const fn is_sign_negative(self) -> bool {
// IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus // IEEE754 says: isSignMinus(x) is true if and only if x has negative sign. isSignMinus
// applies to zeros and NaNs as well. // applies to zeros and NaNs as well.
// SAFETY: This is just transmuting to get the sign bit, it's fine. self.to_bits() & Self::SIGN_MASK != 0
unsafe { mem::transmute::<f64, u64>(self) & Self::SIGN_MASK != 0 }
} }
#[must_use] #[must_use]
@ -1095,6 +1100,7 @@ impl f64 {
without modifying the original"] without modifying the original"]
#[stable(feature = "float_bits_conv", since = "1.20.0")] #[stable(feature = "float_bits_conv", since = "1.20.0")]
#[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")] #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
#[inline] #[inline]
pub const fn to_bits(self) -> u64 { pub const fn to_bits(self) -> u64 {
// SAFETY: `u64` is a plain old datatype so we can always transmute to it. // 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")] #[rustc_const_stable(feature = "const_float_bits_conv", since = "1.83.0")]
#[must_use] #[must_use]
#[inline] #[inline]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
pub const fn from_bits(v: u64) -> Self { pub const fn from_bits(v: u64) -> Self {
// It turns out the safety issues with sNaN were overblown! Hooray! // 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. // 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. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_add(self, rhs: f64) -> f64 { pub const fn algebraic_add(self, rhs: f64) -> f64 {
intrinsics::fadd_algebraic(self, rhs) intrinsics::fadd_algebraic(self, rhs)
} }
@ -1525,8 +1533,9 @@ impl f64 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_sub(self, rhs: f64) -> f64 { pub const fn algebraic_sub(self, rhs: f64) -> f64 {
intrinsics::fsub_algebraic(self, rhs) intrinsics::fsub_algebraic(self, rhs)
} }
@ -1535,8 +1544,9 @@ impl f64 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_mul(self, rhs: f64) -> f64 { pub const fn algebraic_mul(self, rhs: f64) -> f64 {
intrinsics::fmul_algebraic(self, rhs) intrinsics::fmul_algebraic(self, rhs)
} }
@ -1545,8 +1555,9 @@ impl f64 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_div(self, rhs: f64) -> f64 { pub const fn algebraic_div(self, rhs: f64) -> f64 {
intrinsics::fdiv_algebraic(self, rhs) intrinsics::fdiv_algebraic(self, rhs)
} }
@ -1555,8 +1566,9 @@ impl f64 {
/// See [algebraic operators](primitive@f32#algebraic-operators) for more info. /// See [algebraic operators](primitive@f32#algebraic-operators) for more info.
#[must_use = "method returns a new number and does not mutate the original value"] #[must_use = "method returns a new number and does not mutate the original value"]
#[unstable(feature = "float_algebraic", issue = "136469")] #[unstable(feature = "float_algebraic", issue = "136469")]
#[rustc_const_unstable(feature = "float_algebraic", issue = "136469")]
#[inline] #[inline]
pub fn algebraic_rem(self, rhs: f64) -> f64 { pub const fn algebraic_rem(self, rhs: f64) -> f64 {
intrinsics::frem_algebraic(self, rhs) intrinsics::frem_algebraic(self, rhs)
} }
} }

View File

@ -3675,6 +3675,7 @@ macro_rules! int_impl {
/// ``` /// ```
#[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.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 // SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes // transmute them to arrays of bytes
#[must_use = "this returns the result of the operation, \ #[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")] #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
#[must_use] #[must_use]
// SAFETY: const sound because integers are plain old datatypes so we can always // SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them // transmute to them

View File

@ -3523,6 +3523,7 @@ macro_rules! uint_impl {
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
// SAFETY: const sound because integers are plain old datatypes so we can always // SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes // transmute them to arrays of bytes
#[inline] #[inline]
@ -3624,6 +3625,7 @@ macro_rules! uint_impl {
/// ``` /// ```
#[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
#[cfg_attr(not(bootstrap), allow(unnecessary_transmutes))]
#[must_use] #[must_use]
// SAFETY: const sound because integers are plain old datatypes so we can always // SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them // transmute to them

View File

@ -389,6 +389,17 @@ pub mod os {
pub const EXE_EXTENSION: &str = "exe"; 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. // The fallback when none of the other gates match.
#[else] #[else]
pub mod os { pub mod os {

View File

@ -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";
}

@ -1 +1 @@
Subproject commit 4666c7376f25a265c74535585d622da3da6dfeb1 Subproject commit 1245618ccf5b2df7ab1ebb0279b9f3f726670161

View File

@ -13,7 +13,6 @@ pub fn suggest(builder: &Builder<'_>, run: bool) {
let git_config = builder.config.git_config(); let git_config = builder.config.git_config();
let suggestions = builder let suggestions = builder
.tool_cmd(Tool::SuggestTests) .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_NIGHTLY_BRANCH", git_config.nightly_branch)
.env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL", git_config.git_merge_commit_email) .env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL", git_config.git_merge_commit_email)
.run_capture_stdout(builder) .run_capture_stdout(builder)

View File

@ -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(); 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("--nightly-branch").arg(git_config.nightly_branch);
cmd.arg("--git-merge-commit-email").arg(git_config.git_merge_commit_email); cmd.arg("--git-merge-commit-email").arg(git_config.git_merge_commit_email);
cmd.force_coloring_in_ci(); cmd.force_coloring_in_ci();

View File

@ -2963,7 +2963,6 @@ impl Config {
pub fn git_config(&self) -> GitConfig<'_> { pub fn git_config(&self) -> GitConfig<'_> {
GitConfig { GitConfig {
git_repository: &self.stage0_metadata.config.git_repository,
nightly_branch: &self.stage0_metadata.config.nightly_branch, nightly_branch: &self.stage0_metadata.config.nightly_branch,
git_merge_commit_email: &self.stage0_metadata.config.git_merge_commit_email, git_merge_commit_email: &self.stage0_metadata.config.git_merge_commit_email,
} }

View File

@ -135,7 +135,6 @@ impl GitCtx {
fn git_config(&self) -> GitConfig<'_> { fn git_config(&self) -> GitConfig<'_> {
GitConfig { GitConfig {
git_repository: &self.git_repo,
nightly_branch: &self.nightly_branch, nightly_branch: &self.nightly_branch,
git_merge_commit_email: &self.merge_bot_email, git_merge_commit_email: &self.merge_bot_email,
} }

View File

@ -5,7 +5,6 @@ use crate::ci::CiEnv;
#[derive(Debug)] #[derive(Debug)]
pub struct GitConfig<'a> { pub struct GitConfig<'a> {
pub git_repository: &'a str,
pub nightly_branch: &'a str, pub nightly_branch: &'a str,
pub git_merge_commit_email: &'a str, pub git_merge_commit_email: &'a str,
} }

View File

@ -20,7 +20,6 @@ pub struct Stage0Config {
pub artifacts_server: String, pub artifacts_server: String,
pub artifacts_with_llvm_assertions_server: String, pub artifacts_with_llvm_assertions_server: String,
pub git_merge_commit_email: String, pub git_merge_commit_email: String,
pub git_repository: String,
pub nightly_branch: 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() stage0.config.artifacts_with_llvm_assertions_server = value.to_owned()
} }
"git_merge_commit_email" => stage0.config.git_merge_commit_email = 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(), "nightly_branch" => stage0.config.nightly_branch = value.to_owned(),
"compiler_date" => stage0.compiler.date = value.to_owned(), "compiler_date" => stage0.compiler.date = value.to_owned(),

View File

@ -2,7 +2,6 @@ dist_server=https://static.rust-lang.org
artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds
artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt
git_merge_commit_email=bors@rust-lang.org git_merge_commit_email=bors@rust-lang.org
git_repository=rust-lang/rust
nightly_branch=master nightly_branch=master
# The configuration above this comment is editable, and can be changed # The configuration above this comment is editable, and can be changed

View File

@ -61,7 +61,6 @@ impl Tool {
artifacts_server, artifacts_server,
artifacts_with_llvm_assertions_server, artifacts_with_llvm_assertions_server,
git_merge_commit_email, git_merge_commit_email,
git_repository,
nightly_branch, nightly_branch,
} = &self.config; } = &self.config;
@ -72,7 +71,6 @@ impl Tool {
artifacts_with_llvm_assertions_server 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_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(&format!("nightly_branch={}\n", nightly_branch));
file_content.push_str("\n"); file_content.push_str("\n");

View File

@ -1,7 +1,13 @@
//@aux-build:proc_macro_attr.rs //@aux-build:proc_macro_attr.rs
#![warn(clippy::blocks_in_conditions)] #![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)] #![warn(clippy::nonminimal_bool)]
macro_rules! blocky { macro_rules! blocky {

View File

@ -1,7 +1,13 @@
//@aux-build:proc_macro_attr.rs //@aux-build:proc_macro_attr.rs
#![warn(clippy::blocks_in_conditions)] #![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)] #![warn(clippy::nonminimal_bool)]
macro_rules! blocky { macro_rules! blocky {

View File

@ -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` 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 | / if {
LL | | LL | |
@ -20,13 +20,13 @@ LL ~ }; if res {
| |
error: omit braces around single expression condition 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 } LL | if { true } { 6 } else { 10 }
| ^^^^^^^^ help: try: `true` | ^^^^^^^^ help: try: `true`
error: this boolean expression can be simplified 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 } LL | if true && x == 3 { 6 } else { 10 }
| ^^^^^^^^^^^^^^ help: try: `x == 3` | ^^^^^^^^^^^^^^ help: try: `x == 3`

View File

@ -1,6 +1,6 @@
//@ check-pass //@ 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)] #![allow(clippy::unnecessary_cast, clippy::missing_transmute_annotations)]
/// Should not trigger an ICE in `SpanlessEq` / `consts::constant` /// Should not trigger an ICE in `SpanlessEq` / `consts::constant`

View File

@ -3,6 +3,7 @@
#![allow( #![allow(
dead_code, dead_code,
clippy::borrow_as_ptr, clippy::borrow_as_ptr,
unnecessary_transmutes,
clippy::needless_lifetimes, clippy::needless_lifetimes,
clippy::missing_transmute_annotations clippy::missing_transmute_annotations
)] )]

View File

@ -1,5 +1,5 @@
error: transmute from a reference to a pointer 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); LL | let _: *const T = core::mem::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const 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)]` = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]`
error: transmute from a reference to a pointer 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); LL | let _: *mut T = core::mem::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T` | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T`
error: transmute from a reference to a pointer 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); LL | let _: *const U = core::mem::transmute(t);
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U` | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U`
error: transmute from a type (`std::vec::Vec<i32>`) to itself error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> tests/ui/transmute.rs:46:27 --> tests/ui/transmute.rs:47:27
| |
LL | let _: Vec<i32> = core::mem::transmute(my_vec()); LL | let _: Vec<i32> = core::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> tests/ui/transmute.rs:49:27 --> tests/ui/transmute.rs:50:27
| |
LL | let _: Vec<i32> = core::mem::transmute(my_vec()); LL | let _: Vec<i32> = core::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> tests/ui/transmute.rs:52:27 --> tests/ui/transmute.rs:53:27
| |
LL | let _: Vec<i32> = std::mem::transmute(my_vec()); LL | let _: Vec<i32> = std::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> tests/ui/transmute.rs:55:27 --> tests/ui/transmute.rs:56:27
| |
LL | let _: Vec<i32> = std::mem::transmute(my_vec()); LL | let _: Vec<i32> = std::mem::transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`std::vec::Vec<i32>`) to itself error: transmute from a type (`std::vec::Vec<i32>`) to itself
--> tests/ui/transmute.rs:58:27 --> tests/ui/transmute.rs:59:27
| |
LL | let _: Vec<i32> = my_transmute(my_vec()); LL | let _: Vec<i32> = my_transmute(my_vec());
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error: transmute from an integer to a pointer 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); LL | let _: *const usize = std::mem::transmute(5_isize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize`
error: transmute from an integer to a pointer 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); LL | let _: *const usize = std::mem::transmute(1 + 1usize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize`
error: transmute from a type (`*const Usize`) to the type that it points to (`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); 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)]` = 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`) 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); LL | let _: Usize = core::mem::transmute(int_mut_ptr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`) 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()); LL | let _: *const Usize = core::mem::transmute(my_int());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`) 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()); LL | let _: *mut Usize = core::mem::transmute(my_int());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: transmute from a `u8` to a `bool` 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) }; LL | let _: bool = unsafe { std::mem::transmute(0_u8) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0` | ^^^^^^^^^^^^^^^^^^^^^^^^^ 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)]` = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]`
error: transmute from a `u16` to a `f16` 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) }; LL | let _: f16 = unsafe { std::mem::transmute(0_u16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(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)]` = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]`
error: transmute from a `i16` to a `f16` 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) }; LL | let _: f16 = unsafe { std::mem::transmute(0_i16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_i16 as u16)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_i16 as u16)`
error: transmute from a `u32` to a `f32` 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) }; LL | let _: f32 = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
error: transmute from a `i32` to a `f32` 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) }; LL | let _: f32 = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
error: transmute from a `u64` to a `f64` 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) }; LL | let _: f64 = unsafe { std::mem::transmute(0_u64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
error: transmute from a `i64` to a `f64` 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) }; LL | let _: f64 = unsafe { std::mem::transmute(0_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
error: transmute from a `u128` to a `f128` 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) }; LL | let _: f128 = unsafe { std::mem::transmute(0_u128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_u128)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_u128)`
error: transmute from a `i128` to a `f128` 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) }; LL | let _: f128 = unsafe { std::mem::transmute(0_i128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
error: transmute from a `u16` to a `f16` 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) }; LL | const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)`
error: transmute from a `u32` to a `f32` 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) }; LL | const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
error: transmute from a `i64` to a `f64` 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) }; LL | const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
error: transmute from a `i128` to a `f128` 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) }; LL | const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
error: transmute from a `i16` to a `f16` 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) } LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)`
error: transmute from a `i32` to a `f32` 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) } LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)`
error: transmute from a `u64` to a `f64` 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) } LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)`
error: transmute from a `u128` to a `f128` 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) } LL | unsafe { std::mem::transmute(v) }
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)`
error: transmute from a `u8` to a `[u8; 1]` 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); LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ 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)]` = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
error: transmute from a `u32` to a `[u8; 4]` 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); LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]` 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); LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]` 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); LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]` 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); LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]` 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); LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `f16` to a `[u8; 2]` 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); LL | let _: [u8; 2] = std::mem::transmute(0.0f16);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
error: transmute from a `f32` to a `[u8; 4]` 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); LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
error: transmute from a `f64` to a `[u8; 8]` 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); LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
error: transmute from a `f128` to a `[u8; 16]` 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); LL | let _: [u8; 16] = std::mem::transmute(0.0f128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
error: transmute from a `u8` to a `[u8; 1]` 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); LL | let _: [u8; 1] = std::mem::transmute(0u8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
error: transmute from a `u32` to a `[u8; 4]` 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); LL | let _: [u8; 4] = std::mem::transmute(0u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
error: transmute from a `u128` to a `[u8; 16]` 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); LL | let _: [u8; 16] = std::mem::transmute(0u128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
error: transmute from a `i8` to a `[u8; 1]` 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); LL | let _: [u8; 1] = std::mem::transmute(0i8);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
error: transmute from a `i32` to a `[u8; 4]` 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); LL | let _: [u8; 4] = std::mem::transmute(0i32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
error: transmute from a `i128` to a `[u8; 16]` 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); LL | let _: [u8; 16] = std::mem::transmute(0i128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
error: transmute from a `f16` to a `[u8; 2]` 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); LL | let _: [u8; 2] = std::mem::transmute(0.0f16);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
error: transmute from a `f32` to a `[u8; 4]` 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); LL | let _: [u8; 4] = std::mem::transmute(0.0f32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
error: transmute from a `f64` to a `[u8; 8]` 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); LL | let _: [u8; 8] = std::mem::transmute(0.0f64);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
error: transmute from a `f128` to a `[u8; 16]` 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); LL | let _: [u8; 16] = std::mem::transmute(0.0f128);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
error: transmute from a `&[u8]` to a `&str` 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) }; LL | let _: &str = unsafe { std::mem::transmute(B) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()` | ^^^^^^^^^^^^^^^^^^^^^^ 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)]` = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
error: transmute from a `&mut [u8]` to a `&mut 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) }; LL | let _: &mut str = unsafe { std::mem::transmute(mb) };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()` | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
error: transmute from a `&[u8]` to a `&str` 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) }; LL | const _: &str = unsafe { std::mem::transmute(B) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)` | ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`

View File

@ -1,5 +1,5 @@
#![warn(clippy::transmute_float_to_int)] #![warn(clippy::transmute_float_to_int)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]
#![feature(f128)] #![feature(f128)]
#![feature(f16)] #![feature(f16)]

View File

@ -1,5 +1,5 @@
#![warn(clippy::transmute_float_to_int)] #![warn(clippy::transmute_float_to_int)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]
#![feature(f128)] #![feature(f128)]
#![feature(f16)] #![feature(f16)]

View File

@ -1,5 +1,5 @@
#![warn(clippy::transmute_int_to_char)] #![warn(clippy::transmute_int_to_char)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]
fn int_to_char() { fn int_to_char() {
let _: char = unsafe { std::char::from_u32(0_u32).unwrap() }; let _: char = unsafe { std::char::from_u32(0_u32).unwrap() };

View File

@ -1,5 +1,5 @@
#![warn(clippy::transmute_int_to_char)] #![warn(clippy::transmute_int_to_char)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]
fn int_to_char() { fn int_to_char() {
let _: char = unsafe { std::mem::transmute(0_u32) }; let _: char = unsafe { std::mem::transmute(0_u32) };

View File

@ -1,7 +1,7 @@
#![no_std] #![no_std]
#![feature(lang_items)] #![feature(lang_items)]
#![warn(clippy::transmute_int_to_char)] #![warn(clippy::transmute_int_to_char)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]
use core::panic::PanicInfo; use core::panic::PanicInfo;

View File

@ -1,7 +1,7 @@
#![no_std] #![no_std]
#![feature(lang_items)] #![feature(lang_items)]
#![warn(clippy::transmute_int_to_char)] #![warn(clippy::transmute_int_to_char)]
#![allow(clippy::missing_transmute_annotations)] #![allow(clippy::missing_transmute_annotations, unnecessary_transmutes)]
use core::panic::PanicInfo; use core::panic::PanicInfo;

View File

@ -399,7 +399,6 @@ pub struct Config {
pub nocapture: bool, pub nocapture: bool,
// Needed both to construct build_helper::git::GitConfig // Needed both to construct build_helper::git::GitConfig
pub git_repository: String,
pub nightly_branch: String, pub nightly_branch: String,
pub git_merge_commit_email: String, pub git_merge_commit_email: String,
@ -514,7 +513,6 @@ impl Config {
pub fn git_config(&self) -> GitConfig<'_> { pub fn git_config(&self) -> GitConfig<'_> {
GitConfig { GitConfig {
git_repository: &self.git_repository,
nightly_branch: &self.nightly_branch, nightly_branch: &self.nightly_branch,
git_merge_commit_email: &self.git_merge_commit_email, git_merge_commit_email: &self.git_merge_commit_email,
} }

View File

@ -175,7 +175,6 @@ impl ConfigBuilder {
self.host.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), self.host.as_deref().unwrap_or("x86_64-unknown-linux-gnu"),
"--target", "--target",
self.target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"), self.target.as_deref().unwrap_or("x86_64-unknown-linux-gnu"),
"--git-repository=",
"--nightly-branch=", "--nightly-branch=",
"--git-merge-commit-email=", "--git-merge-commit-email=",
"--minicore-path=", "--minicore-path=",

View File

@ -188,7 +188,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
"run tests which rely on commit version being compiled into the binaries", "run tests which rely on commit version being compiled into the binaries",
) )
.optopt("", "edition", "default Rust edition", "EDITION") .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("", "nightly-branch", "name of the git branch for nightly", "BRANCH")
.reqopt( .reqopt(
"", "",
@ -440,7 +439,6 @@ pub fn parse_config(args: Vec<String>) -> Config {
nocapture: matches.opt_present("no-capture"), nocapture: matches.opt_present("no-capture"),
git_repository: matches.opt_str("git-repository").unwrap(),
nightly_branch: matches.opt_str("nightly-branch").unwrap(), nightly_branch: matches.opt_str("nightly-branch").unwrap(),
git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(), git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),

View File

@ -391,32 +391,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(res, dest)?; 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] #[rustfmt::skip]
| "fadd_fast" | "fadd_fast"
| "fsub_fast" | "fsub_fast"

View File

@ -1,3 +1,4 @@
#![allow(unnecessary_transmutes)]
fn main() { fn main() {
let _b = unsafe { std::mem::transmute::<u8, bool>(2) }; //~ ERROR: expected a boolean let _b = unsafe { std::mem::transmute::<u8, bool>(2) }; //~ ERROR: expected a boolean
} }

View File

@ -2,6 +2,7 @@
// Make sure we find these even with many checks disabled. // Make sure we find these even with many checks disabled.
//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation //@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation
#![allow(unnecessary_transmutes)]
fn main() { fn main() {
let b = unsafe { std::mem::transmute::<u8, bool>(2) }; let b = unsafe { std::mem::transmute::<u8, bool>(2) };
let _x = b == std::hint::black_box(true); //~ ERROR: interpreting an invalid 8-bit value as a bool let _x = b == std::hint::black_box(true); //~ ERROR: interpreting an invalid 8-bit value as a bool

View File

@ -1,3 +1,4 @@
#![allow(unnecessary_transmutes)]
fn main() { fn main() {
assert!(std::char::from_u32(-1_i32 as u32).is_none()); assert!(std::char::from_u32(-1_i32 as u32).is_none());
let _val = match unsafe { std::mem::transmute::<i32, char>(-1) } { let _val = match unsafe { std::mem::transmute::<i32, char>(-1) } {

View File

@ -2,6 +2,7 @@
// Make sure we find these even with many checks disabled. // Make sure we find these even with many checks disabled.
//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation //@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation
#![allow(unnecessary_transmutes)]
fn main() { fn main() {
let c = 0xFFFFFFu32; let c = 0xFFFFFFu32;
assert!(std::char::from_u32(c).is_none()); assert!(std::char::from_u32(c).is_none());

View File

@ -6,6 +6,7 @@
#![feature(f16)] #![feature(f16)]
#![allow(arithmetic_overflow)] #![allow(arithmetic_overflow)]
#![allow(internal_features)] #![allow(internal_features)]
#![allow(unnecessary_transmutes)]
use std::any::type_name; use std::any::type_name;
use std::cmp::min; use std::cmp::min;

View File

@ -1,3 +1,4 @@
#![allow(unnecessary_transmutes)]
pub fn main() { pub fn main() {
let bytes: [u8; 8] = unsafe { ::std::mem::transmute(0u64) }; let bytes: [u8; 8] = unsafe { ::std::mem::transmute(0u64) };
let _val: &[u8] = &bytes; let _val: &[u8] = &bytes;

View File

@ -368,7 +368,7 @@ unsafe fn load_m256i_word<T>(data: &[T], word_index: usize) -> __m256i {
#[target_feature(enable = "avx512f")] #[target_feature(enable = "avx512f")]
unsafe fn load_m512i_word<T>(data: &[T], word_index: usize) -> __m512i { unsafe fn load_m512i_word<T>(data: &[T], word_index: usize) -> __m512i {
let byte_offset = word_index * 64 / size_of::<T>(); let byte_offset = word_index * 64 / size_of::<T>();
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)) _mm512_loadu_si512(black_box(pointer))
} }

View File

@ -1,5 +1,6 @@
// We're testing x86 target specific features // We're testing x86 target specific features
//@only-target: x86_64 i686 //@only-target: x86_64 i686
#![allow(unnecessary_transmutes)]
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
use std::arch::x86::*; use std::arch::x86::*;

View File

@ -6,7 +6,6 @@ use suggest_tests::get_suggestions;
fn main() -> ExitCode { fn main() -> ExitCode {
let modified_files = get_git_modified_files( let modified_files = get_git_modified_files(
&GitConfig { &GitConfig {
git_repository: &env("SUGGEST_TESTS_GIT_REPOSITORY"),
nightly_branch: &env("SUGGEST_TESTS_NIGHTLY_BRANCH"), nightly_branch: &env("SUGGEST_TESTS_NIGHTLY_BRANCH"),
git_merge_commit_email: &env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL"), git_merge_commit_email: &env("SUGGEST_TESTS_MERGE_COMMIT_EMAIL"),
}, },

View File

@ -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);
}

View File

@ -2,7 +2,7 @@
//@ ignore-endian-big //@ ignore-endian-big
// ignore-tidy-linelength // ignore-tidy-linelength
//@ normalize-stderr: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼" -> "╾ALLOC_ID$1╼" //@ normalize-stderr: "╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼" -> "╾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)] #![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)]
use std::mem; use std::mem;

View File

@ -1,3 +1,4 @@
#![allow(unnecessary_transmutes)]
use std::mem; use std::mem;
fn main() { fn main() {

View File

@ -1,5 +1,5 @@
error[E0716]: temporary value dropped while borrowed 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) }; LL | let x: &'static u32 = unsafe { &mem::transmute(3.0f32) };
| ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use

View File

@ -1,3 +1,4 @@
#![allow(unnecessary_transmutes)]
use std::mem; use std::mem;
static FOO: bool = unsafe { mem::transmute(3u8) }; static FOO: bool = unsafe { mem::transmute(3u8) };

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value 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) }; LL | static FOO: bool = unsafe { mem::transmute(3u8) };
| ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean

View File

@ -3,7 +3,7 @@
//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
//@ normalize-stderr: "0x0+" -> "0x0" //@ normalize-stderr: "0x0+" -> "0x0"
#![feature(never_type)] #![feature(never_type)]
#![allow(invalid_value)] #![allow(invalid_value, unnecessary_transmutes)]
use std::mem; use std::mem;

View File

@ -1,5 +1,5 @@
// ignore-tidy-linelength // ignore-tidy-linelength
#![allow(unused)] #![allow(unused, unnecessary_transmutes)]
#![feature(ptr_metadata)] #![feature(ptr_metadata)]
use std::{ptr, mem}; use std::{ptr, mem};

View File

@ -2,6 +2,7 @@
//@ [no_flag] check-pass //@ [no_flag] check-pass
//@ [with_flag] compile-flags: -Zextra-const-ub-checks //@ [with_flag] compile-flags: -Zextra-const-ub-checks
#![feature(never_type)] #![feature(never_type)]
#![allow(unnecessary_transmutes)]
use std::mem::transmute; use std::mem::transmute;
use std::ptr::addr_of; use std::ptr::addr_of;

View File

@ -1,11 +1,11 @@
error[E0080]: evaluation of constant value failed 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); LL | let _x: bool = transmute(3u8);
| ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean | ^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
error[E0080]: evaluation of constant value failed 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); LL | let _x: usize = transmute(&3u8);
| ^^^^^^^^^^^^^^^ constructing invalid value: encountered a pointer, but expected an integer | ^^^^^^^^^^^^^^^ 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 = 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 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); LL | let _x: PtrSizedEnum = transmute(&3u8);
| ^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered a pointer, but expected an integer | ^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: 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 = 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 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); LL | let _x: (usize, usize) = transmute(x);
| ^^^^^^^^^^^^ constructing invalid value at .0: encountered a pointer, but expected an integer | ^^^^^^^^^^^^ 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 = 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 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]); LL | let _x: &u32 = transmute(&[0u8; 4]);
| ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1) | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 4 byte alignment but found 1)
error[E0080]: evaluation of constant value failed 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::<UninhDiscriminant>(); LL | let v = *addr_of!(data).cast::<UninhDiscriminant>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered an uninhabited enum variant
error[E0080]: evaluation of constant value failed 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]); 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 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 = 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 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; LL | let _val = &*slice;
| ^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object | ^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object

View File

@ -1,8 +1,8 @@
//@ run-pass //@ run-pass
const fn make_nans() -> (f64, f64, f32, f32) { const fn make_nans() -> (f64, f64, f32, f32) {
let nan1: f64 = unsafe { std::mem::transmute(0x7FF0_0001_0000_0001u64) }; let nan1 = f64::from_bits(0x7FF0_0001_0000_0001);
let nan2: f64 = unsafe { std::mem::transmute(0x7FF0_0000_0000_0001u64) }; let nan2 = f64::from_bits(0x7FF0_0000_0000_0001);
let nan1_32 = nan1 as f32; let nan1_32 = nan1 as f32;
let nan2_32 = nan2 as f32; let nan2_32 = nan2 as f32;

View File

@ -1,4 +1,5 @@
//@ run-pass //@ run-pass
#![allow(unnecessary_transmutes)]
use std::mem::transmute; use std::mem::transmute;
fn main() { fn main() {

View File

@ -1,8 +1,8 @@
// check-fail // check-fail
// run-rustfix // run-rustfix
#![allow(unnecessary_transmutes)]
use std::ptr; use std::{mem, ptr};
use std::mem;
unsafe fn null_ptr() { unsafe fn null_ptr() {
ptr::write( ptr::write(
@ -41,7 +41,7 @@ unsafe fn null_ptr() {
//~^ 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::NonNull::dangling().as_ptr(),
ptr::null_mut(), ptr::null_mut(),
0 0,
); );
#[derive(Copy, Clone)] #[derive(Copy, Clone)]

View File

@ -117,7 +117,7 @@ LL | |
LL | | ptr::NonNull::dangling().as_ptr(), LL | | ptr::NonNull::dangling().as_ptr(),
LL | | ptr::null_mut(), LL | | ptr::null_mut(),
| | --------------- null pointer originates from here | | --------------- null pointer originates from here
LL | | 0 LL | | 0,
LL | | ); LL | | );
| |_____^ | |_____^
| |

View File

@ -2,6 +2,8 @@
#![deny(improper_ctypes)] #![deny(improper_ctypes)]
#![feature(ptr_internals)] #![feature(ptr_internals)]
#![feature(transparent_unions)] #![feature(transparent_unions)]
#![feature(repr128)]
#![allow(incomplete_features)]
use std::num; use std::num;
@ -40,6 +42,20 @@ enum Isize {
C, C,
} }
#[repr(u128)]
enum U128 {
A,
B,
C,
}
#[repr(i128)]
enum I128 {
A,
B,
C,
}
#[repr(transparent)] #[repr(transparent)]
struct TransparentStruct<T>(T, std::marker::PhantomData<Z>); struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
@ -71,6 +87,8 @@ extern "C" {
fn repr_c(x: ReprC); fn repr_c(x: ReprC);
fn repr_u8(x: U8); fn repr_u8(x: U8);
fn repr_isize(x: Isize); 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_ref(x: Option<&'static u8>);
fn option_fn(x: Option<extern "C" fn()>); fn option_fn(x: Option<extern "C" fn()>);
fn option_nonnull(x: Option<std::ptr::NonNull<u8>>); fn option_nonnull(x: Option<std::ptr::NonNull<u8>>);

View File

@ -1,5 +1,5 @@
error: `extern` block uses type `U`, which is not FFI-safe 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); LL | fn uf(x: U);
| ^ not FFI-safe | ^ 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 = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint = note: enum has no representation hint
note: the type is defined here note: the type is defined here
--> $DIR/lint-ctypes-enum.rs:9:1 --> $DIR/lint-ctypes-enum.rs:11:1
| |
LL | enum U { LL | enum U {
| ^^^^^^ | ^^^^^^
@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: `extern` block uses type `B`, which is not FFI-safe 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); LL | fn bf(x: B);
| ^ not FFI-safe | ^ 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 = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint = note: enum has no representation hint
note: the type is defined here note: the type is defined here
--> $DIR/lint-ctypes-enum.rs:12:1 --> $DIR/lint-ctypes-enum.rs:14:1
| |
LL | enum B { LL | enum B {
| ^^^^^^ | ^^^^^^
error: `extern` block uses type `T`, which is not FFI-safe 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); LL | fn tf(x: T);
| ^ not FFI-safe | ^ 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 = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint = note: enum has no representation hint
note: the type is defined here note: the type is defined here
--> $DIR/lint-ctypes-enum.rs:16:1 --> $DIR/lint-ctypes-enum.rs:18:1
| |
LL | enum T { 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 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<num::NonZero<u128>>); LL | fn option_nonzero_u128(x: Option<num::NonZero<u128>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -54,7 +80,7 @@ LL | fn option_nonzero_u128(x: Option<num::NonZero<u128>>);
= note: 128-bit integers don't currently have a known stable ABI = note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `i128`, which is not FFI-safe 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<num::NonZero<i128>>); LL | fn option_nonzero_i128(x: Option<num::NonZero<i128>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -62,7 +88,7 @@ LL | fn option_nonzero_i128(x: Option<num::NonZero<i128>>);
= note: 128-bit integers don't currently have a known stable ABI = note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, which is not FFI-safe error: `extern` block uses type `Option<TransparentUnion<NonZero<u8>>>`, 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<TransparentUnion<num::NonZero<u8>>>); LL | fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -71,7 +97,7 @@ LL | fn option_transparent_union(x: Option<TransparentUnion<num::NonZero<u8>
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, which is not FFI-safe error: `extern` block uses type `Option<Rust<NonZero<u8>>>`, 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<Rust<num::NonZero<u8>>>); LL | fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -80,7 +106,7 @@ LL | fn option_repr_rust(x: Option<Rust<num::NonZero<u8>>>);
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Option<u8>`, which is not FFI-safe error: `extern` block uses type `Option<u8>`, 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<u8>); LL | fn option_u8(x: Option<u8>);
| ^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^ not FFI-safe
@ -89,7 +115,7 @@ LL | fn option_u8(x: Option<u8>);
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `u128`, which is not FFI-safe 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<num::NonZero<u128>, ()>); LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -97,7 +123,7 @@ LL | fn result_nonzero_u128_t(x: Result<num::NonZero<u128>, ()>);
= note: 128-bit integers don't currently have a known stable ABI = note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `i128`, which is not FFI-safe 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<num::NonZero<i128>, ()>); LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -105,7 +131,7 @@ LL | fn result_nonzero_i128_t(x: Result<num::NonZero<i128>, ()>);
= note: 128-bit integers don't currently have a known stable ABI = note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `Result<TransparentUnion<NonZero<u8>>, ()>`, which is not FFI-safe error: `extern` block uses type `Result<TransparentUnion<NonZero<u8>>, ()>`, 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<TransparentUnion<num::NonZero<u8>>, ()>); LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u8>>, ()>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -114,7 +140,7 @@ LL | fn result_transparent_union_t(x: Result<TransparentUnion<num::NonZero<u
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<Rust<NonZero<u8>>, ()>`, which is not FFI-safe error: `extern` block uses type `Result<Rust<NonZero<u8>>, ()>`, 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<Rust<num::NonZero<u8>>, ()>); LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -123,7 +149,7 @@ LL | fn result_repr_rust_t(x: Result<Rust<num::NonZero<u8>>, ()>);
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<NonZero<u8>, U>`, which is not FFI-safe error: `extern` block uses type `Result<NonZero<u8>, 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<num::NonZero<u8>, U>); LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>, U>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -132,7 +158,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result<num::NonZero<u8>,
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<NonZero<u8>, B>`, which is not FFI-safe error: `extern` block uses type `Result<NonZero<u8>, 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<num::NonZero<u8>, B>); LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>, B>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -141,7 +167,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result<num::NonZero<u8>
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<NonZero<u8>, NonExhaustive>`, which is not FFI-safe error: `extern` block uses type `Result<NonZero<u8>, 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<num::NonZero<u8>, NonExhaustive>); LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>, NonExhaustive>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -150,7 +176,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result<num::NonZero<u8>,
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<NonZero<u8>, Field>`, which is not FFI-safe error: `extern` block uses type `Result<NonZero<u8>, 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<num::NonZero<u8>, Field>); LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Field>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -159,7 +185,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result<num::NonZero<u8>, Fi
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, which is not FFI-safe error: `extern` block uses type `Result<Result<(), NonZero<u8>>, ()>`, 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<Result<(), num::NonZero<u8>>, ()>); LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -168,7 +194,7 @@ LL | fn result_cascading_t(x: Result<Result<(), num::NonZero<u8>>, ()>);
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `u128`, which is not FFI-safe 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<u128>>); LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -176,7 +202,7 @@ LL | fn result_nonzero_u128_e(x: Result<(), num::NonZero<u128>>);
= note: 128-bit integers don't currently have a known stable ABI = note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `i128`, which is not FFI-safe 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<i128>>); LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -184,7 +210,7 @@ LL | fn result_nonzero_i128_e(x: Result<(), num::NonZero<i128>>);
= note: 128-bit integers don't currently have a known stable ABI = note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, which is not FFI-safe error: `extern` block uses type `Result<(), TransparentUnion<NonZero<u8>>>`, 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<num::NonZero<u8>>>); LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZero<u8>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -193,7 +219,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion<num::NonZe
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, which is not FFI-safe error: `extern` block uses type `Result<(), Rust<NonZero<u8>>>`, 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<num::NonZero<u8>>>); LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -202,7 +228,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust<num::NonZero<u8>>>);
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<U, NonZero<u8>>`, which is not FFI-safe error: `extern` block uses type `Result<U, NonZero<u8>>`, 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<U, num::NonZero<u8>>); LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -211,7 +237,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result<U, num::NonZero<u8
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<B, NonZero<u8>>`, which is not FFI-safe error: `extern` block uses type `Result<B, NonZero<u8>>`, 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<B, num::NonZero<u8>>); LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<u8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -220,7 +246,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result<B, num::NonZero<
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, which is not FFI-safe error: `extern` block uses type `Result<NonExhaustive, NonZero<u8>>`, 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<NonExhaustive, num::NonZero<u8>>); LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num::NonZero<u8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -229,7 +255,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result<NonExhaustive, num
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<Field, NonZero<u8>>`, which is not FFI-safe error: `extern` block uses type `Result<Field, NonZero<u8>>`, 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<Field, num::NonZero<u8>>); LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<u8>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -238,7 +264,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result<Field, num::NonZero<
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, which is not FFI-safe error: `extern` block uses type `Result<(), Result<(), NonZero<u8>>>`, 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<u8>>>); LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -247,7 +273,7 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero<u8>>>);
= note: enum has no representation hint = note: enum has no representation hint
error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe 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<(), ()>); LL | fn result_unit_t_e(x: Result<(), ()>);
| ^^^^^^^^^^^^^^ not FFI-safe | ^^^^^^^^^^^^^^ 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 = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint = note: enum has no representation hint
error: aborting due to 27 previous errors error: aborting due to 29 previous errors

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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