Auto merge of #102265 - fee1-dead-contrib:rollup-a7fccbg, r=fee1-dead

Rollup of 8 pull requests

Successful merges:

 - #98111 (Clarify `[T]::select_nth_unstable*` return values)
 - #101431 (Look at move place's type when suggesting mutable reborrow)
 - #101800 (Constify slice.split_at_mut(_unchecked))
 - #101997 (Remove support for legacy PM)
 - #102194 (Note the type when unable to drop values in compile time)
 - #102200 (Constify Default impl's for Arrays and Tuples.)
 - #102245 (Constify cmp_min_max_by.)
 - #102259 (Type-annotate and simplify documentation of Option::unwrap_or_default)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-09-25 14:28:04 +00:00
commit 17e8752aca
63 changed files with 315 additions and 862 deletions

View File

@ -3263,7 +3263,6 @@ dependencies = [
"bitflags",
"cstr",
"libc",
"libloading",
"measureme",
"object 0.29.0",
"rustc-demangle",

View File

@ -198,7 +198,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
move_span,
move_spans,
*moved_place,
Some(used_place),
partially_str,
loop_message,
move_msg,

View File

@ -972,7 +972,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
move_span: Span,
move_spans: UseSpans<'tcx>,
moved_place: Place<'tcx>,
used_place: Option<PlaceRef<'tcx>>,
partially_str: &str,
loop_message: &str,
move_msg: &str,
@ -1060,9 +1059,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
place_name, partially_str, loop_message
),
);
// If we have a `&mut` ref, we need to reborrow.
if let Some(ty::Ref(_, _, hir::Mutability::Mut)) = used_place
.map(|used_place| used_place.ty(self.body, self.infcx.tcx).ty.kind())
// If the moved place was a `&mut` ref, then we can
// suggest to reborrow it where it was moved, so it
// will still be valid by the time we get to the usage.
if let ty::Ref(_, _, hir::Mutability::Mut) =
moved_place.ty(self.body, self.infcx.tcx).ty.kind()
{
// If we are in a loop this will be suggested later.
if !is_loop_move {

View File

@ -401,7 +401,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
if let Some(use_spans) = use_spans {
self.explain_captures(
&mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
&mut err, span, span, use_spans, move_place, "", "", "", false, true,
);
}
err

View File

@ -11,7 +11,6 @@ doctest = false
bitflags = "1.0"
cstr = "0.2"
libc = "0.2"
libloading = "0.7.1"
measureme = "10.0.0"
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "archive", "coff", "elf", "macho", "pe"] }
tracing = "0.1"

View File

@ -1,8 +1,6 @@
use crate::back::write::{
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
};
use crate::llvm::{self, build_string, False, True};
use crate::{llvm_util, LlvmCodegenBackend, ModuleLlvm};
use crate::back::write::{self, save_temp_bitcode, DiagnosticHandlers};
use crate::llvm::{self, build_string};
use crate::{LlvmCodegenBackend, ModuleLlvm};
use object::read::archive::ArchiveFile;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::symbol_export;
@ -597,61 +595,9 @@ pub(crate) fn run_pass_manager(
1,
);
}
if llvm_util::should_use_new_llvm_pass_manager(
&config.new_llvm_pass_manager,
&cgcx.target_arch,
) {
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
write::optimize_with_new_llvm_pass_manager(
cgcx,
diag_handler,
module,
config,
opt_level,
opt_stage,
)?;
debug!("lto done");
return Ok(());
}
let pm = llvm::LLVMCreatePassManager();
llvm::LLVMAddAnalysisPasses(module.module_llvm.tm, pm);
if config.verify_llvm_ir {
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr().cast());
llvm::LLVMRustAddPass(pm, pass.unwrap());
}
let opt_level = config
.opt_level
.map(|x| to_llvm_opt_settings(x).0)
.unwrap_or(llvm::CodeGenOptLevel::None);
with_llvm_pmb(module.module_llvm.llmod(), config, opt_level, false, &mut |b| {
if thin {
llvm::LLVMRustPassManagerBuilderPopulateThinLTOPassManager(b, pm);
} else {
llvm::LLVMRustPassManagerBuilderPopulateLTOPassManager(
b, pm, /* Internalize = */ False, /* RunInliner = */ True,
);
}
});
// We always generate bitcode through ThinLTOBuffers,
// which do not support anonymous globals
if config.bitcode_needed() {
let pass = llvm::LLVMRustFindAndCreatePass("name-anon-globals\0".as_ptr().cast());
llvm::LLVMRustAddPass(pm, pass.unwrap());
}
if config.verify_llvm_ir {
let pass = llvm::LLVMRustFindAndCreatePass("verify\0".as_ptr().cast());
llvm::LLVMRustAddPass(pm, pass.unwrap());
}
llvm::LLVMRunPassManager(pm, module.module_llvm.llmod());
llvm::LLVMDisposePassManager(pm);
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
write::llvm_optimize(cgcx, diag_handler, module, config, opt_level, opt_stage)?;
}
debug!("lto done");
Ok(())

View File

