mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Auto merge of #125463 - GuillaumeGomez:rollup-287wx4y, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #125263 (rust-lld: fallback to rustc's sysroot if there's no path to the linker in the target sysroot) - #125345 (rustc_codegen_llvm: add support for writing summary bitcode) - #125362 (Actually use TAIT instead of emulating it) - #125412 (Don't suggest adding the unexpected cfgs to the build-script it-self) - #125445 (Migrate `run-make/rustdoc-with-short-out-dir-option` to `rmake.rs`) - #125452 (Cleanup check-cfg handling in core and std) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7601adcc76
@ -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
|
||||
|
@ -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!();
|
||||
}
|
||||
|
||||
|
@ -230,9 +230,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)
|
||||
}
|
||||
|
||||
@ -672,9 +675,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)
|
||||
}
|
||||
}
|
||||
@ -688,6 +691,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 {
|
||||
|
@ -709,13 +709,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() {
|
||||
@ -726,6 +728,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
|
||||
|
@ -237,8 +237,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()))
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -3141,13 +3141,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
|
||||
|
@ -108,6 +108,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
|
||||
@ -232,6 +233,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(),
|
||||
@ -283,6 +288,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)
|
||||
}
|
||||
@ -630,6 +636,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);
|
||||
}
|
||||
@ -883,7 +892,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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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}\");"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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) {
|
||||
|
@ -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()))',
|
||||
]
|
||||
|
@ -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
|
||||
|
@ -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)]
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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,
|
||||
|
@ -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")]
|
||||
|
@ -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()))',
|
||||
]
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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"])),
|
||||
|
@ -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
|
||||
|
@ -1,8 +0,0 @@
|
||||
include ../tools.mk
|
||||
|
||||
OUTPUT_DIR := "$(TMPDIR)/rustdoc"
|
||||
|
||||
all:
|
||||
$(RUSTDOC) src/lib.rs --crate-name foobar --crate-type lib -o $(OUTPUT_DIR)
|
||||
|
||||
$(HTMLDOCCK) $(OUTPUT_DIR) src/lib.rs
|
16
tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs
Normal file
16
tests/run-make/rustdoc-with-short-out-dir-option/rmake.rs
Normal file
@ -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
tests/ui/check-cfg/cargo-build-script.rs
Normal file
22
tests/ui/check-cfg/cargo-build-script.rs
Normal file
@ -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
tests/ui/check-cfg/cargo-build-script.stderr
Normal file
43
tests/ui/check-cfg/cargo-build-script.stderr
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user