Skip to content
15 changes: 7 additions & 8 deletions compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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(),
)
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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()
}
28 changes: 19 additions & 9 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2256,8 +2256,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,
Expand All @@ -2280,18 +2283,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) fn LLVMRustCoverageWriteCovfunSectionNameToString(M: &Module, OutStr: &RustString);

pub(crate) fn LLVMRustCoverageWriteCovmapVarNameToString(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 LLVMRustCoverageMappingVersion() -> u32;
pub(crate) safe fn LLVMRustCoverageMappingVersion() -> u32;
pub(crate) fn LLVMRustDebugMetadataVersion() -> u32;
pub(crate) fn LLVMRustVersionMajor() -> u32;
pub(crate) fn LLVMRustVersionMinor() -> u32;
Expand Down
74 changes: 70 additions & 4 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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;
Expand Down Expand Up @@ -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),
Expand All @@ -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.
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_target/src/spec/base/apple/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))]),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/proc-macro/quote/not-quotable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
26 changes: 22 additions & 4 deletions tests/ui/suggestions/auxiliary/hidden-struct.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
// `Foo` and `Bar` should not be suggested in diagnostics of dependents

#[doc(hidden)]
pub mod hidden {
pub struct Foo;
}

pub mod hidden1 {
#[doc(hidden)]
pub struct Foo;
pub struct Bar;
}

// `Baz` and `Quux` *should* be suggested in diagnostics of dependents

#[doc(hidden)]
pub(crate) mod hidden2 {
pub struct Bar;
pub mod hidden2 {
pub struct Baz;
}

pub use hidden2::Baz;

#[doc(hidden)]
pub(crate) mod hidden3 {
pub struct Quux;
}

pub use hidden2::Bar;
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 {}
18 changes: 15 additions & 3 deletions tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@ aux-build:hidden-struct.rs
//@ compile-flags: --crate-type lib

extern crate hidden_struct;

Expand All @@ -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]
}
Loading
Loading