@ -21,7 +21,6 @@ use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_errors::{FatalError, Handler, Level};
use rustc_fs_util::{link_or_copy, path_to_c_string};
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
use rustc_session::Session;
@ -417,7 +416,7 @@ fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
}
}
pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
pub(crate) unsafe fn llvm_optimize(
cgcx: &CodegenContext<LlvmCodegenBackend>,
diag_handler: &Handler,
module: &ModuleCodegen<ModuleLlvm>,
@ -465,7 +464,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
// FIXME: NewPM doesn't provide a facility to pass custom InlineParams.
// We would have to add upstream support for this first, before we can support
// config.inline_threshold and our more aggressive default thresholds.
let result = llvm::LLVMRustOptimizeWithNewPassManager(
let result = llvm::LLVMRustOptimize(
module.module_llvm.llmod(),
&*module.module_llvm.tm,
to_pass_builder_opt_level(opt_level),
@ -509,18 +508,11 @@ pub(crate) unsafe fn optimize(
let llmod = module.module_llvm.llmod();
let llcx = &*module.module_llvm.llcx;
let tm = &*module.module_llvm.tm;
let _handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
let module_name = module.name.clone();
let module_name = Some(&module_name[..]);
if let Some(false) = config.new_llvm_pass_manager && llvm_util::get_version() >= (15, 0, 0) {
diag_handler.warn(
"ignoring `-Z new-llvm-pass-manager=no`, which is no longer supported with LLVM 15",
);
}
if config.emit_no_opt_bc {
let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
let out = path_to_c_string(&out);
@ -528,184 +520,17 @@ pub(crate) unsafe fn optimize(
}
if let Some(opt_level) = config.opt_level {
if llvm_util::should_use_new_llvm_pass_manager(
&config.new_llvm_pass_manager,
&cgcx.target_arch,
) {
let opt_stage = match cgcx.lto {
Lto::Fat => llvm::OptStage::PreLinkFatLTO,
Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
_ => llvm::OptStage::PreLinkNoLTO,
};
return optimize_with_new_llvm_pass_manager(
cgcx,
diag_handler,
module,
config,
opt_level,
opt_stage,
);
}
if cgcx.prof.llvm_recording_enabled() {
diag_handler
.warn("`-Z self-profile-events = llvm` requires `-Z new-llvm-pass-manager`");
}
// Create the two optimizing pass managers. These mirror what clang
// does, and are by populated by LLVM's default PassManagerBuilder.
// Each manager has a different set of passes, but they also share
// some common passes.
let fpm = llvm::LLVMCreateFunctionPassManagerForModule(llmod);
let mpm = llvm::LLVMCreatePassManager();
{
let find_pass = |pass_name: &str| {
let pass_name = SmallCStr::new(pass_name);
llvm::LLVMRustFindAndCreatePass(pass_name.as_ptr())
};
if config.verify_llvm_ir {
// Verification should run as the very first pass.
llvm::LLVMRustAddPass(fpm, find_pass("verify").unwrap());
}
let mut extra_passes = Vec::new();
let mut have_name_anon_globals_pass = false;
for pass_name in &config.passes {
if pass_name == "lint" {
// Linting should also be performed early, directly on the generated IR.
llvm::LLVMRustAddPass(fpm, find_pass("lint").unwrap());
continue;
}
if let Some(pass) = find_pass(pass_name) {
extra_passes.push(pass);
} else {
diag_handler.warn(&format!("unknown pass `{}`, ignoring", pass_name));
}
if pass_name == "name-anon-globals" {
have_name_anon_globals_pass = true;
}
}
// Instrumentation must be inserted before optimization,
// otherwise LLVM may optimize some functions away which
// breaks llvm-cov.
//
// This mirrors what Clang does in lib/CodeGen/BackendUtil.cpp.
if config.instrument_gcov {
llvm::LLVMRustAddPass(mpm, find_pass("insert-gcov-profiling").unwrap());
}
if config.instrument_coverage {
llvm::LLVMRustAddPass(mpm, find_pass("instrprof").unwrap());
}
if config.debug_info_for_profiling {
llvm::LLVMRustAddPass(mpm, find_pass("add-discriminators").unwrap());
}
add_sanitizer_passes(config, &mut extra_passes);
// Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
// to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise
// we'll get errors in LLVM.
let using_thin_buffers = config.bitcode_needed();
if !config.no_prepopulate_passes {
llvm::LLVMAddAnalysisPasses(tm, fpm);
llvm::LLVMAddAnalysisPasses(tm, mpm);
let opt_level = to_llvm_opt_settings(opt_level).0;
let prepare_for_thin_lto = cgcx.lto == Lto::Thin
|| cgcx.lto == Lto::ThinLocal
|| (cgcx.lto != Lto::Fat && cgcx.opts.cg.linker_plugin_lto.enabled());
with_llvm_pmb(llmod, config, opt_level, prepare_for_thin_lto, &mut |b| {
llvm::LLVMRustAddLastExtensionPasses(
b,
extra_passes.as_ptr(),
extra_passes.len() as size_t,
);
llvm::LLVMRustPassManagerBuilderPopulateFunctionPassManager(b, fpm);
llvm::LLVMRustPassManagerBuilderPopulateModulePassManager(b, mpm);
});
have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
if using_thin_buffers && !prepare_for_thin_lto {
llvm::LLVMRustAddPass(mpm, find_pass("name-anon-globals").unwrap());
have_name_anon_globals_pass = true;
}
} else {
// If we don't use the standard pipeline, directly populate the MPM
// with the extra passes.
for pass in extra_passes {
llvm::LLVMRustAddPass(mpm, pass);
}
}
if using_thin_buffers && !have_name_anon_globals_pass {
// As described above, this will probably cause an error in LLVM
if config.no_prepopulate_passes {
diag_handler.err(
"The current compilation is going to use thin LTO buffers \
without running LLVM's NameAnonGlobals pass. \
This will likely cause errors in LLVM. Consider adding \
-C passes=name-anon-globals to the compiler command line.",
);
} else {
bug!(
"We are using thin LTO buffers without running the NameAnonGlobals pass. \
This will likely cause errors in LLVM and should never happen."
);
}
}
}
diag_handler.abort_if_errors();
// Finally, run the actual optimization passes
{
let _timer = cgcx.prof.extra_verbose_generic_activity(
"LLVM_module_optimize_function_passes",
&*module.name,
);
llvm::LLVMRustRunFunctionPassManager(fpm, llmod);
}
{
let _timer = cgcx.prof.extra_verbose_generic_activity(
"LLVM_module_optimize_module_passes",
&*module.name,
);
llvm::LLVMRunPassManager(mpm, llmod);
}
// Deallocate managers that we're now done with
llvm::LLVMDisposePassManager(fpm);
llvm::LLVMDisposePassManager(mpm);
let opt_stage = match cgcx.lto {
Lto::Fat => llvm::OptStage::PreLinkFatLTO,
Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
_ => llvm::OptStage::PreLinkNoLTO,
};
return llvm_optimize(cgcx, diag_handler, module, config, opt_level, opt_stage);
}
Ok(())
}
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {
if config.sanitizer.contains(SanitizerSet::ADDRESS) {
let recover = config.sanitizer_recover.contains(SanitizerSet::ADDRESS);
passes.push(llvm::LLVMRustCreateAddressSanitizerFunctionPass(recover));
passes.push(llvm::LLVMRustCreateModuleAddressSanitizerPass(recover));
}
if config.sanitizer.contains(SanitizerSet::MEMORY) {
let track_origins = config.sanitizer_memory_track_origins as c_int;
let recover = config.sanitizer_recover.contains(SanitizerSet::MEMORY);
passes.push(llvm::LLVMRustCreateMemorySanitizerPass(track_origins, recover));
}
if config.sanitizer.contains(SanitizerSet::THREAD) {
passes.push(llvm::LLVMRustCreateThreadSanitizerPass());
}
if config.sanitizer.contains(SanitizerSet::HWADDRESS) {
let recover = config.sanitizer_recover.contains(SanitizerSet::HWADDRESS);
passes.push(llvm::LLVMRustCreateHWAddressSanitizerPass(recover));
}
}
pub(crate) fn link(
cgcx: &CodegenContext<LlvmCodegenBackend>,
diag_handler: &Handler,
@ -1072,72 +897,6 @@ unsafe fn embed_bitcode(
}
}
pub unsafe fn with_llvm_pmb(
llmod: &llvm::Module,
config: &ModuleConfig,
opt_level: llvm::CodeGenOptLevel,
prepare_for_thin_lto: bool,
f: &mut dyn FnMut(&llvm::PassManagerBuilder),
) {
use std::ptr;
// Create the PassManagerBuilder for LLVM. We configure it with
// reasonable defaults and prepare it to actually populate the pass
// manager.
let builder = llvm::LLVMRustPassManagerBuilderCreate();
let opt_size = config.opt_size.map_or(llvm::CodeGenOptSizeNone, |x| to_llvm_opt_settings(x).1);
let inline_threshold = config.inline_threshold;
let pgo_gen_path = get_pgo_gen_path(config);
let pgo_use_path = get_pgo_use_path(config);
let pgo_sample_use_path = get_pgo_sample_use_path(config);
llvm::LLVMRustConfigurePassManagerBuilder(
builder,
opt_level,
config.merge_functions,
config.vectorize_slp,
config.vectorize_loop,
prepare_for_thin_lto,
pgo_gen_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
pgo_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
pgo_sample_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
opt_size as c_int,
);
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins);
// Here we match what clang does (kinda). For O0 we only inline
// always-inline functions (but don't add lifetime intrinsics), at O1 we
// inline with lifetime intrinsics, and O2+ we add an inliner with a
// thresholds copied from clang.
match (opt_level, opt_size, inline_threshold) {
(.., Some(t)) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, t);
}
(llvm::CodeGenOptLevel::Aggressive, ..) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 275);
}
(_, llvm::CodeGenOptSizeDefault, _) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 75);
}
(_, llvm::CodeGenOptSizeAggressive, _) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 25);
}
(llvm::CodeGenOptLevel::None, ..) => {
llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers);
}
(llvm::CodeGenOptLevel::Less, ..) => {
llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers);
}
(llvm::CodeGenOptLevel::Default, ..) => {
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 225);
}
}
f(builder);
llvm::LLVMRustPassManagerBuilderDispose(builder);
}
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.
// This is required to satisfy `dllimport` references to static data in .rlibs
// when using MSVC linker. We do this only for data, as linker can fix up

View File

