diff --git a/Cargo.lock b/Cargo.lock index 38b009bfc7000..923d4017c0cad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3507,7 +3507,6 @@ dependencies = [ "cc", "either", "itertools", - "jobserver", "libc", "object 0.36.5", "pathdiff", diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs index 16b3d901956cc..ff838fbbb8868 100644 --- a/compiler/rustc_borrowck/src/borrow_set.rs +++ b/compiler/rustc_borrowck/src/borrow_set.rs @@ -34,6 +34,25 @@ pub struct BorrowSet<'tcx> { pub(crate) locals_state_at_exit: LocalsStateAtExit, } +// These methods are public to support borrowck consumers. +impl<'tcx> BorrowSet<'tcx> { + pub fn location_map(&self) -> &FxIndexMap> { + &self.location_map + } + + pub fn activation_map(&self) -> &FxIndexMap> { + &self.activation_map + } + + pub fn local_map(&self) -> &FxIndexMap> { + &self.local_map + } + + pub fn locals_state_at_exit(&self) -> &LocalsStateAtExit { + &self.locals_state_at_exit + } +} + impl<'tcx> Index for BorrowSet<'tcx> { type Output = BorrowData<'tcx>; @@ -45,7 +64,7 @@ impl<'tcx> Index for BorrowSet<'tcx> { /// Location where a two-phase borrow is activated, if a borrow /// is in fact a two-phase borrow. #[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub(crate) enum TwoPhaseActivation { +pub enum TwoPhaseActivation { NotTwoPhase, NotActivated, ActivatedAt(Location), @@ -68,6 +87,33 @@ pub struct BorrowData<'tcx> { pub(crate) assigned_place: mir::Place<'tcx>, } +// These methods are public to support borrowck consumers. +impl<'tcx> BorrowData<'tcx> { + pub fn reserve_location(&self) -> Location { + self.reserve_location + } + + pub fn activation_location(&self) -> TwoPhaseActivation { + self.activation_location + } + + pub fn kind(&self) -> mir::BorrowKind { + self.kind + } + + pub fn region(&self) -> RegionVid { + self.region + } + + pub fn borrowed_place(&self) -> mir::Place<'tcx> { + self.borrowed_place + } + + pub fn assigned_place(&self) -> mir::Place<'tcx> { + self.assigned_place + } +} + impl<'tcx> fmt::Display for BorrowData<'tcx> { fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { let kind = match self.kind { @@ -120,7 +166,7 @@ impl LocalsStateAtExit { } impl<'tcx> BorrowSet<'tcx> { - pub(crate) fn build( + pub fn build( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, locals_are_invalidated_at_exit: bool, diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 7ace38c3e85ff..74de766ba2317 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -5,15 +5,15 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::{Body, Promoted}; use rustc_middle::ty::TyCtxt; +pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation}; pub use super::constraints::OutlivesConstraint; pub use super::dataflow::{BorrowIndex, Borrows, calculate_borrows_out_of_scope_at_location}; -pub use super::facts::{AllFacts as PoloniusInput, RustcFacts}; +pub use super::facts::{AllFacts as PoloniusInput, PoloniusRegionVid, RustcFacts}; pub use super::location::{LocationTable, RichLocation}; pub use super::nll::PoloniusOutput; pub use super::place_ext::PlaceExt; pub use super::places_conflict::{PlaceConflictBias, places_conflict}; pub use super::region_infer::RegionInferenceContext; -use crate::borrow_set::BorrowSet; /// Options determining the output behavior of [`get_body_with_borrowck_facts`]. /// diff --git a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs index 2093b49ff31a7..b5a81fc11d57b 100644 --- a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs +++ b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs @@ -1,8 +1,7 @@ use std::sync::{Arc, Condvar, Mutex}; -use jobserver::HelperThread; +use rustc_data_structures::jobserver::{self, HelperThread}; use rustc_errors::DiagCtxtHandle; -use rustc_session::Session; // FIXME don't panic when a worker thread panics @@ -14,14 +13,13 @@ pub(super) struct ConcurrencyLimiter { } impl ConcurrencyLimiter { - pub(super) fn new(sess: &Session, pending_jobs: usize) -> Self { + pub(super) fn new(pending_jobs: usize) -> Self { let state = Arc::new(Mutex::new(state::ConcurrencyLimiterState::new(pending_jobs))); let available_token_condvar = Arc::new(Condvar::new()); let state_helper = state.clone(); let available_token_condvar_helper = available_token_condvar.clone(); - let helper_thread = sess - .jobserver + let helper_thread = jobserver::client() .clone() .into_helper_thread(move |token| { let mut state = state_helper.lock().unwrap(); @@ -113,7 +111,7 @@ impl Drop for ConcurrencyLimiterToken { } mod state { - use jobserver::Acquired; + use rustc_data_structures::jobserver::Acquired; #[derive(Debug)] pub(super) struct ConcurrencyLimiterState { diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 5bbcfc2cda7d7..4fc30b69123dd 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -679,7 +679,7 @@ pub(crate) fn run_aot( metadata_module: None, metadata, crate_info: CrateInfo::new(tcx, target_cpu), - concurrency_limiter: ConcurrencyLimiter::new(tcx.sess, 0), + concurrency_limiter: ConcurrencyLimiter::new(0), }); }; @@ -711,7 +711,7 @@ pub(crate) fn run_aot( CguReuse::PreLto | CguReuse::PostLto => false, }); - let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(tcx.sess, todo_cgus.len())); + let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(todo_cgus.len())); let modules = tcx.sess.time("codegen mono items", || { let mut modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| { diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index d68948966eaeb..4be4291021dfa 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -287,12 +287,7 @@ fn dep_symbol_lookup_fn( let mut dylib_paths = Vec::new(); - let data = &crate_info - .dependency_formats - .iter() - .find(|(crate_type, _data)| *crate_type == rustc_session::config::CrateType::Executable) - .unwrap() - .1; + let data = &crate_info.dependency_formats[&rustc_session::config::CrateType::Executable].1; // `used_crates` is in reverse postorder in terms of dependencies. Reverse the order here to // get a postorder which ensures that all dependencies of a dylib are loaded before the dylib // itself. This helps the dynamic linker to find dylibs not in the regular dynamic library diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 9f552b3feb950..c3a1617b49500 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -12,7 +12,6 @@ #![warn(unused_lifetimes)] // tidy-alphabetical-end -extern crate jobserver; #[macro_use] extern crate rustc_middle; extern crate rustc_abi; diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index a573a37beb3fa..4f2af73252751 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -75,10 +75,10 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { // Encode all filenames referenced by coverage mappings in this CGU. let filenames_buffer = global_file_table.make_filenames_buffer(tcx); - - let filenames_size = filenames_buffer.len(); - let filenames_val = cx.const_bytes(&filenames_buffer); - let filenames_ref = llvm_cov::hash_bytes(&filenames_buffer); + // The `llvm-cov` tool uses this hash to associate each covfun record with + // its corresponding filenames table, since the final binary will typically + // contain multiple covmap records from different compilation units. + let filenames_hash = llvm_cov::hash_bytes(&filenames_buffer); let mut unused_function_names = Vec::new(); @@ -101,7 +101,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { for covfun in &covfun_records { unused_function_names.extend(covfun.mangled_function_name_if_unused()); - covfun::generate_covfun_record(cx, filenames_ref, covfun) + covfun::generate_covfun_record(cx, filenames_hash, covfun) } // For unused functions, we need to take their mangled names and store them @@ -126,7 +126,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) { // Generate the coverage map header, which contains the filenames used by // this CGU's coverage mappings, and store it in a well-known global. // (This is skipped if we returned early due to having no covfun records.) - generate_covmap_record(cx, covmap_version, filenames_size, filenames_val); + generate_covmap_record(cx, covmap_version, &filenames_buffer); } /// Maps "global" (per-CGU) file ID numbers to their underlying filenames. @@ -225,38 +225,35 @@ fn span_file_name(tcx: TyCtxt<'_>, span: Span) -> Symbol { /// Generates the contents of the covmap record for this CGU, which mostly /// consists of a header and a list of filenames. The record is then stored /// as a global variable in the `__llvm_covmap` section. -fn generate_covmap_record<'ll>( - cx: &CodegenCx<'ll, '_>, - version: u32, - filenames_size: usize, - filenames_val: &'ll llvm::Value, -) { - debug!("cov map: filenames_size = {}, 0-based version = {}", filenames_size, version); - - // Create the coverage data header (Note, fields 0 and 2 are now always zero, - // as of `llvm::coverage::CovMapVersion::Version4`.) - let zero_was_n_records_val = cx.const_u32(0); - let filenames_size_val = cx.const_u32(filenames_size as u32); - let zero_was_coverage_size_val = cx.const_u32(0); - let version_val = cx.const_u32(version); - let cov_data_header_val = cx.const_struct( - &[zero_was_n_records_val, filenames_size_val, zero_was_coverage_size_val, version_val], - /*packed=*/ false, +fn generate_covmap_record<'ll>(cx: &CodegenCx<'ll, '_>, version: u32, filenames_buffer: &[u8]) { + // A covmap record consists of four target-endian u32 values, followed by + // the encoded filenames table. Two of the header fields are unused in + // modern versions of the LLVM coverage mapping format, and are always 0. + // + // See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp`. + let covmap_header = cx.const_struct( + &[ + cx.const_u32(0), // (unused) + cx.const_u32(filenames_buffer.len() as u32), + cx.const_u32(0), // (unused) + cx.const_u32(version), + ], + /* packed */ false, ); - - // Create the complete LLVM coverage data value to add to the LLVM IR - let covmap_data = - cx.const_struct(&[cov_data_header_val, filenames_val], /*packed=*/ false); - - let llglobal = llvm::add_global(cx.llmod, cx.val_ty(covmap_data), &llvm_cov::covmap_var_name()); - llvm::set_initializer(llglobal, covmap_data); - llvm::set_global_constant(llglobal, true); - llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage); - llvm::set_section(llglobal, &llvm_cov::covmap_section_name(cx.llmod)); + let covmap_record = cx + .const_struct(&[covmap_header, cx.const_bytes(filenames_buffer)], /* packed */ false); + + let covmap_global = + llvm::add_global(cx.llmod, cx.val_ty(covmap_record), &llvm_cov::covmap_var_name()); + llvm::set_initializer(covmap_global, covmap_record); + llvm::set_global_constant(covmap_global, true); + llvm::set_linkage(covmap_global, llvm::Linkage::PrivateLinkage); + llvm::set_section(covmap_global, &llvm_cov::covmap_section_name(cx.llmod)); // LLVM's coverage mapping format specifies 8-byte alignment for items in this section. // - llvm::set_alignment(llglobal, Align::EIGHT); - cx.add_used_global(llglobal); + llvm::set_alignment(covmap_global, Align::EIGHT); + + cx.add_used_global(covmap_global); } /// Each CGU will normally only emit coverage metadata for the functions that it actually generates. diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs index 530e6827f55d3..33e7a0f2f201b 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs @@ -136,7 +136,7 @@ fn fill_region_tables<'tcx>( /// as a global variable in the `__llvm_covfun` section. pub(crate) fn generate_covfun_record<'tcx>( cx: &CodegenCx<'_, 'tcx>, - filenames_ref: u64, + filenames_hash: u64, covfun: &CovfunRecord<'tcx>, ) { let &CovfunRecord { @@ -155,46 +155,45 @@ pub(crate) fn generate_covfun_record<'tcx>( regions, ); - // Concatenate the encoded coverage mappings - let coverage_mapping_size = coverage_mapping_buffer.len(); - let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer); - + // A covfun record consists of four target-endian integers, followed by the + // encoded mapping data in bytes. Note that the length field is 32 bits. + // + // See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp` and + // `COVMAP_V3` in `src/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc`. let func_name_hash = llvm_cov::hash_bytes(mangled_function_name.as_bytes()); - let func_name_hash_val = cx.const_u64(func_name_hash); - let coverage_mapping_size_val = cx.const_u32(coverage_mapping_size as u32); - let source_hash_val = cx.const_u64(source_hash); - let filenames_ref_val = cx.const_u64(filenames_ref); - let func_record_val = cx.const_struct( + let covfun_record = cx.const_struct( &[ - func_name_hash_val, - coverage_mapping_size_val, - source_hash_val, - filenames_ref_val, - coverage_mapping_val, + cx.const_u64(func_name_hash), + cx.const_u32(coverage_mapping_buffer.len() as u32), + cx.const_u64(source_hash), + cx.const_u64(filenames_hash), + cx.const_bytes(&coverage_mapping_buffer), ], - /*packed=*/ true, + // This struct needs to be packed, so that the 32-bit length field + // doesn't have unexpected padding. + true, ); // Choose a variable name to hold this function's covfun data. // Functions that are used have a suffix ("u") to distinguish them from // unused copies of the same function (from different CGUs), so that if a // linker sees both it won't discard the used copy's data. - let func_record_var_name = - CString::new(format!("__covrec_{:X}{}", func_name_hash, if is_used { "u" } else { "" })) - .unwrap(); - debug!("function record var name: {:?}", func_record_var_name); - - let llglobal = llvm::add_global(cx.llmod, cx.val_ty(func_record_val), &func_record_var_name); - llvm::set_initializer(llglobal, func_record_val); - llvm::set_global_constant(llglobal, true); - llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage); - llvm::set_visibility(llglobal, llvm::Visibility::Hidden); - llvm::set_section(llglobal, cx.covfun_section_name()); + let u = if is_used { "u" } else { "" }; + let covfun_var_name = CString::new(format!("__covrec_{func_name_hash:X}{u}")).unwrap(); + debug!("function record var name: {covfun_var_name:?}"); + + let covfun_global = llvm::add_global(cx.llmod, cx.val_ty(covfun_record), &covfun_var_name); + llvm::set_initializer(covfun_global, covfun_record); + llvm::set_global_constant(covfun_global, true); + llvm::set_linkage(covfun_global, llvm::Linkage::LinkOnceODRLinkage); + llvm::set_visibility(covfun_global, llvm::Visibility::Hidden); + llvm::set_section(covfun_global, cx.covfun_section_name()); // LLVM's coverage mapping format specifies 8-byte alignment for items in this section. // - llvm::set_alignment(llglobal, Align::EIGHT); + llvm::set_alignment(covfun_global, Align::EIGHT); if cx.target_spec().supports_comdat() { - llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name); + llvm::set_comdat(cx.llmod, covfun_global, &covfun_var_name); } - cx.add_used_global(llglobal); + + cx.add_used_global(covfun_global); } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index c81e36dfc8d0a..450a95ae20cdd 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -11,7 +11,6 @@ bitflags = "2.4.1" cc = "1.1.23" either = "1.5.0" itertools = "0.12" -jobserver = "0.1.28" pathdiff = "0.2.0" regex = "1.4" rustc_abi = { path = "../rustc_abi" } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 35d18d0206dbb..31ac8c6e66aae 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -236,7 +236,13 @@ pub fn each_linked_rlib( ) -> Result<(), errors::LinkRlibError> { let crates = info.used_crates.iter(); - let fmts = if crate_type.is_none() { + let fmts = if let Some(crate_type) = crate_type { + let Some(fmts) = info.dependency_formats.get(&crate_type) else { + return Err(errors::LinkRlibError::MissingFormat); + }; + + fmts + } else { for combination in info.dependency_formats.iter().combinations(2) { let (ty1, list1) = &combination[0]; let (ty2, list2) = &combination[1]; @@ -252,18 +258,7 @@ pub fn each_linked_rlib( if info.dependency_formats.is_empty() { return Err(errors::LinkRlibError::MissingFormat); } - &info.dependency_formats[0].1 - } else { - let fmts = info - .dependency_formats - .iter() - .find_map(|&(ty, ref list)| if Some(ty) == crate_type { Some(list) } else { None }); - - let Some(fmts) = fmts else { - return Err(errors::LinkRlibError::MissingFormat); - }; - - fmts + info.dependency_formats.first().unwrap().1 }; for &cnum in crates { @@ -624,8 +619,7 @@ fn link_staticlib( let fmts = codegen_results .crate_info .dependency_formats - .iter() - .find_map(|&(ty, ref list)| if ty == CrateType::Staticlib { Some(list) } else { None }) + .get(&CrateType::Staticlib) .expect("no dependency formats for staticlib"); let mut all_rust_dylibs = vec![]; @@ -2355,11 +2349,10 @@ fn linker_with_args( // they are used within inlined functions or instantiated generic functions. We do this *after* // handling the raw-dylib symbols in the current crate to make sure that those are chosen first // by the linker. - let (_, dependency_linkage) = codegen_results + let dependency_linkage = codegen_results .crate_info .dependency_formats - .iter() - .find(|(ty, _)| *ty == crate_type) + .get(&crate_type) .expect("failed to find crate type in dependency format list"); // We sort the libraries below @@ -2738,11 +2731,10 @@ fn add_upstream_rust_crates( // Linking to a rlib involves just passing it to the linker (the linker // will slurp up the object files inside), and linking to a dynamic library // involves just passing the right -l flag. - let (_, data) = codegen_results + let data = codegen_results .crate_info .dependency_formats - .iter() - .find(|(ty, _)| *ty == crate_type) + .get(&crate_type) .expect("failed to find crate type in dependency format list"); if sess.target.is_like_aix { diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 4c5eb98e890e8..301b22f2be4f8 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1749,7 +1749,7 @@ fn for_each_exported_symbols_include_dep<'tcx>( } let formats = tcx.dependency_formats(()); - let deps = formats.iter().find_map(|(t, list)| (*t == crate_type).then_some(list)).unwrap(); + let deps = &formats[&crate_type]; for (index, dep_format) in deps.iter().enumerate() { let cnum = CrateNum::new(index + 1); diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 501f751791936..683defcafee24 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -6,9 +6,9 @@ use std::sync::Arc; use std::sync::mpsc::{Receiver, Sender, channel}; use std::{fs, io, mem, str, thread}; -use jobserver::{Acquired, Client}; use rustc_ast::attr; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; +use rustc_data_structures::jobserver::{self, Acquired}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard}; use rustc_errors::emitter::Emitter; @@ -456,7 +456,6 @@ pub(crate) fn start_async_codegen( metadata_module: Option, ) -> OngoingCodegen { let (coordinator_send, coordinator_receive) = channel(); - let sess = tcx.sess; let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); @@ -477,7 +476,6 @@ pub(crate) fn start_async_codegen( shared_emitter, codegen_worker_send, coordinator_receive, - sess.jobserver.clone(), Arc::new(regular_config), Arc::new(metadata_config), Arc::new(allocator_config), @@ -1093,7 +1091,6 @@ fn start_executing_work( shared_emitter: SharedEmitter, codegen_worker_send: Sender, coordinator_receive: Receiver>, - jobserver: Client, regular_config: Arc, metadata_config: Arc, allocator_config: Arc, @@ -1145,7 +1142,7 @@ fn start_executing_work( // get tokens on `coordinator_receive` which will // get managed in the main loop below. let coordinator_send2 = coordinator_send.clone(); - let helper = jobserver + let helper = jobserver::client() .into_helper_thread(move |token| { drop(coordinator_send2.send(Box::new(Message::Token::(token)))); }) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index a180d5da9418b..9ac2a024ccf37 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -540,10 +540,14 @@ pub trait Machine<'tcx>: Sized { interp_ok(ReturnAction::Normal) } - /// Called immediately after an "immediate" local variable is read + /// Called immediately after an "immediate" local variable is read in a given frame /// (i.e., this is called for reads that do not end up accessing addressable memory). #[inline(always)] - fn after_local_read(_ecx: &InterpCx<'tcx, Self>, _local: mir::Local) -> InterpResult<'tcx> { + fn after_local_read( + _ecx: &InterpCx<'tcx, Self>, + _frame: &Frame<'tcx, Self::Provenance, Self::FrameExtra>, + _local: mir::Local, + ) -> InterpResult<'tcx> { interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 0157e6c2125e5..9d2a7125f5105 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -15,9 +15,9 @@ use rustc_middle::{bug, mir, span_bug, ty}; use tracing::trace; use super::{ - CtfeProvenance, InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, - PlaceTy, Pointer, Projectable, Provenance, Scalar, alloc_range, err_ub, from_known_layout, - interp_ok, mir_assign_valid_types, throw_ub, + CtfeProvenance, Frame, InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, + OffsetMode, PlaceTy, Pointer, Projectable, Provenance, Scalar, alloc_range, err_ub, + from_known_layout, interp_ok, mir_assign_valid_types, throw_ub, }; /// An `Immediate` represents a single immediate self-contained Rust value. @@ -706,23 +706,32 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(str) } - /// Read from a local of the current frame. + /// Read from a local of the current frame. Convenience method for [`InterpCx::local_at_frame_to_op`]. + pub fn local_to_op( + &self, + local: mir::Local, + layout: Option>, + ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { + self.local_at_frame_to_op(self.frame(), local, layout) + } + + /// Read from a local of a given frame. /// Will not access memory, instead an indirect `Operand` is returned. /// - /// This is public because it is used by [priroda](https://github.com/oli-obk/priroda) to get an - /// OpTy from a local. - pub fn local_to_op( + /// This is public because it is used by [Aquascope](https://github.com/cognitive-engineering-lab/aquascope/) + /// to get an OpTy from a local. + pub fn local_at_frame_to_op( &self, + frame: &Frame<'tcx, M::Provenance, M::FrameExtra>, local: mir::Local, layout: Option>, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { - let frame = self.frame(); let layout = self.layout_of_local(frame, local, layout)?; let op = *frame.locals[local].access()?; if matches!(op, Operand::Immediate(_)) { assert!(!layout.is_unsized()); } - M::after_local_read(self, local)?; + M::after_local_read(self, frame, local)?; interp_ok(OpTy { op, layout }) } diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index a9ebf38661703..6512675530a45 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -584,8 +584,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { interp_ok(()) } + /// This is public because it is used by [Aquascope](https://github.com/cognitive-engineering-lab/aquascope/) + /// to analyze all the locals in a stack frame. #[inline(always)] - pub(super) fn layout_of_local( + pub fn layout_of_local( &self, frame: &Frame<'tcx, M::Provenance, M::FrameExtra>, local: mir::Local, diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs index d09f7efc8ffff..1204f2d692d6c 100644 --- a/compiler/rustc_data_structures/src/jobserver.rs +++ b/compiler/rustc_data_structures/src/jobserver.rs @@ -1,6 +1,6 @@ use std::sync::{LazyLock, OnceLock}; -pub use jobserver_crate::Client; +pub use jobserver_crate::{Acquired, Client, HelperThread}; use jobserver_crate::{FromEnv, FromEnvErrorKind}; // We can only call `from_env_ext` once per process diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 2e01c385a6670..b8d5281087efa 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -350,6 +350,8 @@ fn run_compiler( callbacks.config(&mut config); + let registered_lints = config.register_lints.is_some(); + interface::run_compiler(config, |compiler| { let sess = &compiler.sess; let codegen_backend = &*compiler.codegen_backend; @@ -365,7 +367,7 @@ fn run_compiler( // `--help`/`-Zhelp`/`-Chelp`. This is the earliest it can run, because // it must happen after lints are registered, during session creation. if sess.opts.describe_lints { - describe_lints(sess); + describe_lints(sess, registered_lints); return early_exit(); } @@ -982,7 +984,7 @@ the command line flag directly. } /// Write to stdout lint command options, together with a list of all available lints -pub fn describe_lints(sess: &Session) { +pub fn describe_lints(sess: &Session, registered_lints: bool) { safe_println!( " Available lint options: @@ -1086,7 +1088,7 @@ Available lint options: print_lint_groups(builtin_groups, true); - match (sess.registered_lints, loaded.len(), loaded_groups.len()) { + match (registered_lints, loaded.len(), loaded_groups.len()) { (false, 0, _) | (false, _, 0) => { safe_println!("Lint tools like Clippy can load additional lints and lint groups."); } diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 25feb95d5dfeb..a2df0ba265c0e 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -246,6 +246,12 @@ hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty hir_analysis_invalid_receiver_ty_help = consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` +hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types = + consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +hir_analysis_invalid_receiver_ty_no_arbitrary_self_types = invalid `self` parameter type: `{$receiver_ty}` + .note = type of `self` must be `Self` or a type that dereferences to it + hir_analysis_invalid_union_field = field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union .note = union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>` diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 57264d0bd2afc..e6ef29de965a9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1748,9 +1748,15 @@ fn check_method_receiver<'tcx>( // Report error; would not have worked with `arbitrary_self_types[_pointers]`. { match receiver_validity_err { - ReceiverValidityError::DoesNotDeref => { + ReceiverValidityError::DoesNotDeref if arbitrary_self_types_level.is_some() => { tcx.dcx().emit_err(errors::InvalidReceiverTy { span, receiver_ty }) } + ReceiverValidityError::DoesNotDeref => { + tcx.dcx().emit_err(errors::InvalidReceiverTyNoArbitrarySelfTypes { + span, + receiver_ty, + }) + } ReceiverValidityError::MethodGenericParamUsed => { tcx.dcx().emit_err(errors::InvalidGenericReceiverTy { span, receiver_ty }) } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index debfe6af0fbf9..cb5086c9a659f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -201,12 +201,13 @@ pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>( placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect(); if let Some(generics) = generics { - if let Some(arg) = params.iter().find(|arg| { - matches!(arg.name, hir::ParamName::Plain(Ident { name: kw::Underscore, .. })) + if let Some(span) = params.iter().find_map(|arg| match arg.name { + hir::ParamName::Plain(Ident { name: kw::Underscore, span }) => Some(span), + _ => None, }) { // Account for `_` already present in cases like `struct S<_>(_);` and suggest // `struct S(T);` instead of `struct S<_, T>(T);`. - sugg.push((arg.span, (*type_name).to_string())); + sugg.push((span, (*type_name).to_string())); } else if let Some(span) = generics.span_for_param_suggestion() { // Account for bounds, we want `fn foo(_: K)` not `fn foo(_: K)`. sugg.push((span, format!(", {type_name}"))); diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 7f62ccc91f09a..5ab6faf3b7cea 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1655,6 +1655,16 @@ pub(crate) struct NonConstRange { pub span: Span, } +#[derive(Diagnostic)] +#[diag(hir_analysis_invalid_receiver_ty_no_arbitrary_self_types, code = E0307)] +#[note] +#[help(hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types)] +pub(crate) struct InvalidReceiverTyNoArbitrarySelfTypes<'tcx> { + #[primary_span] + pub span: Span, + pub receiver_ty: Ty<'tcx>, +} + #[derive(Diagnostic)] #[diag(hir_analysis_invalid_receiver_ty, code = E0307)] #[note] diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 2e227ead14a93..6e10450313cb4 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -9,7 +9,6 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_middle::bug; -use rustc_middle::query::Key; use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _}; use rustc_middle::ty::{ self, AdtDef, Binder, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeVisitableExt, @@ -1007,8 +1006,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )), .. }) = node - && let Some(ty_def_id) = qself_ty.ty_def_id() - && let [inherent_impl] = tcx.inherent_impls(ty_def_id) + && let Some(adt_def) = qself_ty.ty_adt_def() + && let [inherent_impl] = tcx.inherent_impls(adt_def.did()) && let name = format!("{ident2}_{ident3}") && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx .associated_items(inherent_impl) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 07ae24ee6d32b..91f190c6a28de 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -371,7 +371,6 @@ pub(crate) fn initialize_checked_jobserver(early_dcx: &EarlyDiagCtxt) { // JUSTIFICATION: before session exists, only config #[allow(rustc::bad_opt_access)] -#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Send) -> R { trace!("run_compiler"); @@ -425,7 +424,11 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.opts.unstable_opts.translate_directionality_markers, ) { Ok(bundle) => bundle, - Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")), + Err(e) => { + // We can't translate anything if we failed to load translations + #[allow(rustc::untranslatable_diagnostic)] + early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")) + } }; let mut locale_resources = config.locale_resources; @@ -479,7 +482,6 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints()); if let Some(register_lints) = config.register_lints.as_deref() { register_lints(&sess, &mut lint_store); - sess.registered_lints = true; } sess.lint_store = Some(Lrc::new(lint_store)); diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 641d1d8e79819..e8de0acb7c9fe 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -77,7 +77,7 @@ pub(crate) fn calculate(tcx: TyCtxt<'_>) -> Dependencies { verify_ok(tcx, &linkage); (ty, linkage) }) - .collect::>() + .collect() } fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e67db5d347836..df5b06c6d16f6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2161,10 +2161,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_dylib_dependency_formats(&mut self) -> LazyArray> { empty_proc_macro!(self); let formats = self.tcx.dependency_formats(()); - for (ty, arr) in formats.iter() { - if *ty != CrateType::Dylib { - continue; - } + if let Some(arr) = formats.get(&CrateType::Dylib) { return self.lazy_array(arr.iter().map(|slot| match *slot { Linkage::NotLinked | Linkage::IncludedFromDylib => None, diff --git a/compiler/rustc_middle/src/middle/dependency_format.rs b/compiler/rustc_middle/src/middle/dependency_format.rs index a3aff9a110130..e3b40b6415784 100644 --- a/compiler/rustc_middle/src/middle/dependency_format.rs +++ b/compiler/rustc_middle/src/middle/dependency_format.rs @@ -7,6 +7,7 @@ // FIXME: move this file to rustc_metadata::dependency_format, but // this will introduce circular dependency between rustc_metadata and rustc_middle +use rustc_data_structures::fx::FxIndexMap; use rustc_macros::{Decodable, Encodable, HashStable}; use rustc_session::config::CrateType; @@ -18,7 +19,7 @@ pub type DependencyList = Vec; /// A mapping of all required dependencies for a particular flavor of output. /// /// This is local to the tcx, and is generally relevant to one session. -pub type Dependencies = Vec<(CrateType, DependencyList)>; +pub type Dependencies = FxIndexMap; #[derive(Copy, Clone, PartialEq, Debug, HashStable, Encodable, Decodable)] pub enum Linkage { diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 970dc72e1ff61..66fec2dd0f7e8 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -41,7 +41,8 @@ pub trait Key: Sized { None } - fn ty_def_id(&self) -> Option { + /// Used to detect when ADT def ids are used as keys in a cycle for better error reporting. + fn def_id_for_ty_in_cycle(&self) -> Option { None } } @@ -423,7 +424,7 @@ impl<'tcx> Key for Ty<'tcx> { DUMMY_SP } - fn ty_def_id(&self) -> Option { + fn def_id_for_ty_in_cycle(&self) -> Option { match *self.kind() { ty::Adt(adt, _) => Some(adt.did()), ty::Coroutine(def_id, ..) => Some(def_id), @@ -471,8 +472,8 @@ impl<'tcx, T: Key> Key for ty::PseudoCanonicalInput<'tcx, T> { self.value.default_span(tcx) } - fn ty_def_id(&self) -> Option { - self.value.ty_def_id() + fn def_id_for_ty_in_cycle(&self) -> Option { + self.value.def_id_for_ty_in_cycle() } } @@ -593,7 +594,7 @@ impl<'tcx> Key for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx> DUMMY_SP } - fn ty_def_id(&self) -> Option { + fn def_id_for_ty_in_cycle(&self) -> Option { match self.1.value.kind() { ty::Adt(adt, _) => Some(adt.did()), _ => None, diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 48d744a9ef6cd..390909bb0ab0c 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -100,7 +100,7 @@ impl<'tcx> Value> for Representability { } for info in &cycle_error.cycle { if info.query.dep_kind == dep_kinds::representability_adt_ty - && let Some(def_id) = info.query.ty_def_id + && let Some(def_id) = info.query.def_id_for_ty_in_cycle && let Some(def_id) = def_id.as_local() && !item_and_field_ids.iter().any(|&(id, _)| id == def_id) { @@ -182,7 +182,7 @@ impl<'tcx, T> Value> for Result> &cycle_error.cycle, |cycle| { if cycle[0].query.dep_kind == dep_kinds::layout_of - && let Some(def_id) = cycle[0].query.ty_def_id + && let Some(def_id) = cycle[0].query.def_id_for_ty_in_cycle && let Some(def_id) = def_id.as_local() && let def_kind = tcx.def_kind(def_id) && matches!(def_kind, DefKind::Closure) @@ -209,7 +209,7 @@ impl<'tcx, T> Value> for Result> if frame.query.dep_kind != dep_kinds::layout_of { continue; } - let Some(frame_def_id) = frame.query.ty_def_id else { + let Some(frame_def_id) = frame.query.def_id_for_ty_in_cycle else { continue; }; let Some(frame_coroutine_kind) = tcx.coroutine_kind(frame_def_id) else { diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index f72f656b2f8f9..1b12af62ea5a9 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -349,9 +349,9 @@ pub(crate) fn create_query_frame< hasher.finish::() }) }; - let ty_def_id = key.ty_def_id(); + let def_id_for_ty_in_cycle = key.def_id_for_ty_in_cycle(); - QueryStackFrame::new(description, span, def_id, def_kind, kind, ty_def_id, hash) + QueryStackFrame::new(description, span, def_id, def_kind, kind, def_id_for_ty_in_cycle, hash) } pub(crate) fn encode_query_results<'a, 'tcx, Q>( diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index b81386f06ec7a..82c51193a19d3 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -33,7 +33,7 @@ pub struct QueryStackFrame { pub def_id: Option, pub def_kind: Option, /// A def-id that is extracted from a `Ty` in a query key - pub ty_def_id: Option, + pub def_id_for_ty_in_cycle: Option, pub dep_kind: DepKind, /// This hash is used to deterministically pick /// a query to remove cycles in the parallel compiler. @@ -48,10 +48,10 @@ impl QueryStackFrame { def_id: Option, def_kind: Option, dep_kind: DepKind, - ty_def_id: Option, + def_id_for_ty_in_cycle: Option, hash: impl FnOnce() -> Hash64, ) -> Self { - Self { description, span, def_id, def_kind, ty_def_id, dep_kind, hash: hash() } + Self { description, span, def_id, def_kind, def_id_for_ty_in_cycle, dep_kind, hash: hash() } } // FIXME(eddyb) Get more valid `Span`s on queries. diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 993d111466bed..9f6106f9cfb7e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -8,7 +8,6 @@ use std::{env, fmt, io}; use rustc_data_structures::flock; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; -use rustc_data_structures::jobserver::{self, Client}; use rustc_data_structures::profiling::{SelfProfiler, SelfProfilerRef}; use rustc_data_structures::sync::{ DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock, @@ -154,16 +153,9 @@ pub struct Session { /// Data about code being compiled, gathered during compilation. pub code_stats: CodeStats, - /// Loaded up early on in the initialization of this `Session` to avoid - /// false positives about a job server in our environment. - pub jobserver: Client, - /// This only ever stores a `LintStore` but we don't want a dependency on that type here. pub lint_store: Option>, - /// Should be set if any lints are registered in `lint_store`. - pub registered_lints: bool, - /// Cap lint level specified by a driver specifically. pub driver_lint_caps: FxHashMap, @@ -1072,9 +1064,7 @@ pub fn build_session( incr_comp_session: RwLock::new(IncrCompSession::NotInitialized), prof, code_stats: Default::default(), - jobserver: jobserver::client(), lint_store: None, - registered_lints: false, driver_lint_caps, ctfe_backtrace, miri_unleashed_features: Lock::new(Default::default()), diff --git a/library/std/src/sys/pal/hermit/fs.rs b/library/std/src/sys/pal/hermit/fs.rs index 11862a076082d..88fc40687195d 100644 --- a/library/std/src/sys/pal/hermit/fs.rs +++ b/library/std/src/sys/pal/hermit/fs.rs @@ -3,7 +3,7 @@ use super::hermit_abi::{ self, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG, dirent64, stat as stat_struct, }; -use crate::ffi::{CStr, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString, c_char}; use crate::io::{self, BorrowedCursor, Error, ErrorKind, IoSlice, IoSliceMut, SeekFrom}; use crate::os::hermit::ffi::OsStringExt; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; @@ -204,7 +204,7 @@ impl Iterator for ReadDir { // the size of dirent64. The file name is always a C string and terminated by `\0`. // Consequently, we are able to ignore the last byte. let name_bytes = - unsafe { CStr::from_ptr(&dir.d_name as *const _ as *const i8).to_bytes() }; + unsafe { CStr::from_ptr(&dir.d_name as *const _ as *const c_char).to_bytes() }; let entry = DirEntry { root: self.inner.root.clone(), ino: dir.d_ino, @@ -445,7 +445,7 @@ impl DirBuilder { pub fn mkdir(&self, path: &Path) -> io::Result<()> { run_path_with_cstr(path, &|path| { - cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode.into()) }).map(|_| ()) + cvt(unsafe { hermit_abi::mkdir(path.as_ptr().cast(), self.mode.into()) }).map(|_| ()) }) } diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index f03fca603441d..d833c9d632c6d 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -85,7 +85,7 @@ pub unsafe extern "C" fn runtime_entry( } // initialize environment - os::init_environment(env as *const *const i8); + os::init_environment(env); let result = unsafe { main(argc as isize, argv) }; diff --git a/library/std/src/sys/pal/hermit/os.rs b/library/std/src/sys/pal/hermit/os.rs index f8ea80afa43f1..791cdb1e57e7d 100644 --- a/library/std/src/sys/pal/hermit/os.rs +++ b/library/std/src/sys/pal/hermit/os.rs @@ -3,7 +3,7 @@ use core::slice::memchr; use super::hermit_abi; use crate::collections::HashMap; use crate::error::Error as StdError; -use crate::ffi::{CStr, OsStr, OsString}; +use crate::ffi::{CStr, OsStr, OsString, c_char}; use crate::marker::PhantomData; use crate::os::hermit::ffi::OsStringExt; use crate::path::{self, PathBuf}; @@ -70,7 +70,7 @@ pub fn current_exe() -> io::Result { static ENV: Mutex>> = Mutex::new(None); -pub fn init_environment(env: *const *const i8) { +pub fn init_environment(env: *const *const c_char) { let mut guard = ENV.lock().unwrap(); let map = guard.insert(HashMap::new()); diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index 91b31f31ab192..2c26ffa76f6a8 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -423,6 +423,14 @@ pub(crate) fn build_index( } Some(path) }); + } else if let Some(parent_idx) = item.parent_idx { + let i = >::try_into(parent_idx).unwrap(); + item.path = { + let p = &crate_paths[i].1; + join_with_double_colon(&p[..p.len() - 1]) + }; + item.exact_path = + crate_paths[i].2.as_ref().map(|xp| join_with_double_colon(&xp[..xp.len() - 1])); } // Omit the parent path if it is same to that of the prior item. diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index a384c286039d2..5d82b8e309a6a 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -846,11 +846,13 @@ fn main_args( let config = core::create_config(input, options, &render_options, using_internal_features); + let registered_lints = config.register_lints.is_some(); + interface::run_compiler(config, |compiler| { let sess = &compiler.sess; if sess.opts.describe_lints { - rustc_driver::describe_lints(sess); + rustc_driver::describe_lints(sess, registered_lints); return; } diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs index 3de51bc661eb7..5b9e9e70e4770 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs @@ -3,13 +3,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::ty::is_copy; use clippy_utils::usage::mutated_variables; use clippy_utils::visitors::{Descend, for_each_expr_without_closures}; -use clippy_utils::{MaybePath, is_res_lang_ctor, is_trait_method, path_res, path_to_local_id}; +use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_lint::LateContext; -use rustc_middle::query::Key; use rustc_middle::ty; use rustc_span::sym; @@ -44,7 +43,6 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a if name == "filter_map" && let hir::ExprKind::Call(expr, args) = body.value.kind && is_res_lang_ctor(cx, path_res(cx, expr), OptionSome) - && arg_id.ty_def_id() == args[0].hir_id().ty_def_id() && let hir::ExprKind::Path(_) = args[0].kind { span_lint_and_sugg( diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index b57ce4e070c38..1f7c60ad1bdfe 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -149,10 +149,9 @@ pub fn iter_exported_symbols<'tcx>( let dependency_formats = tcx.dependency_formats(()); // Find the dependencies of the executable we are running. let dependency_format = dependency_formats - .iter() - .find(|(crate_type, _)| *crate_type == CrateType::Executable) + .get(&CrateType::Executable) .expect("interpreting a non-executable crate"); - for cnum in dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| { + for cnum in dependency_format.iter().enumerate().filter_map(|(num, &linkage)| { // We add 1 to the number because that's what rustc also does everywhere it // calls `CrateNum::new`... #[expect(clippy::arithmetic_side_effects)] diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 7cc22f83a24a6..ac26feb345c18 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1571,8 +1571,12 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> { res } - fn after_local_read(ecx: &InterpCx<'tcx, Self>, local: mir::Local) -> InterpResult<'tcx> { - if let Some(data_race) = &ecx.frame().extra.data_race { + fn after_local_read( + ecx: &InterpCx<'tcx, Self>, + frame: &Frame<'tcx, Provenance, FrameExtra<'tcx>>, + local: mir::Local, + ) -> InterpResult<'tcx> { + if let Some(data_race) = &frame.extra.data_race { data_race.local_read(local, &ecx.machine); } interp_ok(()) diff --git a/tests/crashes/123861.rs b/tests/crashes/123861.rs deleted file mode 100644 index 60245960af0d6..0000000000000 --- a/tests/crashes/123861.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: #123861 -//@ needs-rustc-debug-assertions - -struct _; -fn mainIterator<_ = _> {} diff --git a/tests/rustdoc-js-std/osstring-to-string.js b/tests/rustdoc-js-std/osstring-to-string.js index 3fdc0b9f24a3c..17bb602a502af 100644 --- a/tests/rustdoc-js-std/osstring-to-string.js +++ b/tests/rustdoc-js-std/osstring-to-string.js @@ -4,6 +4,6 @@ const EXPECTED = { 'query': 'OsString -> String', 'others': [ - { 'path': 'std::ffi::os_str::OsString', 'name': 'into_string' }, + { 'path': 'std::ffi::OsString', 'name': 'into_string' }, ] }; diff --git a/tests/rustdoc-js/reexport.js b/tests/rustdoc-js/reexport.js index 9021cc2e90fe0..0b9415dd3e480 100644 --- a/tests/rustdoc-js/reexport.js +++ b/tests/rustdoc-js/reexport.js @@ -14,4 +14,13 @@ const EXPECTED = [ { 'path': 'reexport', 'name': 'AnotherOne' }, ], }, + { + 'query': 'fn:Equivalent::equivalent', + 'others': [ + // These results must never contain `reexport::equivalent::NotEquivalent`, + // since that path does not exist. + { 'path': 'equivalent::Equivalent', 'name': 'equivalent' }, + { 'path': 'reexport::NotEquivalent', 'name': 'equivalent' }, + ], + }, ]; diff --git a/tests/rustdoc-js/reexport.rs b/tests/rustdoc-js/reexport.rs index 0b3718cd9a3e8..ecbbeca5ea89d 100644 --- a/tests/rustdoc-js/reexport.rs +++ b/tests/rustdoc-js/reexport.rs @@ -2,6 +2,15 @@ // This is a DWIM case, since renaming the export probably means the intent is also different. // For the de-duplication case of exactly the same name, see reexport-dedup +//@ aux-crate:equivalent=equivalent.rs +//@ compile-flags: --extern equivalent +//@ aux-build:equivalent.rs +//@ build-aux-docs +#[doc(inline)] +pub extern crate equivalent; +#[doc(inline)] +pub use equivalent::Equivalent as NotEquivalent; + pub mod fmt { pub struct Subscriber; } diff --git a/tests/ui/async-await/inference_var_self_argument.stderr b/tests/ui/async-await/inference_var_self_argument.stderr index a33c5f7b07dca..7b7b3dbc757f1 100644 --- a/tests/ui/async-await/inference_var_self_argument.stderr +++ b/tests/ui/async-await/inference_var_self_argument.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `&dyn Foo` LL | async fn foo(self: &dyn Foo) { | ^^^^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/inference_var_self_argument.rs:5:5 diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr index f4db949a5f430..c95ae1147df36 100644 --- a/tests/ui/async-await/issue-66312.stderr +++ b/tests/ui/async-await/issue-66312.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `T` LL | fn is_some(self: T); | ^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0308]: mismatched types --> $DIR/issue-66312.rs:9:8 diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr index eb9e51a04c394..2150effc3b74d 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Cell<&Self>` LL | fn cell(self: Cell<&Self>); | ^^^^^^^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to 1 previous error diff --git a/tests/ui/generics/overlapping-errors-span-issue-123861.rs b/tests/ui/generics/overlapping-errors-span-issue-123861.rs new file mode 100644 index 0000000000000..e0a27f6874874 --- /dev/null +++ b/tests/ui/generics/overlapping-errors-span-issue-123861.rs @@ -0,0 +1,8 @@ +fn mainIterator<_ = _> {} +//~^ ERROR expected identifier, found reserved identifier `_` +//~| ERROR missing parameters for function definition +//~| ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions [invalid_type_param_default] +//~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +//~| ERROR the placeholder `_` is not allowed within types on item signatures for functions [E0121] + +fn main() {} diff --git a/tests/ui/generics/overlapping-errors-span-issue-123861.stderr b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr new file mode 100644 index 0000000000000..e0a49343b0e0d --- /dev/null +++ b/tests/ui/generics/overlapping-errors-span-issue-123861.stderr @@ -0,0 +1,52 @@ +error: expected identifier, found reserved identifier `_` + --> $DIR/overlapping-errors-span-issue-123861.rs:1:17 + | +LL | fn mainIterator<_ = _> {} + | ^ expected identifier, found reserved identifier + +error: missing parameters for function definition + --> $DIR/overlapping-errors-span-issue-123861.rs:1:23 + | +LL | fn mainIterator<_ = _> {} + | ^ + | +help: add a parameter list + | +LL | fn mainIterator<_ = _>() {} + | ++ + +error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/overlapping-errors-span-issue-123861.rs:1:17 + | +LL | fn mainIterator<_ = _> {} + | ^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + = note: `#[deny(invalid_type_param_default)]` on by default + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/overlapping-errors-span-issue-123861.rs:1:21 + | +LL | fn mainIterator<_ = _> {} + | ^ not allowed in type signatures + | +help: use type parameters instead + | +LL | fn mainIterator {} + | ~ ~ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0121`. +Future incompatibility report: Future breakage diagnostic: +error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions + --> $DIR/overlapping-errors-span-issue-123861.rs:1:17 + | +LL | fn mainIterator<_ = _> {} + | ^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #36887 + = note: `#[deny(invalid_type_param_default)]` on by default + diff --git a/tests/ui/issues/issue-56806.stderr b/tests/ui/issues/issue-56806.stderr index 4b0a59fe12def..ec50d863758db 100644 --- a/tests/ui/issues/issue-56806.stderr +++ b/tests/ui/issues/issue-56806.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Box<(dyn Trait + 'static)>` LL | fn dyn_instead_of_self(self: Box); | ^^^^^^^^^^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to 1 previous error diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr index 0469aca27dc81..c75165d9f8e27 100644 --- a/tests/ui/self/arbitrary-self-opaque.stderr +++ b/tests/ui/self/arbitrary-self-opaque.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn foo(self: Bar) {} | ^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: item does not constrain `Bar::{opaque#0}`, but has it in its signature --> $DIR/arbitrary-self-opaque.rs:7:8 diff --git a/tests/ui/span/issue-27522.stderr b/tests/ui/span/issue-27522.stderr index 04904b0ddc1c5..c57a100bbe227 100644 --- a/tests/ui/span/issue-27522.stderr +++ b/tests/ui/span/issue-27522.stderr @@ -4,8 +4,8 @@ error[E0307]: invalid `self` parameter type: `&SomeType` LL | fn handler(self: &SomeType); | ^^^^^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr index eb9f9196a7234..beafd7c2ab00f 100644 --- a/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr +++ b/tests/ui/suggestions/dyn-incompatible-trait-should-use-where-sized.stderr @@ -32,8 +32,8 @@ error[E0307]: invalid `self` parameter type: `()` LL | fn bar(self: ()) {} | ^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error: aborting due to 2 previous errors diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 1c58915111f2c..86234d15a5d4b 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -61,8 +61,8 @@ error[E0307]: invalid `self` parameter type: `Smaht` LL | fn foo(self: Smaht); | ^^^^^^^^^^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures --> $DIR/issue-78372.rs:3:1 diff --git a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr index 36bdc714e050b..2a8c4edbdb5f3 100644 --- a/tests/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/tests/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -22,8 +22,8 @@ error[E0307]: invalid `self` parameter type: `isize` LL | fn foo(self: isize, x: isize) -> isize { | ^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0307]: invalid `self` parameter type: `Bar` --> $DIR/ufcs-explicit-self-bad.rs:19:18 @@ -31,8 +31,8 @@ error[E0307]: invalid `self` parameter type: `Bar` LL | fn foo(self: Bar, x: isize) -> isize { | ^^^^^^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0307]: invalid `self` parameter type: `&Bar` --> $DIR/ufcs-explicit-self-bad.rs:23:18 @@ -40,8 +40,8 @@ error[E0307]: invalid `self` parameter type: `&Bar` LL | fn bar(self: &Bar, x: isize) -> isize { | ^^^^^^^^^^^ | - = note: type of `self` must be `Self` or some type implementing `Receiver` - = help: consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box`, `self: Rc`, or `self: Arc` + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) error[E0308]: mismatched `self` parameter type --> $DIR/ufcs-explicit-self-bad.rs:37:21