Auto merge of #147198 - matthiaskrgr:rollup-b0ryvvu, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang/rust#143069 (Add fast-path for accessing the current thread id)
 - rust-lang/rust#146518 (Improve the documentation around `ZERO_AR_DATE`)
 - rust-lang/rust#146596 (Add a dummy codegen backend)
 - rust-lang/rust#146617 (Don’t suggest foreign `doc(hidden)` types in "the following other types implement trait" diagnostics)
 - rust-lang/rust#146635 (cg_llvm: Stop using `as_c_char_ptr` for coverage-related bindings)
 - rust-lang/rust#147184 (Fix the bevy implied bounds hack for the next solver)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-10-01 04:46:14 +00:00
commit 1e1a39441b
14 changed files with 246 additions and 48 deletions

View file

@ -2,26 +2,25 @@
use std::ffi::CString;
use crate::common::AsCCharPtr;
use crate::coverageinfo::ffi;
use crate::llvm;
pub(crate) fn covmap_var_name() -> CString {
CString::new(llvm::build_byte_buffer(|s| unsafe {
CString::new(llvm::build_byte_buffer(|s| {
llvm::LLVMRustCoverageWriteCovmapVarNameToString(s);
}))
.expect("covmap variable name should not contain NUL")
}
pub(crate) fn covmap_section_name(llmod: &llvm::Module) -> CString {
CString::new(llvm::build_byte_buffer(|s| unsafe {
CString::new(llvm::build_byte_buffer(|s| {
llvm::LLVMRustCoverageWriteCovmapSectionNameToString(llmod, s);
}))
.expect("covmap section name should not contain NUL")
}
pub(crate) fn covfun_section_name(llmod: &llvm::Module) -> CString {
CString::new(llvm::build_byte_buffer(|s| unsafe {
CString::new(llvm::build_byte_buffer(|s| {
llvm::LLVMRustCoverageWriteCovfunSectionNameToString(llmod, s);
}))
.expect("covfun section name should not contain NUL")
@ -34,7 +33,7 @@ pub(crate) fn create_pgo_func_name_var<'ll>(
unsafe {
llvm::LLVMRustCoverageCreatePGOFuncNameVar(
llfn,
mangled_fn_name.as_c_char_ptr(),
mangled_fn_name.as_ptr(),
mangled_fn_name.len(),
)
}
@ -44,7 +43,7 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef<str>]) -> Vec<u8
let (pointers, lengths) = filenames
.into_iter()
.map(AsRef::as_ref)
.map(|s: &str| (s.as_c_char_ptr(), s.len()))
.map(|s: &str| (s.as_ptr(), s.len()))
.unzip::<_, _, Vec<_>, Vec<_>>();
llvm::build_byte_buffer(|buffer| unsafe {
@ -89,12 +88,12 @@ pub(crate) fn write_function_mappings_to_buffer(
/// Hashes some bytes into a 64-bit hash, via LLVM's `IndexedInstrProf::ComputeHash`,
/// as required for parts of the LLVM coverage mapping format.
pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 {
unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_c_char_ptr(), bytes.len()) }
unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_ptr(), bytes.len()) }
}
/// Returns LLVM's `coverage::CovMapVersion::CurrentVersion` (CoverageMapping.h)
/// as a raw numeric value. For historical reasons, the numeric value is 1 less
/// than the number in the version's name, so `Version7` is actually `6u32`.
pub(crate) fn mapping_version() -> u32 {
unsafe { llvm::LLVMRustCoverageMappingVersion() }
llvm::LLVMRustCoverageMappingVersion()
}

View file

@ -2226,8 +2226,11 @@ unsafe extern "C" {
ConstraintsLen: size_t,
) -> bool;
/// A list of pointer-length strings is passed as two pointer-length slices,
/// one slice containing pointers and one slice containing their corresponding
/// lengths. The implementation will check that both slices have the same length.
pub(crate) fn LLVMRustCoverageWriteFilenamesToBuffer(
Filenames: *const *const c_char,
Filenames: *const *const c_uchar, // See "PTR_LEN_STR".
FilenamesLen: size_t,
Lengths: *const size_t,
LengthsLen: size_t,
@ -2250,18 +2253,25 @@ unsafe extern "C" {
pub(crate) fn LLVMRustCoverageCreatePGOFuncNameVar(
F: &Value,
FuncName: *const c_char,
FuncName: *const c_uchar, // See "PTR_LEN_STR".
FuncNameLen: size_t,
) -> &Value;
pub(crate) fn LLVMRustCoverageHashBytes(Bytes: *const c_char, NumBytes: size_t) -> u64;
pub(crate) fn LLVMRustCoverageHashBytes(
Bytes: *const c_uchar, // See "PTR_LEN_STR".
NumBytes: size_t,
) -> u64;
pub(crate) fn LLVMRustCoverageWriteCovmapSectionNameToString(M: &Module, OutStr: &RustString);
pub(crate) safe fn LLVMRustCoverageWriteCovmapSectionNameToString(
M: &Module,
OutStr: &RustString,
);
pub(crate) safe fn LLVMRustCoverageWriteCovfunSectionNameToString(
M: &Module,
OutStr: &RustString,
);
pub(crate) safe fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
pub(crate) fn LLVMRustCoverageWriteCovfunSectionNameToString(M: &Module, OutStr: &RustString);
pub(crate) fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString);
pub(crate) fn LLVMRustCoverageMappingVersion() -> u32;
pub(crate) safe fn LLVMRustCoverageMappingVersion() -> u32;
pub(crate) fn LLVMRustDebugMetadataVersion() -> u32;
pub(crate) fn LLVMRustVersionMajor() -> u32;
pub(crate) fn LLVMRustVersionMinor() -> u32;

View file

@ -170,6 +170,10 @@ impl<'tcx> InferCtxt<'tcx> {
std::mem::take(&mut self.inner.borrow_mut().region_obligations)
}
pub fn clone_registered_region_obligations(&self) -> Vec<TypeOutlivesConstraint<'tcx>> {
self.inner.borrow().region_obligations.clone()
}
pub fn register_region_assumption(&self, assumption: ty::ArgOutlivesPredicate<'tcx>) {
let mut inner = self.inner.borrow_mut();
inner.undo_log.push(UndoLog::PushRegionAssumption);

View file

@ -1,3 +1,4 @@
use std::any::Any;
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering};
@ -6,13 +7,20 @@ use std::{env, thread};
use rustc_ast as ast;
use rustc_attr_parsing::{ShouldEmit, validate_attr};
use rustc_codegen_ssa::back::archive::ArArchiveBuilderBuilder;
use rustc_codegen_ssa::back::link::link_binary;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::{CodegenResults, CrateInfo};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::jobserver::Proxy;
use rustc_data_structures::sync;
use rustc_errors::LintBuffer;
use rustc_metadata::{DylibError, load_symbol_from_dylib};
use rustc_middle::ty::CurrentGcx;
use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple};
use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib};
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::{CurrentGcx, TyCtxt};
use rustc_session::config::{
Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple,
};
use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
use rustc_session::{EarlyDiagCtxt, Session, filesearch, lint};
use rustc_span::edit_distance::find_best_match_for_name;
@ -316,12 +324,13 @@ pub fn get_codegen_backend(
let backend = backend_name
.or(target.default_codegen_backend.as_deref())
.or(option_env!("CFG_DEFAULT_CODEGEN_BACKEND"))
.unwrap_or("llvm");
.unwrap_or("dummy");
match backend {
filename if filename.contains('.') => {
load_backend_from_dylib(early_dcx, filename.as_ref())
}
"dummy" => || Box::new(DummyCodegenBackend),
#[cfg(feature = "llvm")]
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name),
@ -334,6 +343,63 @@ pub fn get_codegen_backend(
unsafe { load() }
}
struct DummyCodegenBackend;
impl CodegenBackend for DummyCodegenBackend {
fn locale_resource(&self) -> &'static str {
""
}
fn name(&self) -> &'static str {
"dummy"
}
fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any> {
Box::new(CodegenResults {
modules: vec![],
allocator_module: None,
crate_info: CrateInfo::new(tcx, String::new()),
})
}
fn join_codegen(
&self,
ongoing_codegen: Box<dyn Any>,
_sess: &Session,
_outputs: &OutputFilenames,
) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
(*ongoing_codegen.downcast().unwrap(), FxIndexMap::default())
}
fn link(
&self,
sess: &Session,
codegen_results: CodegenResults,
metadata: EncodedMetadata,
outputs: &OutputFilenames,
) {
// JUSTIFICATION: TyCtxt no longer available here
#[allow(rustc::bad_opt_access)]
if sess.opts.crate_types.iter().any(|&crate_type| crate_type != CrateType::Rlib) {
#[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)]
sess.dcx().fatal(format!(
"crate type {} not supported by the dummy codegen backend",
sess.opts.crate_types[0],
));
}
link_binary(
sess,
&ArArchiveBuilderBuilder,
codegen_results,
metadata,
outputs,
self.name(),
);
}
}
// This is used for rustdoc, but it uses similar machinery to codegen backend
// loading, so we leave the code here. It is potentially useful for other tools
// that want to invoke the rustc binary while linking to rustc as well.

View file

@ -158,12 +158,22 @@ pub(crate) fn base(
SplitDebuginfo::Off,
]),
// Tell the linker that we would like it to avoid irreproducible binaries.
//
// This environment variable is pretty magical but is intended for
// producing deterministic builds. This was first discovered to be used
// by the `ar` tool as a way to control whether or not mtime entries in
// the archive headers were set to zero or not. It appears that
// eventually the linker got updated to do the same thing and now reads
// this environment variable too in recent versions.
// the archive headers were set to zero or not.
//
// In `ld64-351.8`, shipped with Xcode 9.3, the linker was updated to
// read this flag too. Linker versions that don't support this flag
// may embed modification timestamps in binaries (especially in debug
// information).
//
// A cleaner alternative would be to pass the `-reproducible` flag,
// though that is only supported since `ld64-819.6` shipped with Xcode
// 14, which is too new for our minimum supported version:
// https://doc.rust-lang.org/rustc/platform-support/apple-darwin.html#host-tooling
//
// For some more info see the commentary on #47086
link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),

View file

@ -1897,6 +1897,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
other: bool,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
let parent_map = self.tcx.visible_parent_map(());
let alternative_candidates = |def_id: DefId| {
let mut impl_candidates: Vec<_> = self
.tcx
@ -1921,7 +1922,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// FIXME(compiler-errors): This could be generalized, both to
// be more granular, and probably look past other `#[fundamental]`
// types, too.
self.tcx.visibility(def.did()).is_accessible_from(body_def_id, self.tcx)
let mut did = def.did();
if self.tcx.visibility(did).is_accessible_from(body_def_id, self.tcx) {
// don't suggest foreign `#[doc(hidden)]` types
if !did.is_local() {
while let Some(parent) = parent_map.get(&did) {
if self.tcx.is_doc_hidden(did) {
return false;
}
did = *parent;
}
}
true
} else {
false
}
} else {
true
}

View file

@ -55,6 +55,12 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
span: Span,
disable_implied_bounds_hack: bool,
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
// Inside mir borrowck, each computation starts with an empty list.
assert!(
ocx.infcx.inner.borrow().region_obligations().is_empty(),
"compute_implied_outlives_bounds assumes region obligations are empty before starting"
);
let normalize_ty = |ty| -> Result<_, NoSolution> {
// We must normalize the type so we can compute the right outlives components.
// for example, if we have some constrained param type like `T: Trait<Out = U>`,
@ -143,7 +149,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
&& ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break()
{
for TypeOutlivesConstraint { sup_type, sub_region, .. } in
ocx.infcx.take_registered_region_obligations()
ocx.infcx.clone_registered_region_obligations()
{
let mut components = smallvec![];
push_outlives_components(ocx.infcx.tcx, sup_type, &mut components);

View file

@ -133,12 +133,32 @@ pub(super) fn set_current(thread: Thread) -> Result<(), Thread> {
Ok(())
}
/// Gets the id of the thread that invokes it.
/// Gets the unique identifier of the thread which invokes it.
///
/// Calling this function may be more efficient than accessing the current
/// thread id through the current thread handle. i.e. `thread::current().id()`.
///
/// This function will always succeed, will always return the same value for
/// one thread and is guaranteed not to call the global allocator.
///
/// # Examples
///
/// ```
/// #![feature(current_thread_id)]
///
/// use std::thread;
///
/// let other_thread = thread::spawn(|| {
/// thread::current_id()
/// });
///
/// let other_thread_id = other_thread.join().unwrap();
/// assert_ne!(thread::current_id(), other_thread_id);
/// ```
#[inline]
pub(crate) fn current_id() -> ThreadId {
#[must_use]
#[unstable(feature = "current_thread_id", issue = "147194")]
pub fn current_id() -> ThreadId {
// If accessing the persistent thread ID takes multiple TLS accesses, try
// to retrieve it from the current thread handle, which will only take one
// TLS access.

View file

@ -183,7 +183,9 @@ mod current;
#[stable(feature = "rust1", since = "1.0.0")]
pub use current::current;
pub(crate) use current::{current_id, current_or_unnamed, current_os_id, drop_current};
#[unstable(feature = "current_thread_id", issue = "147194")]
pub use current::current_id;
pub(crate) use current::{current_or_unnamed, current_os_id, drop_current};
use current::{set_current, try_with_current};
mod spawnhook;

View file

@ -1,6 +1,8 @@
#![crate_name = "bevy_ecs"]
//@ check-pass
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
#![crate_name = "bevy_ecs"]
// We currently special case bevy from erroring on incorrect implied bounds
// from normalization (issue #109628).

View file

@ -15,8 +15,8 @@ LL | let _ = quote! { $ip };
Cow<'_, T>
Option<T>
Rc<T>
RepInterp<T>
and 25 others
bool
and 24 others
error: aborting due to 1 previous error

View file

@ -1,3 +1,5 @@
// `Foo` and `Bar` should not be suggested in diagnostics of dependents
#[doc(hidden)]
pub mod hidden {
pub struct Foo;
@ -5,13 +7,29 @@ pub mod hidden {
pub mod hidden1 {
#[doc(hidden)]
pub struct Foo;
}
#[doc(hidden)]
pub(crate) mod hidden2 {
pub struct Bar;
}
pub use hidden2::Bar;
// `Baz` and `Quux` *should* be suggested in diagnostics of dependents
#[doc(hidden)]
pub mod hidden2 {
pub struct Baz;
}
pub use hidden2::Baz;
#[doc(hidden)]
pub(crate) mod hidden3 {
pub struct Quux;
}
pub use hidden3::Quux;
pub trait Marker {}
impl Marker for Option<u32> {}
impl Marker for hidden::Foo {}
impl Marker for hidden1::Bar {}
impl Marker for Baz {}
impl Marker for Quux {}

View file

@ -1,5 +1,4 @@
//@ aux-build:hidden-struct.rs
//@ compile-flags: --crate-type lib
extern crate hidden_struct;
@ -9,7 +8,20 @@ mod local {
}
pub fn test(_: Foo) {}
//~^ ERROR cannot find type `Foo` in this scope
//~^ ERROR [E0412]
pub fn test2(_: Bar) {}
//~^ ERROR cannot find type `Bar` in this scope
//~^ ERROR [E0412]
pub fn test3(_: Baz) {}
//~^ ERROR [E0412]
pub fn test4(_: Quux) {}
//~^ ERROR [E0412]
fn test5<T: hidden_struct::Marker>() {}
fn main() {
test5::<i32>();
//~^ ERROR [E0277]
}

View file

@ -1,5 +1,5 @@
error[E0412]: cannot find type `Foo` in this scope
--> $DIR/dont-suggest-foreign-doc-hidden.rs:11:16
--> $DIR/dont-suggest-foreign-doc-hidden.rs:10:16
|
LL | pub fn test(_: Foo) {}
| ^^^ not found in this scope
@ -10,16 +10,50 @@ LL + use local::Foo;
|
error[E0412]: cannot find type `Bar` in this scope
--> $DIR/dont-suggest-foreign-doc-hidden.rs:14:17
--> $DIR/dont-suggest-foreign-doc-hidden.rs:13:17
|
LL | pub fn test2(_: Bar) {}
| ^^^ not found in this scope
error[E0412]: cannot find type `Baz` in this scope
--> $DIR/dont-suggest-foreign-doc-hidden.rs:16:17
|
LL | pub fn test3(_: Baz) {}
| ^^^ not found in this scope
|
help: consider importing this struct
|
LL + use hidden_struct::Bar;
LL + use hidden_struct::Baz;
|
error: aborting due to 2 previous errors
error[E0412]: cannot find type `Quux` in this scope
--> $DIR/dont-suggest-foreign-doc-hidden.rs:19:17
|
LL | pub fn test4(_: Quux) {}
| ^^^^ not found in this scope
|
help: consider importing this struct
|
LL + use hidden_struct::Quux;
|
For more information about this error, try `rustc --explain E0412`.
error[E0277]: the trait bound `i32: Marker` is not satisfied
--> $DIR/dont-suggest-foreign-doc-hidden.rs:25:13
|
LL | test5::<i32>();
| ^^^ the trait `Marker` is not implemented for `i32`
|
= help: the following other types implement trait `Marker`:
Baz
Option<u32>
Quux
note: required by a bound in `test5`
--> $DIR/dont-suggest-foreign-doc-hidden.rs:22:13
|
LL | fn test5<T: hidden_struct::Marker>() {}
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5`
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0412.
For more information about an error, try `rustc --explain E0277`.