@ -1792,18 +1792,9 @@ extern "C" {
/// Writes a module to the specified path. Returns 0 on success.
pub fn LLVMWriteBitcodeToFile(M: &Module, Path: *const c_char) -> c_int;
/// Creates a pass manager.
/// Creates a legacy pass manager -- only used for final codegen.
pub fn LLVMCreatePassManager<'a>() -> &'a mut PassManager<'a>;
/// Creates a function-by-function pass manager
pub fn LLVMCreateFunctionPassManagerForModule(M: &Module) -> &mut PassManager<'_>;
/// Disposes a pass manager.
pub fn LLVMDisposePassManager<'a>(PM: &'a mut PassManager<'a>);
/// Runs a pass manager on a module.
pub fn LLVMRunPassManager<'a>(PM: &PassManager<'a>, M: &'a Module) -> Bool;
pub fn LLVMInitializePasses();
pub fn LLVMTimeTraceProfilerInitialize();
@ -1814,32 +1805,6 @@ extern "C" {
pub fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>);
pub fn LLVMRustPassManagerBuilderCreate() -> &'static mut PassManagerBuilder;
pub fn LLVMRustPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder);
pub fn LLVMRustPassManagerBuilderUseInlinerWithThreshold(
PMB: &PassManagerBuilder,
threshold: c_uint,
);
pub fn LLVMRustPassManagerBuilderPopulateModulePassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMRustPassManagerBuilderPopulateFunctionPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMRustPassManagerBuilderPopulateLTOPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
Internalize: Bool,
RunInliner: Bool,
);
pub fn LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMGetHostCPUFeatures() -> *mut c_char;
pub fn LLVMDisposeMessage(message: *mut c_char);
@ -2244,22 +2209,6 @@ extern "C" {
pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
pub fn LLVMRustCreateAddressSanitizerFunctionPass(Recover: bool) -> &'static mut Pass;
pub fn LLVMRustCreateModuleAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
pub fn LLVMRustCreateMemorySanitizerPass(
TrackOrigins: c_int,
Recover: bool,
) -> &'static mut Pass;
pub fn LLVMRustCreateThreadSanitizerPass() -> &'static mut Pass;
pub fn LLVMRustCreateHWAddressSanitizerPass(Recover: bool) -> &'static mut Pass;
pub fn LLVMRustAddPass(PM: &PassManager<'_>, Pass: &'static mut Pass);
pub fn LLVMRustAddLastExtensionPasses(
PMB: &PassManagerBuilder,
Passes: *const &'static mut Pass,
NumPasses: size_t,
);
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine);
@ -2293,29 +2242,11 @@ extern "C" {
SplitDwarfFile: *const c_char,
) -> Option<&'static mut TargetMachine>;
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
pub fn LLVMRustAddBuilderLibraryInfo<'a>(
PMB: &'a PassManagerBuilder,
M: &'a Module,
DisableSimplifyLibCalls: bool,
);
pub fn LLVMRustConfigurePassManagerBuilder(
PMB: &PassManagerBuilder,
OptLevel: CodeGenOptLevel,
MergeFunctions: bool,
SLPVectorize: bool,
LoopVectorize: bool,
PrepareForThinLTO: bool,
PGOGenPath: *const c_char,
PGOUsePath: *const c_char,
PGOSampleUsePath: *const c_char,
SizeLevel: c_int,
);
pub fn LLVMRustAddLibraryInfo<'a>(
PM: &PassManager<'a>,
M: &'a Module,
DisableSimplifyLibCalls: bool,
);
pub fn LLVMRustRunFunctionPassManager<'a>(PM: &PassManager<'a>, M: &'a Module);
pub fn LLVMRustWriteOutputFile<'a>(
T: &'a TargetMachine,
PM: &PassManager<'a>,
@ -2324,7 +2255,7 @@ extern "C" {
DwoOutput: *const c_char,
FileType: FileType,
) -> LLVMRustResult;
pub fn LLVMRustOptimizeWithNewPassManager<'a>(
pub fn LLVMRustOptimize<'a>(
M: &'a Module,
TM: &'a TargetMachine,
OptLevel: PassBuilderOptLevel,
@ -2362,7 +2293,6 @@ extern "C" {
pub fn LLVMRustSetLLVMOptions(Argc: c_int, Argv: *const *const c_char);
pub fn LLVMRustPrintPasses();
pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
pub fn LLVMRustAddAlwaysInlinePass(P: &PassManagerBuilder, AddLifetimes: bool);
pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;

View File

@ -1,7 +1,6 @@
use crate::back::write::create_informational_target_machine;
use crate::{llvm, llvm_util};
use crate::llvm;
use libc::c_int;
use libloading::Library;
use rustc_codegen_ssa::target_features::{
supported_target_features, tied_target_features, RUSTC_SPECIFIC_FEATURES,
};
@ -16,7 +15,6 @@ use rustc_target::spec::{MergeFunctions, PanicStrategy};
use smallvec::{smallvec, SmallVec};
use std::ffi::{CStr, CString};
use std::mem;
use std::path::Path;
use std::ptr;
use std::slice;
@ -120,22 +118,6 @@ unsafe fn configure_llvm(sess: &Session) {
llvm::LLVMInitializePasses();
// Use the legacy plugin registration if we don't use the new pass manager
if !should_use_new_llvm_pass_manager(
&sess.opts.unstable_opts.new_llvm_pass_manager,
&sess.target.arch,
) {
// Register LLVM plugins by loading them into the compiler process.
for plugin in &sess.opts.unstable_opts.llvm_plugins {
let lib = Library::new(plugin).unwrap_or_else(|e| bug!("couldn't load plugin: {}", e));
debug!("LLVM plugin loaded successfully {:?} ({})", lib, plugin);
// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long.
mem::forget(lib);
}
}
rustc_llvm::initialize_available_targets();
llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int, llvm_args.as_ptr());
@ -539,19 +521,3 @@ pub fn tune_cpu(sess: &Session) -> Option<&str> {
let name = sess.opts.unstable_opts.tune_cpu.as_ref()?;
Some(handle_native(name))
}
pub(crate) fn should_use_new_llvm_pass_manager(user_opt: &Option<bool>, target_arch: &str) -> bool {
// The new pass manager is enabled by default for LLVM >= 13.
// This matches Clang, which also enables it since Clang 13.
// Since LLVM 15, the legacy pass manager is no longer supported.
if llvm_util::get_version() >= (15, 0, 0) {
return true;
}
// There are some perf issues with the new pass manager when targeting
// s390x with LLVM 13, so enable the new pass manager only with LLVM 14.
// See https://github.com/rust-lang/rust/issues/89609.
let min_version = if target_arch == "s390x" { 14 } else { 13 };
user_opt.unwrap_or_else(|| llvm_util::get_version() >= (min_version, 0, 0))
}

View File

@ -113,7 +113,6 @@ pub struct ModuleConfig {
pub vectorize_slp: bool,
pub merge_functions: bool,
pub inline_threshold: Option<u32>,
pub new_llvm_pass_manager: Option<bool>,
pub emit_lifetime_markers: bool,
pub llvm_plugins: Vec<String>,
}
@ -265,7 +264,6 @@ impl ModuleConfig {
},
inline_threshold: sess.opts.cg.inline_threshold,
new_llvm_pass_manager: sess.opts.unstable_opts.new_llvm_pass_manager,
emit_lifetime_markers: sess.emit_lifetime_markers(),
llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]),
}

View File

@ -1009,7 +1009,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if needs_non_const_drop {
self.check_op_spanned(
ops::LiveDrop { dropped_at: Some(terminator.source_info.span) },
ops::LiveDrop {
dropped_at: Some(terminator.source_info.span),
dropped_ty: ty_of_dropped_place,
},
err_span,
);
}

View File

