Skip to content

Rollup of 6 pull requests #125463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
May 24, 2024
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
fde4a22
core: actually use TAIT instead of emulating it
joboet May 21, 2024
6867d64
add helper to target bin path
lqd May 21, 2024
aa91871
rustc_codegen_llvm: add support for writing summary bitcode
durin42 Jan 19, 2024
03d5556
cleanup: remove leftover extra block
durin42 May 22, 2024
1c7859e
Don't suggest adding the unexpected cfgs the build-script it-self
Urgau May 22, 2024
de64462
Migrate `run-make/rustdoc-with-short-out-dir-option` to `rmake.rs`
GuillaumeGomez May 23, 2024
c398b2c
core: use `Copy` in TAIT to fix clippy lint
joboet May 23, 2024
324b66c
Expect any feature cfg in core and std crates
Urgau May 23, 2024
a59589b
Replace fake "restricted-std" Cargo feature by custom cfg
Urgau May 23, 2024
2868985
Move some expected cfgs to std build.rs as per Cargo recommandation
Urgau May 23, 2024
45ad60d
Copy core/alloc check-cfg message also in std
Urgau May 23, 2024
fab28f2
rust-lld: fallback to the default default sysroot where rustc is curr…
lqd May 18, 2024
d64a8bd
emit an error if we can't find a path to the self-contained linker
lqd May 21, 2024
de8200c
thinlto: only build summary file if needed
durin42 May 23, 2024
3ea4941
cleanup: standardize on summary over index in names
durin42 May 23, 2024
a0581b5
cleanup: run rustfmt
durin42 May 23, 2024
cfe3f77
rustc_codegen_gcc: fix changed method signature
durin42 May 23, 2024
d6a1f1d
Rollup merge of #125263 - lqd:lld-fallback, r=petrochenkov
GuillaumeGomez May 23, 2024
4ee97fc
Rollup merge of #125345 - durin42:thin-link-bitcode, r=bjorn3
GuillaumeGomez May 23, 2024
1e4bde1
Rollup merge of #125362 - joboet:tait_hack, r=Nilstrieb
GuillaumeGomez May 23, 2024
56427d3
Rollup merge of #125412 - Urgau:check-cfg-less-build-rs, r=wesleywiser
GuillaumeGomez May 23, 2024
0de052a
Rollup merge of #125445 - GuillaumeGomez:rustdoc-migrate-short-out-di…
GuillaumeGomez May 23, 2024
a8a71d0
Rollup merge of #125452 - Urgau:check-cfg-libraries-cleanup, r=bjorn3
GuillaumeGomez May 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/driver/aot.rs
Original file line number Diff line number Diff line change
@@ -200,7 +200,7 @@ fn produce_final_output_artifacts(
// to get rid of it.
for output_type in crate_output.outputs.keys() {
match *output_type {
OutputType::Bitcode => {
OutputType::Bitcode | OutputType::ThinLinkBitcode => {
// Cranelift doesn't have bitcode
// user_wants_bitcode = true;
// // Copy to .bc, but always keep the .0.bc. There is a later
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -335,6 +335,10 @@ impl ThinBufferMethods for ThinBuffer {
fn data(&self) -> &[u8] {
unimplemented!();
}

fn thin_link_data(&self) -> &[u8] {
unimplemented!();
}
}

pub struct GccContext {
@@ -414,7 +418,7 @@ impl WriteBackendMethods for GccCodegenBackend {
back::write::codegen(cgcx, dcx, module, config)
}

fn prepare_thin(_module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
fn prepare_thin(_module: ModuleCodegen<Self::Module>, _emit_summary: bool) -> (String, Self::ThinBuffer) {
unimplemented!();
}

19 changes: 15 additions & 4 deletions compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
@@ -229,9 +229,12 @@ pub(crate) fn run_thin(
thin_lto(cgcx, &dcx, modules, upstream_modules, cached_modules, &symbols_below_threshold)
}

pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBuffer) {
pub(crate) fn prepare_thin(
module: ModuleCodegen<ModuleLlvm>,
emit_summary: bool,
) -> (String, ThinBuffer) {
let name = module.name;
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true);
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true, emit_summary);
(name, buffer)
}

@@ -671,9 +674,9 @@ unsafe impl Send for ThinBuffer {}
unsafe impl Sync for ThinBuffer {}

impl ThinBuffer {
pub fn new(m: &llvm::Module, is_thin: bool) -> ThinBuffer {
pub fn new(m: &llvm::Module, is_thin: bool, emit_summary: bool) -> ThinBuffer {
unsafe {
let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin);
let buffer = llvm::LLVMRustThinLTOBufferCreate(m, is_thin, emit_summary);
ThinBuffer(buffer)
}
}
@@ -687,6 +690,14 @@ impl ThinBufferMethods for ThinBuffer {
slice::from_raw_parts(ptr, len)
}
}

fn thin_link_data(&self) -> &[u8] {
unsafe {
let ptr = llvm::LLVMRustThinLTOBufferThinLinkDataPtr(self.0) as *const _;
let len = llvm::LLVMRustThinLTOBufferThinLinkDataLen(self.0);
slice::from_raw_parts(ptr, len)
}
}
}

impl Drop for ThinBuffer {
23 changes: 22 additions & 1 deletion compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
@@ -708,13 +708,15 @@ pub(crate) unsafe fn codegen(
// asm from LLVM and use `gcc` to create the object file.

let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
let bc_summary_out =
cgcx.output_filenames.temp_path(OutputType::ThinLinkBitcode, module_name);
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);

if config.bitcode_needed() {
let _timer = cgcx
.prof
.generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &*module.name);
let thin = ThinBuffer::new(llmod, config.emit_thin_lto);
let thin = ThinBuffer::new(llmod, config.emit_thin_lto, config.emit_thin_lto_summary);
let data = thin.data();

if let Some(bitcode_filename) = bc_out.file_name() {
@@ -725,6 +727,25 @@ pub(crate) unsafe fn codegen(
);
}

if config.emit_thin_lto_summary
&& let Some(thin_link_bitcode_filename) = bc_summary_out.file_name()
{
let summary_data = thin.thin_link_data();
cgcx.prof.artifact_size(
"llvm_bitcode_summary",
thin_link_bitcode_filename.to_string_lossy(),
summary_data.len() as u64,
);

let _timer = cgcx.prof.generic_activity_with_arg(
"LLVM_module_codegen_emit_bitcode_summary",
&*module.name,
);
if let Err(err) = fs::write(&bc_summary_out, summary_data) {
dcx.emit_err(WriteBytecode { path: &bc_summary_out, err });
}
}

if config.emit_bc || config.emit_obj == EmitObj::Bitcode {
let _timer = cgcx
.prof
7 changes: 5 additions & 2 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -240,8 +240,11 @@ impl WriteBackendMethods for LlvmCodegenBackend {
) -> Result<CompiledModule, FatalError> {
back::write::codegen(cgcx, dcx, module, config)
}
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer) {
back::lto::prepare_thin(module)
fn prepare_thin(
module: ModuleCodegen<Self::Module>,
emit_summary: bool,
) -> (String, Self::ThinBuffer) {
back::lto::prepare_thin(module, emit_summary)
}
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer) {
(module.name, back::lto::ModuleBuffer::new(module.module_llvm.llmod()))
8 changes: 7 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -2350,10 +2350,16 @@ extern "C" {
#[allow(improper_ctypes)]
pub fn LLVMRustModuleInstructionStats(M: &Module, Str: &RustString);

pub fn LLVMRustThinLTOBufferCreate(M: &Module, is_thin: bool) -> &'static mut ThinLTOBuffer;
pub fn LLVMRustThinLTOBufferCreate(
M: &Module,
is_thin: bool,
emit_summary: bool,
) -> &'static mut ThinLTOBuffer;
pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer);
pub fn LLVMRustThinLTOBufferPtr(M: &ThinLTOBuffer) -> *const c_char;
pub fn LLVMRustThinLTOBufferLen(M: &ThinLTOBuffer) -> size_t;
pub fn LLVMRustThinLTOBufferThinLinkDataPtr(M: &ThinLTOBuffer) -> *const c_char;
pub fn LLVMRustThinLTOBufferThinLinkDataLen(M: &ThinLTOBuffer) -> size_t;
pub fn LLVMRustCreateThinLTOData(
Modules: *const ThinLTOModule,
NumModules: c_uint,
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/messages.ftl
Original file line number Diff line number Diff line change
@@ -212,6 +212,8 @@ codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, fo
codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected
codegen_ssa_self_contained_linker_missing = the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot
codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time
codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link
10 changes: 9 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -3140,13 +3140,21 @@ fn add_lld_args(

let self_contained_linker = self_contained_cli || self_contained_target;
if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() {
let mut linker_path_exists = false;
for path in sess.get_tools_search_paths(false) {
let linker_path = path.join("gcc-ld");
linker_path_exists |= linker_path.exists();
cmd.arg({
let mut arg = OsString::from("-B");
arg.push(path.join("gcc-ld"));
arg.push(linker_path);
arg
});
}
if !linker_path_exists {
// As a sanity check, we emit an error if none of these paths exist: we want
// self-contained linking and have no linker.
sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing);
}
}

// 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of
11 changes: 10 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
@@ -107,6 +107,7 @@ pub struct ModuleConfig {
pub emit_asm: bool,
pub emit_obj: EmitObj,
pub emit_thin_lto: bool,
pub emit_thin_lto_summary: bool,
pub bc_cmdline: String,

// Miscellaneous flags. These are mostly copied from command-line
@@ -231,6 +232,10 @@ impl ModuleConfig {
),
emit_obj,
emit_thin_lto: sess.opts.unstable_opts.emit_thin_lto,
emit_thin_lto_summary: if_regular!(
sess.opts.output_types.contains_key(&OutputType::ThinLinkBitcode),
false
),
bc_cmdline: sess.target.bitcode_llvm_cmdline.to_string(),

verify_llvm_ir: sess.verify_llvm_ir(),
@@ -282,6 +287,7 @@ impl ModuleConfig {

pub fn bitcode_needed(&self) -> bool {
self.emit_bc
|| self.emit_thin_lto_summary
|| self.emit_obj == EmitObj::Bitcode
|| self.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full)
}
@@ -629,6 +635,9 @@ fn produce_final_output_artifacts(
// them for making an rlib.
copy_if_one_unit(OutputType::Bitcode, true);
}
OutputType::ThinLinkBitcode => {
copy_if_one_unit(OutputType::ThinLinkBitcode, false);
}
OutputType::LlvmAssembly => {
copy_if_one_unit(OutputType::LlvmAssembly, false);
}
@@ -882,7 +891,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
match lto_type {
ComputedLtoType::No => finish_intra_module_work(cgcx, module, module_config),
ComputedLtoType::Thin => {
let (name, thin_buffer) = B::prepare_thin(module);
let (name, thin_buffer) = B::prepare_thin(module, false);
if let Some(path) = bitcode {
fs::write(&path, thin_buffer.data()).unwrap_or_else(|e| {
panic!("Error writing pre-lto-bitcode file `{}`: {}", path.display(), e);
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
@@ -413,6 +413,10 @@ pub struct UnableToExeLinker {
#[diag(codegen_ssa_msvc_missing_linker)]
pub struct MsvcMissingLinker;

#[derive(Diagnostic)]
#[diag(codegen_ssa_self_contained_linker_missing)]
pub struct SelfContainedLinkerMissing;

#[derive(Diagnostic)]
#[diag(codegen_ssa_check_installed_visual_studio)]
pub struct CheckInstalledVisualStudio;
6 changes: 5 additions & 1 deletion compiler/rustc_codegen_ssa/src/traits/write.rs
Original file line number Diff line number Diff line change
@@ -56,12 +56,16 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
module: ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError>;
fn prepare_thin(module: ModuleCodegen<Self::Module>) -> (String, Self::ThinBuffer);
fn prepare_thin(
module: ModuleCodegen<Self::Module>,
want_summary: bool,
) -> (String, Self::ThinBuffer);
fn serialize_module(module: ModuleCodegen<Self::Module>) -> (String, Self::ModuleBuffer);
}

pub trait ThinBufferMethods: Send + Sync {
fn data(&self) -> &[u8];
fn thin_link_data(&self) -> &[u8];
}

pub trait ModuleBufferMethods: Send + Sync {
30 changes: 18 additions & 12 deletions compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
Original file line number Diff line number Diff line change
@@ -42,6 +42,22 @@ fn to_check_cfg_arg(name: Symbol, value: Option<Symbol>, quotes: EscapeQuotes) -
}
}

fn cargo_help_sub(
sess: &Session,
inst: &impl Fn(EscapeQuotes) -> String,
) -> lints::UnexpectedCfgCargoHelp {
// We don't want to suggest the `build.rs` way to expected cfgs if we are already in a
// `build.rs`. We therefor do a best effort check (looking if the `--crate-name` is
// `build_script_build`) to try to figure out if we are building a Cargo build script

let unescaped = &inst(EscapeQuotes::No);
if matches!(&sess.opts.crate_name, Some(crate_name) if crate_name == "build_script_build") {
lints::UnexpectedCfgCargoHelp::lint_cfg(unescaped)
} else {
lints::UnexpectedCfgCargoHelp::lint_cfg_and_build_rs(unescaped, &inst(EscapeQuotes::Yes))
}
}

pub(super) fn unexpected_cfg_name(
sess: &Session,
(name, name_span): (Symbol, Span),
@@ -162,14 +178,7 @@ pub(super) fn unexpected_cfg_name(
let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes);

let invocation_help = if is_from_cargo {
let sub = if !is_feature_cfg {
Some(lints::UnexpectedCfgCargoHelp::new(
&inst(EscapeQuotes::No),
&inst(EscapeQuotes::Yes),
))
} else {
None
};
let sub = if !is_feature_cfg { Some(cargo_help_sub(sess, &inst)) } else { None };
lints::unexpected_cfg_name::InvocationHelp::Cargo { sub }
} else {
lints::unexpected_cfg_name::InvocationHelp::Rustc(lints::UnexpectedCfgRustcHelp::new(
@@ -267,10 +276,7 @@ pub(super) fn unexpected_cfg_value(
Some(lints::unexpected_cfg_value::CargoHelp::DefineFeatures)
}
} else if !is_cfg_a_well_know_name {
Some(lints::unexpected_cfg_value::CargoHelp::Other(lints::UnexpectedCfgCargoHelp::new(
&inst(EscapeQuotes::No),
&inst(EscapeQuotes::Yes),
)))
Some(lints::unexpected_cfg_value::CargoHelp::Other(cargo_help_sub(sess, &inst)))
} else {
None
};
36 changes: 24 additions & 12 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
@@ -1962,21 +1962,33 @@ pub struct UnitBindingsDiag {
pub struct BuiltinNamedAsmLabel;

#[derive(Subdiagnostic)]
#[help(lint_unexpected_cfg_add_cargo_feature)]
#[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
#[help(lint_unexpected_cfg_add_build_rs_println)]
pub struct UnexpectedCfgCargoHelp {
pub build_rs_println: String,
pub cargo_toml_lint_cfg: String,
pub enum UnexpectedCfgCargoHelp {
#[help(lint_unexpected_cfg_add_cargo_feature)]
#[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
LintCfg { cargo_toml_lint_cfg: String },
#[help(lint_unexpected_cfg_add_cargo_feature)]
#[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
#[help(lint_unexpected_cfg_add_build_rs_println)]
LintCfgAndBuildRs { cargo_toml_lint_cfg: String, build_rs_println: String },
}

impl UnexpectedCfgCargoHelp {
pub fn new(unescaped: &str, escaped: &str) -> Self {
Self {
cargo_toml_lint_cfg: format!(
"\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{unescaped}'] }}",
),
build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");",),
fn cargo_toml_lint_cfg(unescaped: &str) -> String {
format!(
"\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{unescaped}'] }}"
)
}

pub fn lint_cfg(unescaped: &str) -> Self {
UnexpectedCfgCargoHelp::LintCfg {
cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
}
}

pub fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self {
UnexpectedCfgCargoHelp::LintCfgAndBuildRs {
cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");"),
}
}
}
19 changes: 17 additions & 2 deletions compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
@@ -1488,13 +1488,15 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
// a ThinLTO summary attached.
struct LLVMRustThinLTOBuffer {
std::string data;
std::string thin_link_data;
};

extern "C" LLVMRustThinLTOBuffer*
LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin, bool emit_summary) {
auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
{
auto OS = raw_string_ostream(Ret->data);
auto ThinLinkOS = raw_string_ostream(Ret->thin_link_data);
{
if (is_thin) {
PassBuilder PB;
@@ -1508,7 +1510,10 @@ LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
PB.registerLoopAnalyses(LAM);
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
ModulePassManager MPM;
MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
// We only pass ThinLinkOS to be filled in if we want the summary,
// because otherwise LLVM does extra work and may double-emit some
// errors or warnings.
MPM.addPass(ThinLTOBitcodeWriterPass(OS, emit_summary ? &ThinLinkOS : nullptr));
MPM.run(*unwrap(M), MAM);
} else {
WriteBitcodeToFile(*unwrap(M), OS);
@@ -1533,6 +1538,16 @@ LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
return Buffer->data.length();
}

extern "C" const void*
LLVMRustThinLTOBufferThinLinkDataPtr(const LLVMRustThinLTOBuffer *Buffer) {
return Buffer->thin_link_data.data();
}

extern "C" size_t
LLVMRustThinLTOBufferThinLinkDataLen(const LLVMRustThinLTOBuffer *Buffer) {
return Buffer->thin_link_data.length();
}

// This is what we used to parse upstream bitcode for actual ThinLTO
// processing. We'll call this once per module optimized through ThinLTO, and
// it'll be called concurrently on many threads.
24 changes: 20 additions & 4 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
@@ -465,6 +465,7 @@ impl FromStr for SplitDwarfKind {
#[derive(Encodable, Decodable)]
pub enum OutputType {
Bitcode,
ThinLinkBitcode,
Assembly,
LlvmAssembly,
Mir,
@@ -492,6 +493,7 @@ impl OutputType {
match *self {
OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true,
OutputType::Bitcode
| OutputType::ThinLinkBitcode
| OutputType::Assembly
| OutputType::LlvmAssembly
| OutputType::Mir
@@ -502,6 +504,7 @@ impl OutputType {
pub fn shorthand(&self) -> &'static str {
match *self {
OutputType::Bitcode => "llvm-bc",
OutputType::ThinLinkBitcode => "thin-link-bitcode",
OutputType::Assembly => "asm",
OutputType::LlvmAssembly => "llvm-ir",
OutputType::Mir => "mir",
@@ -518,6 +521,7 @@ impl OutputType {
"llvm-ir" => OutputType::LlvmAssembly,
"mir" => OutputType::Mir,
"llvm-bc" => OutputType::Bitcode,
"thin-link-bitcode" => OutputType::ThinLinkBitcode,
"obj" => OutputType::Object,
"metadata" => OutputType::Metadata,
"link" => OutputType::Exe,
@@ -528,8 +532,9 @@ impl OutputType {

fn shorthands_display() -> String {
format!(
"`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
"`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
OutputType::Bitcode.shorthand(),
OutputType::ThinLinkBitcode.shorthand(),
OutputType::Assembly.shorthand(),
OutputType::LlvmAssembly.shorthand(),
OutputType::Mir.shorthand(),
@@ -543,6 +548,7 @@ impl OutputType {
pub fn extension(&self) -> &'static str {
match *self {
OutputType::Bitcode => "bc",
OutputType::ThinLinkBitcode => "indexing.o",
OutputType::Assembly => "s",
OutputType::LlvmAssembly => "ll",
OutputType::Mir => "mir",
@@ -559,9 +565,11 @@ impl OutputType {
| OutputType::LlvmAssembly
| OutputType::Mir
| OutputType::DepInfo => true,
OutputType::Bitcode | OutputType::Object | OutputType::Metadata | OutputType::Exe => {
false
}
OutputType::Bitcode
| OutputType::ThinLinkBitcode
| OutputType::Object
| OutputType::Metadata
| OutputType::Exe => false,
}
}
}
@@ -644,6 +652,7 @@ impl OutputTypes {
pub fn should_codegen(&self) -> bool {
self.0.keys().any(|k| match *k {
OutputType::Bitcode
| OutputType::ThinLinkBitcode
| OutputType::Assembly
| OutputType::LlvmAssembly
| OutputType::Mir
@@ -657,6 +666,7 @@ impl OutputTypes {
pub fn should_link(&self) -> bool {
self.0.keys().any(|k| match *k {
OutputType::Bitcode
| OutputType::ThinLinkBitcode
| OutputType::Assembly
| OutputType::LlvmAssembly
| OutputType::Mir
@@ -1769,6 +1779,12 @@ fn parse_output_types(
display = OutputType::shorthands_display(),
))
});
if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
early_dcx.early_fatal(format!(
"{} requested but -Zunstable-options not specified",
OutputType::ThinLinkBitcode.shorthand()
));
}
output_types.insert(output_type, path);
}
}
8 changes: 8 additions & 0 deletions compiler/rustc_session/src/filesearch.rs
Original file line number Diff line number Diff line change
@@ -51,6 +51,14 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
}

/// Returns a path to the target's `bin` folder within its `rustlib` path in the sysroot. This is
/// where binaries are usually installed, e.g. the self-contained linkers, lld-wrappers, LLVM tools,
/// etc.
pub fn make_target_bin_path(sysroot: &Path, target_triple: &str) -> PathBuf {
let rustlib_path = rustc_target::target_rustlib_path(sysroot, target_triple);
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("bin")])
}

#[cfg(unix)]
fn current_dll_path() -> Result<PathBuf, String> {
use std::ffi::{CStr, OsStr};
25 changes: 17 additions & 8 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
@@ -449,15 +449,24 @@ impl Session {
)
}

/// Returns a list of directories where target-specific tool binaries are located.
/// Returns a list of directories where target-specific tool binaries are located. Some fallback
/// directories are also returned, for example if `--sysroot` is used but tools are missing
/// (#125246): we also add the bin directories to the sysroot where rustc is located.
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, config::host_triple());
let p = PathBuf::from_iter([
Path::new(&self.sysroot),
Path::new(&rustlib_path),
Path::new("bin"),
]);
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_triple());
let fallback_sysroot_paths = filesearch::sysroot_candidates()
.into_iter()
.map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_triple()));
let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths);

if self_contained {
// The self-contained tools are expected to be e.g. in `bin/self-contained` in the
// sysroot's `rustlib` path, so we add such a subfolder to the bin path, and the
// fallback paths.
search_paths.flat_map(|path| [path.clone(), path.join("self-contained")]).collect()
} else {
search_paths.collect()
}
}

pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) {
4 changes: 3 additions & 1 deletion library/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -46,6 +46,8 @@ check-cfg = [
'cfg(bootstrap)',
'cfg(no_fp_fmt_parse)',
'cfg(stdarch_intel_sde)',
# This matches `EXTRA_CHECK_CFGS` in `src/bootstrap/src/lib.rs`.
# core use #[path] imports to portable-simd `core_simd` crate
# and to stdarch `core_arch` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
'cfg(feature, values(any()))',
]
41 changes: 0 additions & 41 deletions library/core/src/internal_macros.rs
Original file line number Diff line number Diff line change
@@ -80,47 +80,6 @@ macro_rules! forward_ref_op_assign {
}
}

/// Create a zero-size type similar to a closure type, but named.
macro_rules! impl_fn_for_zst {
($(
$( #[$attr: meta] )*
struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
|$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty
$body: block;
)+) => {
$(
$( #[$attr] )*
struct $Name;

impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
$body
}
}

impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name {
#[inline]
extern "rust-call" fn call_mut(
&mut self,
($( $arg, )*): ($( $ArgTy, )*)
) -> $ReturnTy {
Fn::call(&*self, ($( $arg, )*))
}
}

impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name {
type Output = $ReturnTy;

#[inline]
extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy {
Fn::call(&self, ($( $arg, )*))
}
}
)+
}
}

/// A macro for defining `#[cfg]` if-else statements.
///
/// `cfg_if` is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -255,6 +255,7 @@
#![feature(trait_alias)]
#![feature(transparent_unions)]
#![feature(try_blocks)]
#![feature(type_alias_impl_trait)]
#![feature(unboxed_closures)]
#![feature(unsized_fn_params)]
#![feature(with_negative_coherence)]
9 changes: 2 additions & 7 deletions library/core/src/slice/ascii.rs
Original file line number Diff line number Diff line change
@@ -108,7 +108,7 @@ impl [u8] {
without modifying the original"]
#[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
pub fn escape_ascii(&self) -> EscapeAscii<'_> {
EscapeAscii { inner: self.iter().flat_map(EscapeByte) }
EscapeAscii { inner: self.iter().flat_map(|byte| byte.escape_ascii()) }
}

/// Returns a byte slice with leading ASCII whitespace bytes removed.
@@ -190,12 +190,7 @@ impl [u8] {
}
}

impl_fn_for_zst! {
#[derive(Clone)]
struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault {
ascii::escape_default(*byte)
};
}
type EscapeByte = impl (Fn(&u8) -> ascii::EscapeDefault) + Copy;

/// An iterator over the escaped version of a byte slice.
///
6 changes: 4 additions & 2 deletions library/core/src/str/iter.rs
Original file line number Diff line number Diff line change
@@ -1274,8 +1274,10 @@ pub struct SplitWhitespace<'a> {
#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
#[derive(Clone, Debug)]
pub struct SplitAsciiWhitespace<'a> {
pub(super) inner:
Map<Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty>, UnsafeBytesToStr>,
pub(super) inner: Map<
Filter<SliceSplit<'a, u8, IsAsciiWhitespace>, BytesIsNotEmpty<'a>>,
UnsafeBytesToStr<'a>,
>,
}

/// An iterator over the substrings of a string,
104 changes: 37 additions & 67 deletions library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
@@ -983,7 +983,7 @@ impl str {
#[cfg_attr(not(test), rustc_diagnostic_item = "str_split_whitespace")]
#[inline]
pub fn split_whitespace(&self) -> SplitWhitespace<'_> {
SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
SplitWhitespace { inner: self.split(char::is_whitespace).filter(|s| !s.is_empty()) }
}

/// Splits a string slice by ASCII whitespace.
@@ -1032,8 +1032,13 @@ impl str {
#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
#[inline]
pub fn split_ascii_whitespace(&self) -> SplitAsciiWhitespace<'_> {
let inner =
self.as_bytes().split(IsAsciiWhitespace).filter(BytesIsNotEmpty).map(UnsafeBytesToStr);
let inner = self
.as_bytes()
.split(u8::is_ascii_whitespace)
.filter(|s| !s.is_empty())
// SAFETY: the byte slice came from a string and was only split
// along character boundaries, so the resulting slices are strings.
.map(|bytes| unsafe { from_utf8_unchecked(bytes) });
SplitAsciiWhitespace { inner }
}

@@ -1085,7 +1090,11 @@ impl str {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn lines(&self) -> Lines<'_> {
Lines(self.split_inclusive('\n').map(LinesMap))
Lines(self.split_inclusive('\n').map(|line| {
let Some(line) = line.strip_suffix('\n') else { return line };
let Some(line) = line.strip_suffix('\r') else { return line };
line
}))
}

/// An iterator over the lines of a string.
@@ -2636,14 +2645,19 @@ impl str {
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_debug(&self) -> EscapeDebug<'_> {
let mut chars = self.chars();
EscapeDebug {
inner: chars
.next()
.map(|first| first.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL))
.into_iter()
.flatten()
.chain(chars.flat_map(CharEscapeDebugContinue)),
}
let first = chars
.next()
.map(|first| first.escape_debug_ext(EscapeDebugExtArgs::ESCAPE_ALL))
.into_iter()
.flatten();
let inner = first.chain(chars.flat_map(|c| {
c.escape_debug_ext(EscapeDebugExtArgs {
escape_grapheme_extended: false,
escape_single_quote: true,
escape_double_quote: true,
})
}));
EscapeDebug { inner }
}

/// Return an iterator that escapes each char in `self` with [`char::escape_default`].
@@ -2681,7 +2695,7 @@ impl str {
without modifying the original"]
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_default(&self) -> EscapeDefault<'_> {
EscapeDefault { inner: self.chars().flat_map(CharEscapeDefault) }
EscapeDefault { inner: self.chars().flat_map(char::escape_default) }
}

/// Return an iterator that escapes each char in `self` with [`char::escape_unicode`].
@@ -2719,7 +2733,7 @@ impl str {
without modifying the original"]
#[stable(feature = "str_escape", since = "1.34.0")]
pub fn escape_unicode(&self) -> EscapeUnicode<'_> {
EscapeUnicode { inner: self.chars().flat_map(CharEscapeUnicode) }
EscapeUnicode { inner: self.chars().flat_map(char::escape_unicode) }
}
}

@@ -2750,59 +2764,15 @@ impl Default for &mut str {
}
}

impl_fn_for_zst! {
/// A nameable, cloneable fn type
#[derive(Clone)]
struct LinesMap impl<'a> Fn = |line: &'a str| -> &'a str {
let Some(line) = line.strip_suffix('\n') else { return line };
let Some(line) = line.strip_suffix('\r') else { return line };
line
};

#[derive(Clone)]
struct CharEscapeDebugContinue impl Fn = |c: char| -> char::EscapeDebug {
c.escape_debug_ext(EscapeDebugExtArgs {
escape_grapheme_extended: false,
escape_single_quote: true,
escape_double_quote: true
})
};

#[derive(Clone)]
struct CharEscapeUnicode impl Fn = |c: char| -> char::EscapeUnicode {
c.escape_unicode()
};
#[derive(Clone)]
struct CharEscapeDefault impl Fn = |c: char| -> char::EscapeDefault {
c.escape_default()
};

#[derive(Clone)]
struct IsWhitespace impl Fn = |c: char| -> bool {
c.is_whitespace()
};

#[derive(Clone)]
struct IsAsciiWhitespace impl Fn = |byte: &u8| -> bool {
byte.is_ascii_whitespace()
};

#[derive(Clone)]
struct IsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b str| -> bool {
!s.is_empty()
};

#[derive(Clone)]
struct BytesIsNotEmpty impl<'a, 'b> Fn = |s: &'a &'b [u8]| -> bool {
!s.is_empty()
};

#[derive(Clone)]
struct UnsafeBytesToStr impl<'a> Fn = |bytes: &'a [u8]| -> &'a str {
// SAFETY: not safe
unsafe { from_utf8_unchecked(bytes) }
};
}
type LinesMap = impl (Fn(&str) -> &str) + Copy;
type CharEscapeDebugContinue = impl (FnMut(char) -> char::EscapeDebug) + Copy;
type CharEscapeUnicode = impl (Fn(char) -> char::EscapeUnicode) + Copy;
type CharEscapeDefault = impl (Fn(char) -> char::EscapeDefault) + Copy;
type IsWhitespace = impl (Fn(char) -> bool) + Copy;
type IsAsciiWhitespace = impl (Fn(&u8) -> bool) + Copy;
type IsNotEmpty = impl (Fn(&&str) -> bool) + Copy;
type BytesIsNotEmpty<'a> = impl (FnMut(&&'a [u8]) -> bool) + Copy;
type UnsafeBytesToStr<'a> = impl (FnMut(&'a [u8]) -> &'a str) + Copy;

// This is required to make `impl From<&str> for Box<dyn Error>` and `impl<E> From<E> for Box<dyn Error>` not overlap.
#[stable(feature = "rust1", since = "1.0.0")]
10 changes: 7 additions & 3 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
@@ -100,10 +100,14 @@ test = true

[lints.rust.unexpected_cfgs]
level = "warn"
# x.py uses beta cargo, so `check-cfg` entries do not yet take effect
# for rust-lang/rust. But for users of `-Zbuild-std` it does.
# The unused warning is waiting for rust-lang/cargo#13925 to reach beta.
check-cfg = [
'cfg(bootstrap)',
'cfg(backtrace_in_libstd)',
'cfg(netbsd10)',
'cfg(target_arch, values("xtensa"))',
'cfg(feature, values("std", "as_crate"))',
# std use #[path] imports to portable-simd `std_float` crate
# and to the `backtrace` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
'cfg(feature, values(any()))',
]
11 changes: 9 additions & 2 deletions library/std/build.rs
Original file line number Diff line number Diff line change
@@ -7,9 +7,13 @@ fn main() {
let target_vendor =
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");

println!("cargo:rustc-check-cfg=cfg(netbsd10)");
if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() {
println!("cargo:rustc-cfg=netbsd10");
}

println!("cargo:rustc-check-cfg=cfg(restricted_std)");
if target_os == "linux"
|| target_os == "android"
|| target_os == "netbsd"
@@ -59,8 +63,11 @@ fn main() {
// - arch=avr
// - JSON targets
// - Any new targets that have not been explicitly added above.
println!("cargo:rustc-cfg=feature=\"restricted-std\"");
println!("cargo:rustc-cfg=restricted_std");
}
println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());

println!("cargo:rustc-check-cfg=cfg(backtrace_in_libstd)");
println!("cargo:rustc-cfg=backtrace_in_libstd");

println!("cargo:rustc-env=STD_ENV_ARCH={}", env::var("CARGO_CFG_TARGET_ARCH").unwrap());
}
4 changes: 2 additions & 2 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -213,9 +213,9 @@
//! [array]: prim@array
//! [slice]: prim@slice
#![cfg_attr(not(feature = "restricted-std"), stable(feature = "rust1", since = "1.0.0"))]
#![cfg_attr(not(restricted_std), stable(feature = "rust1", since = "1.0.0"))]
#![cfg_attr(
feature = "restricted-std",
restricted_std,
unstable(
feature = "restricted_std",
issue = "none",
2 changes: 0 additions & 2 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
@@ -92,8 +92,6 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
(Some(Mode::Std), "no_global_oom_handling", None),
(Some(Mode::Std), "no_rc", None),
(Some(Mode::Std), "no_sync", None),
(Some(Mode::Std), "netbsd10", None),
(Some(Mode::Std), "backtrace_in_libstd", None),
/* Extra values not defined in the built-in targets yet, but used in std */
(Some(Mode::Std), "target_env", Some(&["libnx", "p2"])),
(Some(Mode::Std), "target_os", Some(&["visionos"])),
1 change: 0 additions & 1 deletion src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
@@ -229,7 +229,6 @@ run-make/rustc-macro-dep-files/Makefile
run-make/rustdoc-io-error/Makefile
run-make/rustdoc-verify-output-files/Makefile
run-make/rustdoc-with-output-option/Makefile
run-make/rustdoc-with-short-out-dir-option/Makefile
run-make/sanitizer-cdylib-link/Makefile
run-make/sanitizer-dylib-link/Makefile
run-make/sanitizer-staticlib-link/Makefile
8 changes: 0 additions & 8 deletions tests/run-make/rustdoc-with-short-out-dir-option/Makefile

This file was deleted.

16 changes: 16 additions & 0 deletions tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use run_make_support::{htmldocck, rustdoc, tmp_dir};

fn main() {
let out_dir = tmp_dir().join("rustdoc");

rustdoc()
.input("src/lib.rs")
.crate_name("foobar")
.crate_type("lib")
// This is intentionally using `-o` option flag and not the `output()` method.
.arg("-o")
.arg(&out_dir)
.run();

assert!(htmldocck().arg(out_dir).arg("src/lib.rs").status().unwrap().success());
}
22 changes: 22 additions & 0 deletions tests/ui/check-cfg/cargo-build-script.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// This test checks that when we are building a build script provided
// by Cargo we only suggest expecting the unexpected cfgs in the Cargo.toml.
//
//@ check-pass
//@ no-auto-check-cfg
//@ rustc-env:CARGO_CRATE_NAME=build_script_build
//@ compile-flags:--crate-name=build_script_build
//@ compile-flags:--check-cfg=cfg(has_bar)

#[cfg(has_foo)]
//~^ WARNING unexpected `cfg` condition name
fn foo() {}

#[cfg(has_foo = "yes")]
//~^ WARNING unexpected `cfg` condition name
fn foo() {}

#[cfg(has_bar = "yes")]
//~^ WARNING unexpected `cfg` condition value
fn has_bar() {}

fn main() {}
43 changes: 43 additions & 0 deletions tests/ui/check-cfg/cargo-build-script.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
warning: unexpected `cfg` condition name: `has_foo`
--> $DIR/cargo-build-script.rs:10:7
|
LL | #[cfg(has_foo)]
| ^^^^^^^
|
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `has_bar`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_foo)'] }
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default

warning: unexpected `cfg` condition name: `has_foo`
--> $DIR/cargo-build-script.rs:14:7
|
LL | #[cfg(has_foo = "yes")]
| ^^^^^^^^^^^^^^^
|
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_foo, values("yes"))'] }
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: unexpected `cfg` condition value: `yes`
--> $DIR/cargo-build-script.rs:18:7
|
LL | #[cfg(has_bar = "yes")]
| ^^^^^^^--------
| |
| help: remove the value
|
= note: no expected value for `has_bar`
= help: consider using a Cargo feature instead
= help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(has_bar, values("yes"))'] }
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

warning: 3 warnings emitted