@ -422,10 +422,11 @@ impl<'tcx> NonConstOp<'tcx> for InlineAsm {
}
#[derive(Debug)]
pub struct LiveDrop {
pub struct LiveDrop<'tcx> {
pub dropped_at: Option<Span>,
pub dropped_ty: Ty<'tcx>,
}
impl<'tcx> NonConstOp<'tcx> for LiveDrop {
impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> {
fn build_error(
&self,
ccx: &ConstCx<'_, 'tcx>,
@ -435,9 +436,13 @@ impl<'tcx> NonConstOp<'tcx> for LiveDrop {
ccx.tcx.sess,
span,
E0493,
"destructors cannot be evaluated at compile-time"
"destructor of `{}` cannot be evaluated at compile-time",
self.dropped_ty,
);
err.span_label(
span,
format!("the destructor for this type cannot be evaluated in {}s", ccx.const_kind()),
);
err.span_label(span, format!("{}s cannot evaluate destructors", ccx.const_kind()));
if let Some(span) = self.dropped_at {
err.span_label(span, "value is dropped here");
}

View File

@ -1,6 +1,6 @@
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, BasicBlock, Location};
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_span::{symbol::sym, Span};
use super::check::Qualifs;
@ -58,9 +58,9 @@ impl<'mir, 'tcx> std::ops::Deref for CheckLiveDrops<'mir, 'tcx> {
}
}
impl CheckLiveDrops<'_, '_> {
fn check_live_drop(&self, span: Span) {
ops::LiveDrop { dropped_at: None }.build_error(self.ccx, span).emit();
impl<'tcx> CheckLiveDrops<'_, 'tcx> {
fn check_live_drop(&self, span: Span, dropped_ty: Ty<'tcx>) {
ops::LiveDrop { dropped_at: None, dropped_ty }.build_error(self.ccx, span).emit();
}
}
@ -90,7 +90,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
}
if dropped_place.is_indirect() {
self.check_live_drop(terminator.source_info.span);
self.check_live_drop(terminator.source_info.span, dropped_ty);
return;
}
@ -101,7 +101,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
if self.qualifs.needs_non_const_drop(self.ccx, dropped_place.local, location) {
// Use the span where the dropped local was declared for the error.
let span = self.body.local_decls[dropped_place.local].source_info.span;
self.check_live_drop(span);
self.check_live_drop(span, dropped_ty);
}
}

View File

@ -758,7 +758,6 @@ fn test_unstable_options_tracking_hash() {
tracked!(mir_opt_level, Some(4));
tracked!(move_size_limit, Some(4096));
tracked!(mutable_noalias, Some(true));
tracked!(new_llvm_pass_manager, Some(true));
tracked!(no_generate_arange_section, true);
tracked!(no_link, true);
tracked!(no_unique_section_names, true);

View File

@ -31,13 +31,12 @@
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/FunctionImport.h"
#if LLVM_VERSION_GE(15, 0)
#include "llvm/Transforms/IPO/Internalize.h"
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#endif
#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm/Transforms/Instrumentation.h"
@ -93,172 +92,6 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
timeTraceProfilerCleanup();
}
extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
#if LLVM_VERSION_LT(15, 0)
StringRef SR(PassName);
PassRegistry *PR = PassRegistry::getPassRegistry();
const PassInfo *PI = PR->getPassInfo(SR);
if (PI) {
return wrap(PI->createPass());
}
return nullptr;
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
const bool UseAfterScope = true;
return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
return wrap(createMemorySanitizerLegacyPassPass(
#if LLVM_VERSION_GE(14, 0)
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel, /*EagerChecks=*/true}
#else
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}
#endif
));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
#if LLVM_VERSION_LT(15, 0)
return wrap(createThreadSanitizerLegacyPassPass());
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateHWAddressSanitizerPass(bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
return wrap(createHWAddressSanitizerLegacyPassPass(CompileKernel, Recover));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
#if LLVM_VERSION_LT(15, 0)
assert(RustPass);
Pass *Pass = unwrap(RustPass);
PassManagerBase *PMB = unwrap(PMR);
PMB->add(Pass);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassManagerBuilderRef LLVMRustPassManagerBuilderCreate() {
#if LLVM_VERSION_LT(15, 0)
return LLVMPassManagerBuilderCreate();
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderDispose(PMB);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderPopulateFunctionPassManager(
LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderPopulateFunctionPassManager(PMB, PM);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderPopulateModulePassManager(
LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderPopulateModulePassManager(PMB, PM);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderPopulateLTOPassManager(
LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM, bool Internalize, bool RunInliner) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderPopulateLTOPassManager(PMB, PM, Internalize, RunInliner);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C"
void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
LLVMPassManagerBuilderRef PMBR,
LLVMPassManagerRef PMR
) {
#if LLVM_VERSION_LT(15, 0)
unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderUseInlinerWithThreshold(
LLVMPassManagerBuilderRef PMB, unsigned Threshold) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderUseInlinerWithThreshold(PMB, Threshold);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C"
void LLVMRustAddLastExtensionPasses(
LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) {
#if LLVM_VERSION_LT(15, 0)
auto AddExtensionPasses = [Passes, NumPasses](
const PassManagerBuilder &Builder, PassManagerBase &PM) {
for (size_t I = 0; I < NumPasses; I++) {
PM.add(unwrap(Passes[I]));
}
};
// Add the passes to both of the pre-finalization extension points,
// so they are run for optimized and non-optimized builds.
unwrap(PMBR)->addExtension(PassManagerBuilder::EP_OptimizerLast,
AddExtensionPasses);
unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
AddExtensionPasses);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
#ifdef LLVM_COMPONENT_X86
#define SUBTARGET_X86 SUBTARGET(X86)
#else
@ -604,47 +437,6 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
delete unwrap(TM);
}
extern "C" void LLVMRustConfigurePassManagerBuilder(
LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
const char* PGOGenPath, const char* PGOUsePath, const char* PGOSampleUsePath,
int SizeLevel) {
#if LLVM_VERSION_LT(15, 0)
unwrap(PMBR)->MergeFunctions = MergeFunctions;
unwrap(PMBR)->SLPVectorize = SLPVectorize;
unwrap(PMBR)->OptLevel = fromRust(OptLevel);
unwrap(PMBR)->LoopVectorize = LoopVectorize;
unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
unwrap(PMBR)->SizeLevel = SizeLevel;
unwrap(PMBR)->DisableUnrollLoops = SizeLevel != 0;
if (PGOGenPath) {
assert(!PGOUsePath && !PGOSampleUsePath);
unwrap(PMBR)->EnablePGOInstrGen = true;
unwrap(PMBR)->PGOInstrGen = PGOGenPath;
} else if (PGOUsePath) {
assert(!PGOSampleUsePath);
unwrap(PMBR)->PGOInstrUse = PGOUsePath;
} else if (PGOSampleUsePath) {
unwrap(PMBR)->PGOSampleUse = PGOSampleUsePath;
}
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
// Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
// field of a PassManagerBuilder, we expose our own method of doing so.
extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
LLVMModuleRef M,
bool DisableSimplifyLibCalls) {
Triple TargetTriple(unwrap(M)->getTargetTriple());
TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
if (DisableSimplifyLibCalls)
TLI->disableAllFunctions();
unwrap(PMBR)->LibraryInfo = TLI;
}
// Unfortunately, the LLVM C API doesn't provide a way to create the
// TargetLibraryInfo pass, so we use this method to do so.
extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
@ -656,27 +448,6 @@ extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
}
// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
// all the functions in a module, so we do that manually here. You'll find
// similar code in clang's BackendUtil.cpp file.
extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
LLVMModuleRef M) {
llvm::legacy::FunctionPassManager *P =
unwrap<llvm::legacy::FunctionPassManager>(PMR);
P->doInitialization();
// Upgrade all calls to old intrinsics first.
for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
++I)
if (!I->isDeclaration())
P->run(*I);
P->doFinalization();
}
extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
// Initializing the command-line options more than once is not allowed. So,
// check if they've already been initialized. (This could happen if we're
@ -820,7 +591,7 @@ struct LLVMRustSanitizerOptions {
};
extern "C" LLVMRustResult
LLVMRustOptimizeWithNewPassManager(
LLVMRustOptimize(
LLVMModuleRef ModuleRef,
LLVMTargetMachineRef TMRef,
LLVMRustPassBuilderOptLevel OptLevelRust,
@ -1241,15 +1012,8 @@ extern "C" void LLVMRustPrintPasses() {
PR->enumerateWith(&Listener);
}
extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
bool AddLifetimes) {
unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
}
extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
size_t Len) {
llvm::legacy::PassManager passes;
auto PreserveFunctions = [=](const GlobalValue &GV) {
for (size_t I = 0; I < Len; I++) {
if (GV.getName() == Symbols[I]) {
@ -1259,9 +1023,7 @@ extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
return false;
};
passes.add(llvm::createInternalizePass(PreserveFunctions));
passes.run(*unwrap(M));
internalizeModule(*unwrap(M), PreserveFunctions);
}
extern "C" void
@ -1610,11 +1372,6 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
raw_string_ostream OS(Ret->data);
{
if (is_thin) {
#if LLVM_VERSION_LT(15, 0)
legacy::PassManager PM;
PM.add(createWriteThinLTOBitcodePass(OS));
PM.run(*unwrap(M));
#else
PassBuilder PB;
LoopAnalysisManager LAM;
FunctionAnalysisManager FAM;
@ -1628,11 +1385,8 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
ModulePassManager MPM;
MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
MPM.run(*unwrap(M), MAM);
#endif
} else {
legacy::PassManager PM;
PM.add(createBitcodeWriterPass(OS));
PM.run(*unwrap(M));
WriteBitcodeToFile(*unwrap(M), OS);
}
}
}

View File

@ -12,7 +12,7 @@
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Pass.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Support/Signals.h"
#include "llvm/ADT/Optional.h"
@ -1670,11 +1670,7 @@ LLVMRustModuleBufferCreate(LLVMModuleRef M) {
auto Ret = std::make_unique<LLVMRustModuleBuffer>();
{
raw_string_ostream OS(Ret->data);
{
legacy::PassManager PM;
PM.add(createBitcodeWriterPass(OS));
PM.run(*unwrap(M));
}
WriteBitcodeToFile(*unwrap(M), OS);
}
return Ret.release();
}

View File

@ -1409,8 +1409,6 @@ options! {
"the size at which the `large_assignments` lint starts to be emitted"),
mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
"emit noalias metadata for mutable references (default: yes)"),
new_llvm_pass_manager: Option<bool> = (None, parse_opt_bool, [TRACKED],
"use new LLVM pass manager (default: no)"),
nll_facts: bool = (false, parse_bool, [UNTRACKED],
"dump facts from NLL analysis into side files (default: no)"),
nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED],

View File

@ -434,7 +434,8 @@ impl<T: Copy> SpecArrayClone for T {
macro_rules! array_impl_default {
{$n:expr, $t:ident $($ts:ident)*} => {
#[stable(since = "1.4.0", feature = "array_default")]
impl<T> Default for [T; $n] where T: Default {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<T> const Default for [T; $n] where T: ~const Default {
fn default() -> [T; $n] {
[$t::default(), $($ts::default()),*]
}

View File

@ -22,6 +22,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::const_closure::ConstFnMutClosure;
use crate::marker::Destruct;
use crate::marker::StructuralPartialEq;
@ -1222,7 +1223,12 @@ pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
pub const fn min_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
where
T: ~const Destruct,
F: ~const Destruct,
{
match compare(&v1, &v2) {
Ordering::Less | Ordering::Equal => v1,
Ordering::Greater => v2,
@ -1244,8 +1250,24 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
pub const fn min_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T
where
T: ~const Destruct,
F: ~const Destruct,
K: ~const Destruct,
{
const fn imp<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(
f: &mut F,
(v1, v2): (&T, &T),
) -> Ordering
where
T: ~const Destruct,
K: ~const Destruct,
{
f(v1).cmp(&f(v2))
}
min_by(v1, v2, ConstFnMutClosure::new(&mut f, imp))
}
/// Compares and returns the maximum of two values.
@ -1286,7 +1308,12 @@ pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T {
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
pub const fn max_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T
where
T: ~const Destruct,
F: ~const Destruct,
{
match compare(&v1, &v2) {
Ordering::Less | Ordering::Equal => v2,
Ordering::Greater => v1,
@ -1308,8 +1335,24 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
#[inline]
#[must_use]
#[stable(feature = "cmp_min_max_by", since = "1.53.0")]
pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
pub const fn max_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T
where
T: ~const Destruct,
F: ~const Destruct,
K: ~const Destruct,
{
const fn imp<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(
f: &mut F,
(v1, v2): (&T, &T),
) -> Ordering
where
T: ~const Destruct,
K: ~const Destruct,
{
f(v1).cmp(&f(v2))
}
max_by(v1, v2, ConstFnMutClosure::new(&mut f, imp))
}
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types

View File

@ -138,6 +138,7 @@
#![feature(const_size_of_val)]
#![feature(const_slice_from_raw_parts_mut)]
#![feature(const_slice_ptr_len)]
#![feature(const_slice_split_at_mut)]
#![feature(const_str_from_utf8_unchecked_mut)]
#![feature(const_swap)]
#![feature(const_trait_impl)]

View File

@ -842,6 +842,7 @@ impl<T> Option<T> {
/// ```
/// let good_year_from_input = "1909";
/// let bad_year_from_input = "190blarg";
/// // Result::ok() converts a Result<T> to an Option<T>
/// let good_year = good_year_from_input.parse().ok().unwrap_or_default();
/// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default();
///

View File

@ -1580,7 +1580,8 @@ impl<T> [T] {
#[inline]
#[track_caller]
#[must_use]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
#[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")]
pub const fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
assert!(mid <= self.len());
// SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
// fulfills the requirements of `from_raw_parts_mut`.
@ -1679,9 +1680,10 @@ impl<T> [T] {
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
/// ```
#[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
#[rustc_const_unstable(feature = "const_slice_split_at_mut", issue = "101804")]
#[inline]
#[must_use]
pub unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
pub const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
let len = self.len();
let ptr = self.as_mut_ptr();
@ -2643,9 +2645,10 @@ impl<T> [T] {
/// less than or equal to any value at a position `j > index`. Additionally, this reordering is
/// unstable (i.e. any number of equal elements may end up at position `index`), in-place
/// (i.e. does not allocate), and *O*(*n*) worst-case. This function is also/ known as "kth
/// element" in other libraries. It returns a triplet of the following values: all elements less
/// than the one at the given index, the value at the given index, and all elements greater than
/// the one at the given index.
/// element" in other libraries. It returns a triplet of the following from the reordered slice:
/// the subslice prior to `index`, the element at `index`, and the subslice after `index`;
/// accordingly, the values in those two subslices will respectively all be less-than-or-equal-to
/// and greater-than-or-equal-to the value of the element at `index`.
///
/// # Current implementation
///
@ -2689,10 +2692,11 @@ impl<T> [T] {
/// less than or equal to any value at a position `j > index` using the comparator function.
/// Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
/// position `index`), in-place (i.e. does not allocate), and *O*(*n*) worst-case. This function
/// is also known as "kth element" in other libraries. It returns a triplet of the following
/// values: all elements less than the one at the given index, the value at the given index,
/// and all elements greater than the one at the given index, using the provided comparator
/// function.
/// is also known as "kth element" in other libraries. It returns a triplet of the following from
/// the slice reordered according to the provided comparator function: the subslice prior to
/// `index`, the element at `index`, and the subslice after `index`; accordingly, the values in
/// those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to
/// the value of the element at `index`.
///
/// # Current implementation
///
@ -2740,10 +2744,11 @@ impl<T> [T] {
/// less than or equal to any value at a position `j > index` using the key extraction function.
/// Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
/// position `index`), in-place (i.e. does not allocate), and *O*(*n*) worst-case. This function
/// is also known as "kth element" in other libraries. It returns a triplet of the following
/// values: all elements less than the one at the given index, the value at the given index, and
/// all elements greater than the one at the given index, using the provided key extraction
/// function.
/// is also known as "kth element" in other libraries. It returns a triplet of the following from
/// the slice reordered according to the provided key extraction function: the subslice prior to
/// `index`, the element at `index`, and the subslice after `index`; accordingly, the values in
/// those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to
/// the value of the element at `index`.
///
/// # Current implementation
///

View File

@ -93,7 +93,8 @@ macro_rules! tuple_impls {
maybe_tuple_doc! {
$($T)+ @
#[stable(feature = "rust1", since = "1.0.0")]
impl<$($T:Default),+> Default for ($($T,)+) {
#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")]
impl<$($T: ~const Default),+> const Default for ($($T,)+) {
#[inline]
fn default() -> ($($T,)+) {
($({ let x: $T = Default::default(); x},)+)

View File

@ -41,7 +41,7 @@ $ rustc -Zself-profile -Zself-profile-events=default,args
- `llvm`
- Adds tracing information about LLVM passes and codegeneration.
- Disabled by default because this only works when `-Znew-llvm-pass-manager` is enabled.
- Disabled by default because this significantly increases the trace file size.
## Event synonyms

View File

@ -82,7 +82,6 @@
-Z mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)
-Z move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted
-Z mutable-noalias=val -- emit noalias metadata for mutable references (default: yes)
-Z new-llvm-pass-manager=val -- use new LLVM pass manager (default: no)
-Z nll-facts=val -- dump facts from NLL analysis into side files (default: no)
-Z nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`)
-Z no-analysis=val -- parse and expand the source, but run no analysis

View File

@ -0,0 +1,26 @@
// Tests the suggestion to reborrow the first move site
// when we move then borrow a `&mut` ref.
struct State;
impl IntoIterator for &mut State {
type IntoIter = std::vec::IntoIter<()>;
type Item = ();
fn into_iter(self) -> Self::IntoIter {
vec![].into_iter()
}
}
fn once(f: impl FnOnce()) {}
fn fill_memory_blocks_mt(state: &mut State) {
for _ in state {}
//~^ HELP consider creating a fresh reborrow of `state` here
fill_segment(state);
//~^ ERROR borrow of moved value: `state`
}
fn fill_segment(state: &mut State) {}
fn main() {}

View File

@ -0,0 +1,24 @@
error[E0382]: borrow of moved value: `state`
--> $DIR/reborrow-sugg-move-then-borrow.rs:20:18
|
LL | fn fill_memory_blocks_mt(state: &mut State) {
| ----- move occurs because `state` has type `&mut State`, which does not implement the `Copy` trait
LL | for _ in state {}
| ----- `state` moved due to this implicit call to `.into_iter()`
LL |
LL | fill_segment(state);
| ^^^^^ value borrowed here after move
|
note: this function takes ownership of the receiver `self`, which moves `state`
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
LL | fn into_iter(self) -> Self::IntoIter;
| ^^^^
help: consider creating a fresh reborrow of `state` here
|
LL | for _ in &mut *state {}
| ++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`.

View File

@ -63,7 +63,7 @@ static STATIC8: SafeStruct = SafeStruct{field1: SafeEnum::Variant1,
// This example should fail because field1 in the base struct is not safe
static STATIC9: SafeStruct = SafeStruct{field1: SafeEnum::Variant1,
..SafeStruct{field1: SafeEnum::Variant3(WithDtor),
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
field2: SafeEnum::Variant1}};
struct UnsafeStruct;

View File

@ -1,4 +1,4 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `SafeStruct` cannot be evaluated at compile-time
--> $DIR/check-static-values-constraints.rs:65:43
|
LL | ..SafeStruct{field1: SafeEnum::Variant3(WithDtor),
@ -7,7 +7,7 @@ LL | |
LL | | field2: SafeEnum::Variant1}};
| | ^- value is dropped here
| |________________________________________________________________________________|
| statics cannot evaluate destructors
| the destructor for this type cannot be evaluated in statics
error[E0010]: allocations are not allowed in statics
--> $DIR/check-static-values-constraints.rs:79:33

View File

@ -14,16 +14,16 @@ const X2: FakeNeedsDrop = { let x; x = FakeNeedsDrop; x };
// error
const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
// error
const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x };
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
// error
const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
// error
const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); };
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of

View File

@ -1,34 +1,34 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `FakeNeedsDrop` cannot be evaluated at compile-time
--> $DIR/const_let.rs:16:32
|
LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
| ^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `FakeNeedsDrop` cannot be evaluated at compile-time
--> $DIR/const_let.rs:20:33
|
LL | const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x };
| ^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<FakeNeedsDrop>` cannot be evaluated at compile-time
--> $DIR/const_let.rs:24:21
|
LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
| ^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<FakeNeedsDrop>` cannot be evaluated at compile-time
--> $DIR/const_let.rs:28:22
|
LL | const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); };
| ^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error: aborting due to 4 previous errors

View File

@ -4,7 +4,7 @@
// We will likely have to change this behavior before we allow `&mut` in a `const`.
const _: Vec<i32> = {
let mut x = Vec::<i32>::new(); //~ ERROR destructors cannot be evaluated at compile-time
let mut x = Vec::<i32>::new(); //~ ERROR destructor of
let r = &mut x; //~ ERROR mutable references are not allowed in constants
let y = x;
y

View File

@ -7,11 +7,11 @@ LL | let r = &mut x;
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Vec<i32>` cannot be evaluated at compile-time
--> $DIR/issue-65394.rs:7:9
|
LL | let mut x = Vec::<i32>::new();
| ^^^^^ constants cannot evaluate destructors
| ^^^^^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here

View File

@ -1,6 +1,6 @@
const _: Option<Vec<i32>> = {
let mut never_returned = Some(Vec::new());
let mut always_returned = None; //~ ERROR destructors cannot be evaluated at compile-time
let mut always_returned = None; //~ ERROR destructor of
let mut i = 0;
loop {

View File

@ -1,8 +1,8 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
--> $DIR/livedrop.rs:3:9
|
LL | let mut always_returned = None;
| ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors
| ^^^^^^^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants
...
LL | always_returned = never_returned;
| --------------- value is dropped here

View File

@ -1,14 +1,14 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
--> $DIR/drop-fail.rs:8:9
|
LL | let x = Some(Vec::new());
| ^ constants cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
--> $DIR/drop-fail.rs:39:9
|
LL | let mut tmp = None;
| ^^^^^^^ constants cannot evaluate destructors
| ^^^^^^^ the destructor for this type cannot be evaluated in constants
error: aborting due to 2 previous errors

View File

@ -6,7 +6,7 @@
const _: Option<Vec<i32>> = {
let y: Option<Vec<i32>> = None;
let x = Some(Vec::new());
//[stock,precise]~^ ERROR destructors cannot be evaluated at compile-time
//[stock,precise]~^ ERROR destructor of
if true {
x
@ -19,7 +19,7 @@ const _: Option<Vec<i32>> = {
// existing analysis.
const _: Vec<i32> = {
let vec_tuple = (Vec::new(),);
//[stock]~^ ERROR destructors cannot be evaluated at compile-time
//[stock]~^ ERROR destructor of
vec_tuple.0
};
@ -27,7 +27,7 @@ const _: Vec<i32> = {
// This applies to single-field enum variants as well.
const _: Vec<i32> = {
let x: Result<_, Vec<i32>> = Ok(Vec::new());
//[stock]~^ ERROR destructors cannot be evaluated at compile-time
//[stock]~^ ERROR destructor of
match x {
Ok(x) | Err(x) => x,
@ -37,7 +37,7 @@ const _: Vec<i32> = {
const _: Option<Vec<i32>> = {
let mut some = Some(Vec::new());
let mut tmp = None;
//[stock,precise]~^ ERROR destructors cannot be evaluated at compile-time
//[stock,precise]~^ ERROR destructor of
let mut i = 0;
while i < 10 {

View File

@ -1,35 +1,35 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
--> $DIR/drop-fail.rs:8:9
|
LL | let x = Some(Vec::new());
| ^ constants cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(Vec<i32>,)` cannot be evaluated at compile-time
--> $DIR/drop-fail.rs:21:9
|
LL | let vec_tuple = (Vec::new(),);
| ^^^^^^^^^ constants cannot evaluate destructors
| ^^^^^^^^^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Result<Vec<i32>, Vec<i32>>` cannot be evaluated at compile-time
--> $DIR/drop-fail.rs:29:9
|
LL | let x: Result<_, Vec<i32>> = Ok(Vec::new());
| ^ constants cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
--> $DIR/drop-fail.rs:39:9
|
LL | let mut tmp = None;
| ^^^^^^^ constants cannot evaluate destructors
| ^^^^^^^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here

View File

@ -1,4 +1,4 @@
const fn f<T>(_: Box<T>) {}
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
fn main() {}

View File

@ -1,10 +1,10 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Box<T>` cannot be evaluated at compile-time
--> $DIR/drop_box.rs:1:15
|
LL | const fn f<T>(_: Box<T>) {}
| ^ - value is dropped here
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
error: aborting due to previous error

View File

@ -1,8 +1,8 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `S` cannot be evaluated at compile-time
--> $DIR/drop_zst.rs:14:9
|
LL | let s = S;
| ^ constant functions cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constant functions
error: aborting due to previous error

View File

@ -34,7 +34,7 @@ const fn foo35(a: bool, b: bool) -> bool { a ^ b }
struct Foo<T: ?Sized>(T);
impl<T> Foo<T> {
const fn new(t: T) -> Self { Foo(t) }
const fn into_inner(self) -> T { self.0 } //~ destructors cannot be evaluated
const fn into_inner(self) -> T { self.0 } //~ destructor of
const fn get(&self) -> &T { &self.0 }
const fn get_mut(&mut self) -> &mut T { &mut self.0 }
//~^ mutable references
@ -43,7 +43,7 @@ impl<T> Foo<T> {
}
impl<'a, T> Foo<T> {
const fn new_lt(t: T) -> Self { Foo(t) }
const fn into_inner_lt(self) -> T { self.0 } //~ destructors cannot be evaluated
const fn into_inner_lt(self) -> T { self.0 } //~ destructor of
const fn get_lt(&'a self) -> &T { &self.0 }
const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
//~^ mutable references
@ -52,7 +52,7 @@ impl<'a, T> Foo<T> {
}
impl<T: Sized> Foo<T> {
const fn new_s(t: T) -> Self { Foo(t) }
const fn into_inner_s(self) -> T { self.0 } //~ ERROR destructors
const fn into_inner_s(self) -> T { self.0 } //~ ERROR destructor
const fn get_s(&self) -> &T { &self.0 }
const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
//~^ mutable references

View File

@ -1,10 +1,10 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Foo<T>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:37:25
|
LL | const fn into_inner(self) -> T { self.0 }
| ^^^^ - value is dropped here
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:39:22
@ -33,13 +33,13 @@ LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Foo<T>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:46:28
|
LL | const fn into_inner_lt(self) -> T { self.0 }
| ^^^^ - value is dropped here
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:48:25
@ -68,13 +68,13 @@ LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Foo<T>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:55:27
|
LL | const fn into_inner_s(self) -> T { self.0 }
| ^^^^ - value is dropped here
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:57:24
@ -191,21 +191,21 @@ LL | const fn inc(x: &mut i32) { *x += 1 }
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `AlanTuring<impl std::fmt::Debug>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:122:19
|
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
| ^^ - value is dropped here
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `impl std::fmt::Debug` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:124:18
|
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
| ^^ - value is dropped here
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
error: aborting due to 24 previous errors

View File

@ -8,7 +8,7 @@ trait Foo<T> {
}
trait Bar<T, U: Foo<T>> {
const F: u32 = (U::X, 42).1; //~ ERROR destructors cannot be evaluated at compile-time
const F: u32 = (U::X, 42).1; //~ ERROR destructor of
}
impl Foo<u32> for () {

View File

@ -1,10 +1,10 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(T, u32)` cannot be evaluated at compile-time
--> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:11:20
|
LL | const F: u32 = (U::X, 42).1;
| ^^^^^^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error: aborting due to previous error

View File

@ -6,13 +6,13 @@
// Mutable borrow of a field with drop impl.
pub const fn f() {
let mut a: (u32, Option<String>) = (0, None); //~ ERROR destructors cannot be evaluated
let mut a: (u32, Option<String>) = (0, None); //~ ERROR destructor of
let _ = &mut a.1;
}
// Mutable borrow of a type with drop impl.
pub const A1: () = {
let mut x = None; //~ ERROR destructors cannot be evaluated
let mut x = None; //~ ERROR destructor of
let mut y = Some(String::new());
let a = &mut x;
let b = &mut y;
@ -28,12 +28,12 @@ pub const A2: () = {
let b = &mut y;
std::mem::swap(a, b);
std::mem::forget(y);
let _z = x; //~ ERROR destructors cannot be evaluated
let _z = x; //~ ERROR destructor of
};
// Shared borrow of a type that might be !Freeze and Drop.
pub const fn g1<T>() {
let x: Option<T> = None; //~ ERROR destructors cannot be evaluated
let x: Option<T> = None; //~ ERROR destructor of
let _ = x.is_some();
}
@ -41,24 +41,24 @@ pub const fn g1<T>() {
pub const fn g2<T>() {
let x: Option<T> = None;
let _ = x.is_some();
let _y = x; //~ ERROR destructors cannot be evaluated
let _y = x; //~ ERROR destructor of
}
// Mutable raw reference to a Drop type.
pub const fn address_of_mut() {
let mut x: Option<String> = None; //~ ERROR destructors cannot be evaluated
let mut x: Option<String> = None; //~ ERROR destructor of
&raw mut x;
let mut y: Option<String> = None; //~ ERROR destructors cannot be evaluated
let mut y: Option<String> = None; //~ ERROR destructor of
std::ptr::addr_of_mut!(y);
}
// Const raw reference to a Drop type. Conservatively assumed to allow mutation
// until resolution of https://github.com/rust-lang/rust/issues/56604.
pub const fn address_of_const() {
let x: Option<String> = None; //~ ERROR destructors cannot be evaluated
let x: Option<String> = None; //~ ERROR destructor of
&raw const x;
let y: Option<String> = None; //~ ERROR destructors cannot be evaluated
let y: Option<String> = None; //~ ERROR destructor of
std::ptr::addr_of!(y);
}

View File

@ -1,56 +1,56 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(u32, Option<String>)` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:9:9
|
LL | let mut a: (u32, Option<String>) = (0, None);
| ^^^^^ constant functions cannot evaluate destructors
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:15:9
|
LL | let mut x = None;
| ^^^^^ constants cannot evaluate destructors
| ^^^^^ the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:31:9
|
LL | let _z = x;
| ^^ constants cannot evaluate destructors
| ^^ the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:36:9
|
LL | let x: Option<T> = None;
| ^ constant functions cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:44:9
|
LL | let _y = x;
| ^^ constant functions cannot evaluate destructors
| ^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:52:9
|
LL | let mut y: Option<String> = None;
| ^^^^^ constant functions cannot evaluate destructors
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:49:9
|
LL | let mut x: Option<String> = None;
| ^^^^^ constant functions cannot evaluate destructors
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:62:9
|
LL | let y: Option<String> = None;
| ^ constant functions cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:59:9
|
LL | let x: Option<String> = None;
| ^ constant functions cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constant functions
error: aborting due to 9 previous errors

View File

@ -11,7 +11,7 @@ impl<T> Either<T, T> {
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "foo", since = "1.0.0")]
pub const fn unwrap(self) -> T {
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
match self {
Self::Left(t) => t,
Self::Right(t) => t,

View File

@ -1,8 +1,8 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Either<T, T>` cannot be evaluated at compile-time
--> $DIR/stable-precise-live-drops-in-libcore.rs:13:25
|
LL | pub const fn unwrap(self) -> T {
| ^^^^ constant functions cannot evaluate destructors
| ^^^^ the destructor for this type cannot be evaluated in constant functions
...
LL | }
| - value is dropped here

View File

@ -15,8 +15,8 @@ impl<T> Opt<T> {
#[rustc_const_unstable(feature = "foo", issue = "none")]
#[stable(feature = "rust1", since = "1.0.0")]
const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
//~^ ERROR destructors cannot be evaluated at compile-time
//~| ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
//~| ERROR destructor of
match self {
Opt::Some(t) => t,
Opt::None => f(),

View File

@ -1,17 +1,17 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `F` cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:17:60
|
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
| ^ constant functions cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constant functions
...
LL | }
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `Opt<T>` cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:17:54
|
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
| ^^^^ constant functions cannot evaluate destructors
| ^^^^ the destructor for this type cannot be evaluated in constant functions
...
LL | }
| - value is dropped here

View File

@ -5,7 +5,7 @@ fn borrowck_catch() {
}
const _: [String; 0] = [String::new(); 0];
//~^ ERROR destructors cannot be evaluated at compile-time [E0493]
//~^ ERROR destructor of `String` cannot be evaluated at compile-time [E0493]
fn must_be_init() {
let x: u8;

View File

@ -8,13 +8,13 @@ LL | let _bar = foo;
LL | let _baz = [foo; 0];
| ^^^ value used here after move
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `String` cannot be evaluated at compile-time
--> $DIR/repeat-drop-2.rs:7:25
|
LL | const _: [String; 0] = [String::new(); 0];
| -^^^^^^^^^^^^^----
| ||
| |constants cannot evaluate destructors
| |the destructor for this type cannot be evaluated in constants
| value is dropped here
error[E0381]: used binding `x` isn't initialized

View File

@ -12,7 +12,7 @@ struct Bug {
}
let f: F = async { 1 };
//~^ ERROR `async` blocks are not allowed in constants
//~| ERROR destructors cannot be evaluated at compile-time
//~| ERROR destructor of
1
}],
}

View File

@ -7,11 +7,11 @@ LL | let f: F = async { 1 };
= note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
= help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `F` cannot be evaluated at compile-time
--> $DIR/issue-78722.rs:13:13
|
LL | let f: F = async { 1 };
| ^ constants cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in constants
...
LL | }],
| - value is dropped here

View File

@ -1,4 +1,4 @@
// build-fail
// compile-flags: -Cpasses=unknown-pass -Z new-llvm-pass-manager=yes
// compile-flags: -Cpasses=unknown-pass
fn main() {}

View File

@ -3,9 +3,9 @@
static A: () = {
let a: [String; 1];
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
a[0] = String::new();
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
//~| ERROR binding `a` isn't initialized
};
@ -14,9 +14,9 @@ struct B<T>([T; 1]);
impl<T> B<T> {
pub const fn f(mut self, other: T) -> Self {
let _this = self;
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
self.0[0] = other;
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
//~| ERROR use of moved value
self
}

View File

@ -1,17 +1,17 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `String` cannot be evaluated at compile-time
--> $DIR/drop-elaboration-after-borrowck-error.rs:7:5
|
LL | a[0] = String::new();
| ^^^^
| |
| statics cannot evaluate destructors
| the destructor for this type cannot be evaluated in statics
| value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `[String; 1]` cannot be evaluated at compile-time
--> $DIR/drop-elaboration-after-borrowck-error.rs:5:9
|
LL | let a: [String; 1];
| ^ statics cannot evaluate destructors
| ^ the destructor for this type cannot be evaluated in statics
...
LL | };
| - value is dropped here
@ -25,20 +25,20 @@ LL |
LL | a[0] = String::new();
| ^^^^ `a` used here but it isn't initialized
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/drop-elaboration-after-borrowck-error.rs:18:9
|
LL | self.0[0] = other;
| ^^^^^^^^^
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
| value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `B<T>` cannot be evaluated at compile-time
--> $DIR/drop-elaboration-after-borrowck-error.rs:16:13
|
LL | let _this = self;
| ^^^^^ constant functions cannot evaluate destructors
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
...
LL | }
| - value is dropped here

View File

@ -7,7 +7,7 @@
//
// no-prefer-dynamic
// revisions: opt0 opt1
// compile-flags: -Znew-llvm-pass-manager=yes -Zsanitizer=address -Clto=thin
// compile-flags: -Zsanitizer=address -Clto=thin
//[opt0]compile-flags: -Copt-level=0
//[opt1]compile-flags: -Copt-level=1
// run-fail

View File

@ -15,7 +15,7 @@ impl Drop for Bar {
}
const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
//~^ destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
fn main() {
}

View File

@ -1,10 +1,10 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(Foo, Foo)` cannot be evaluated at compile-time
--> $DIR/E0493.rs:17:17
|
LL | const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error: aborting due to previous error

View File

@ -5,33 +5,33 @@ impl Drop for WithDtor {
}
static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
//~| ERROR temporary value dropped while borrowed
const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
//~| ERROR temporary value dropped while borrowed
static EARLY_DROP_S: i32 = (WithDtor, 0).1;
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
const EARLY_DROP_C: i32 = (WithDtor, 0).1;
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
const fn const_drop<T>(_: T) {}
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
const fn const_drop2<T>(x: T) {
(x, ()).1
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
}
const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
const HELPER: Option<WithDtor> = Some(WithDtor);
const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
//~^ ERROR destructors cannot be evaluated at compile-time
//~^ ERROR destructor of
fn main () {}

View File

@ -1,10 +1,10 @@
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `WithDtor` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:7:60
|
LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
| ^^^^^^^^- value is dropped here
| |
| statics cannot evaluate destructors
| the destructor for this type cannot be evaluated in statics
error[E0716]: temporary value dropped while borrowed
--> $DIR/static-drop-scope.rs:7:60
@ -16,13 +16,13 @@ LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
| | creates a temporary which is freed while still in use
| using this value as a static requires that borrow lasts for `'static`
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `WithDtor` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:11:59
|
LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
| ^^^^^^^^- value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error[E0716]: temporary value dropped while borrowed
--> $DIR/static-drop-scope.rs:11:59
@ -34,54 +34,54 @@ LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
| | creates a temporary which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(WithDtor, i32)` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:15:28
|
LL | static EARLY_DROP_S: i32 = (WithDtor, 0).1;
| ^^^^^^^^^^^^^ - value is dropped here
| |
| statics cannot evaluate destructors
| the destructor for this type cannot be evaluated in statics
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(WithDtor, i32)` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:18:27
|
LL | const EARLY_DROP_C: i32 = (WithDtor, 0).1;
| ^^^^^^^^^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:21:24
|
LL | const fn const_drop<T>(_: T) {}
| ^ - value is dropped here
| |
| constant functions cannot evaluate destructors
| the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(T, ())` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:25:5
|
LL | (x, ()).1
| ^^^^^^^ constant functions cannot evaluate destructors
| ^^^^^^^ the destructor for this type cannot be evaluated in constant functions
LL |
LL | }
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(Option<WithDtor>, i32)` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:29:34
|
LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
| ^^^^^^^^^^^^^^^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error[E0493]: destructors cannot be evaluated at compile-time
error[E0493]: destructor of `(Option<WithDtor>, i32)` cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:34:43
|
LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
| ^^^^^^^^^^^ - value is dropped here
| |
| constants cannot evaluate destructors
| the destructor for this type cannot be evaluated in constants
error: aborting due to 10 previous errors