summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa/src/back
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa/src/back')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs73
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs402
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs67
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs29
6 files changed, 326 insertions, 281 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 0d2aa483d..bb76ca5d2 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -1,44 +1,16 @@
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::memmap::Mmap;
use rustc_session::cstore::DllImport;
use rustc_session::Session;
+use rustc_span::symbol::Symbol;
+use object::read::archive::ArchiveFile;
+
+use std::fmt::Display;
+use std::fs::File;
use std::io;
use std::path::{Path, PathBuf};
-pub(super) fn find_library(
- name: &str,
- verbatim: bool,
- search_paths: &[PathBuf],
- sess: &Session,
-) -> PathBuf {
- // On Windows, static libraries sometimes show up as libfoo.a and other
- // times show up as foo.lib
- let oslibname = if verbatim {
- name.to_string()
- } else {
- format!("{}{}{}", sess.target.staticlib_prefix, name, sess.target.staticlib_suffix)
- };
- let unixlibname = format!("lib{}.a", name);
-
- for path in search_paths {
- debug!("looking for {} inside {:?}", name, path);
- let test = path.join(&oslibname);
- if test.exists() {
- return test;
- }
- if oslibname != unixlibname {
- let test = path.join(&unixlibname);
- if test.exists() {
- return test;
- }
- }
- }
- sess.fatal(&format!(
- "could not find native static library `{}`, \
- perhaps an -L flag is missing?",
- name
- ));
-}
-
pub trait ArchiveBuilderBuilder {
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
@@ -53,7 +25,38 @@ pub trait ArchiveBuilderBuilder {
lib_name: &str,
dll_imports: &[DllImport],
tmpdir: &Path,
+ is_direct_dependency: bool,
) -> PathBuf;
+
+ fn extract_bundled_libs(
+ &self,
+ rlib: &Path,
+ outdir: &Path,
+ bundled_lib_file_names: &FxHashSet<Symbol>,
+ ) -> Result<(), String> {
+ let message = |msg: &str, e: &dyn Display| format!("{} '{}': {}", msg, &rlib.display(), e);
+ let archive_map = unsafe {
+ Mmap::map(File::open(rlib).map_err(|e| message("failed to open file", &e))?)
+ .map_err(|e| message("failed to mmap file", &e))?
+ };
+ let archive = ArchiveFile::parse(&*archive_map)
+ .map_err(|e| message("failed to parse archive", &e))?;
+
+ for entry in archive.members() {
+ let entry = entry.map_err(|e| message("failed to read entry", &e))?;
+ let data = entry
+ .data(&*archive_map)
+ .map_err(|e| message("failed to get data from archive member", &e))?;
+ let name = std::str::from_utf8(entry.name())
+ .map_err(|e| message("failed to convert name", &e))?;
+ if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
+ continue; // We need to extract only native libraries.
+ }
+ std::fs::write(&outdir.join(&name), data)
+ .map_err(|e| message("failed to write file", &e))?;
+ }
+ Ok(())
+ }
}
pub trait ArchiveBuilder<'a> {
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 63207803e..6cce95427 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1,11 +1,13 @@
use rustc_arena::TypedArena;
use rustc_ast::CRATE_NODE_ID;
-use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_errors::{ErrorGuaranteed, Handler};
use rustc_fs_util::fix_windows_verbatim_for_gcc;
use rustc_hir::def_id::CrateNum;
+use rustc_metadata::find_native_static_library;
use rustc_metadata::fs::{emit_metadata, METADATA_FILENAME};
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
@@ -20,11 +22,11 @@ use rustc_session::utils::NativeLibKind;
use rustc_session::{filesearch, Session};
use rustc_span::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile;
-use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
+use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
-use super::archive::{find_library, ArchiveBuilder, ArchiveBuilderBuilder};
+use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use super::command::Command;
use super::linker::{self, Linker};
use super::metadata::{create_rmeta_file, MetadataPosition};
@@ -44,7 +46,7 @@ use std::io::{BufWriter, Write};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::process::{ExitStatus, Output, Stdio};
-use std::{ascii, char, env, fmt, fs, io, mem, str};
+use std::{env, fmt, fs, io, mem, str};
pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
if let Err(e) = fs::remove_file(path) {
@@ -307,6 +309,9 @@ fn link_rlib<'a>(
}
}
+ // Used if packed_bundled_libs flag enabled.
+ let mut packed_bundled_libs = Vec::new();
+
// Note that in this loop we are ignoring the value of `lib.cfg`. That is,
// we may not be configured to actually include a static library if we're
// adding it here. That's because later when we consume this rlib we'll
@@ -326,6 +331,8 @@ fn link_rlib<'a>(
for lib in codegen_results.crate_info.used_libraries.iter() {
match lib.kind {
NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
+ if flavor == RlibFlavor::Normal && sess.opts.unstable_opts.packed_bundled_libs => {}
+ NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
if flavor == RlibFlavor::Normal =>
{
// Don't allow mixing +bundle with +whole_archive since an rlib may contain
@@ -348,7 +355,16 @@ fn link_rlib<'a>(
}
if let Some(name) = lib.name {
let location =
- find_library(name.as_str(), lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
+ find_native_static_library(name.as_str(), lib.verbatim, &lib_search_paths, sess);
+ if sess.opts.unstable_opts.packed_bundled_libs && flavor == RlibFlavor::Normal {
+ packed_bundled_libs.push(find_native_static_library(
+ lib.filename.unwrap().as_str(),
+ Some(true),
+ &lib_search_paths,
+ sess,
+ ));
+ continue;
+ }
ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| {
sess.fatal(&format!(
"failed to add native library {}: {}",
@@ -360,13 +376,14 @@ fn link_rlib<'a>(
}
for (raw_dylib_name, raw_dylib_imports) in
- collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
+ collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
{
let output_path = archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir.as_ref(),
+ true,
);
ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| {
@@ -403,6 +420,12 @@ fn link_rlib<'a>(
ab.add_file(&trailing_metadata);
}
+ // Add all bundled static native library dependencies.
+ // Archives added to the end of .rlib archive, see comment above for the reason.
+ for lib in packed_bundled_libs {
+ ab.add_file(&lib)
+ }
+
return Ok(ab);
}
@@ -412,9 +435,9 @@ fn link_rlib<'a>(
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
/// linker appears to expect only a single import library for each library used, so we need to
/// collate the symbols together by library name before generating the import libraries.
-fn collate_raw_dylibs(
- sess: &Session,
- used_libraries: &[NativeLib],
+fn collate_raw_dylibs<'a, 'b>(
+ sess: &'a Session,
+ used_libraries: impl IntoIterator<Item = &'b NativeLib>,
) -> Result<Vec<(String, Vec<DllImport>)>, ErrorGuaranteed> {
// Use index maps to preserve original order of imports and libraries.
let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();
@@ -552,14 +575,6 @@ fn link_staticlib<'a>(
Ok(())
}
-fn escape_stdout_stderr_string(s: &[u8]) -> String {
- str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
- let mut x = "Non-UTF-8 output: ".to_string();
- x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
- x
- })
-}
-
/// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a
/// DWARF package.
fn link_dwarf_object<'a>(
@@ -764,15 +779,15 @@ fn link_natively<'a>(
"Linker does not support -static-pie command line option. Retrying with -static instead."
);
// Mirror `add_(pre,post)_link_objects` to replace CRT objects.
- let self_contained = crt_objects_fallback(sess, crate_type);
+ let self_contained = self_contained(sess, crate_type);
let opts = &sess.target;
let pre_objects = if self_contained {
- &opts.pre_link_objects_fallback
+ &opts.pre_link_objects_self_contained
} else {
&opts.pre_link_objects
};
let post_objects = if self_contained {
- &opts.post_link_objects_fallback
+ &opts.post_link_objects_self_contained
} else {
&opts.post_link_objects
};
@@ -866,7 +881,7 @@ fn link_natively<'a>(
if !prog.status.success() {
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
- let escaped_output = escape_stdout_stderr_string(&output);
+ let escaped_output = escape_string(&output);
let mut err = sess.struct_err(&format!(
"linking with `{}` failed: {}",
linker_path.display(),
@@ -934,8 +949,8 @@ fn link_natively<'a>(
sess.abort_if_errors();
}
- info!("linker stderr:\n{}", escape_stdout_stderr_string(&prog.stderr));
- info!("linker stdout:\n{}", escape_stdout_stderr_string(&prog.stdout));
+ info!("linker stderr:\n{}", escape_string(&prog.stderr));
+ info!("linker stdout:\n{}", escape_string(&prog.stdout));
}
Err(e) => {
let linker_not_found = e.kind() == io::ErrorKind::NotFound;
@@ -1065,11 +1080,10 @@ fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Opti
}
fn escape_string(s: &[u8]) -> String {
- str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
- let mut x = "Non-UTF-8 output: ".to_string();
- x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
- x
- })
+ match str::from_utf8(s) {
+ Ok(s) => s.to_owned(),
+ Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()),
+ }
}
fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
@@ -1173,13 +1187,6 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
// only the linker flavor is known; use the default linker for the selected flavor
(None, Some(flavor)) => Some((
PathBuf::from(match flavor {
- LinkerFlavor::Em => {
- if cfg!(windows) {
- "emcc.bat"
- } else {
- "emcc"
- }
- }
LinkerFlavor::Gcc => {
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
// On historical Solaris systems, "cc" may have
@@ -1194,11 +1201,17 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
}
}
LinkerFlavor::Ld => "ld",
- LinkerFlavor::Msvc => "link.exe",
LinkerFlavor::Lld(_) => "lld",
- LinkerFlavor::PtxLinker => "rust-ptx-linker",
- LinkerFlavor::BpfLinker => "bpf-linker",
- LinkerFlavor::L4Bender => "l4-bender",
+ LinkerFlavor::Msvc => "link.exe",
+ LinkerFlavor::EmCc => {
+ if cfg!(windows) {
+ "emcc.bat"
+ } else {
+ "emcc"
+ }
+ }
+ LinkerFlavor::Bpf => "bpf-linker",
+ LinkerFlavor::Ptx => "rust-ptx-linker",
}),
flavor,
)),
@@ -1208,7 +1221,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
});
let flavor = if stem == "emcc" {
- LinkerFlavor::Em
+ LinkerFlavor::EmCc
} else if stem == "gcc"
|| stem.ends_with("-gcc")
|| stem == "clang"
@@ -1236,7 +1249,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
// linker and linker flavor specified via command line have precedence over what the target
// specification specifies
- if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) {
+ let linker_flavor = sess.opts.cg.linker_flavor.map(LinkerFlavor::from_cli);
+ if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
return ret;
}
@@ -1556,26 +1570,26 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
true
}
-/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
+/// Various toolchain components used during linking are used from rustc distribution
+/// instead of being found somewhere on the host system.
/// We only provide such support for a very limited number of targets.
-fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
+fn self_contained(sess: &Session, crate_type: CrateType) -> bool {
if let Some(self_contained) = sess.opts.cg.link_self_contained {
return self_contained;
}
- match sess.target.crt_objects_fallback {
+ match sess.target.link_self_contained {
+ LinkSelfContainedDefault::False => false,
+ LinkSelfContainedDefault::True => true,
// FIXME: Find a better heuristic for "native musl toolchain is available",
// based on host and linker path, for example.
// (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
- Some(CrtObjectsFallback::Musl) => sess.crt_static(Some(crate_type)),
- Some(CrtObjectsFallback::Mingw) => {
+ LinkSelfContainedDefault::Musl => sess.crt_static(Some(crate_type)),
+ LinkSelfContainedDefault::Mingw => {
sess.host == sess.target
&& sess.target.vendor != "uwp"
&& detect_self_contained_mingw(&sess)
}
- // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
- Some(CrtObjectsFallback::Wasm) => true,
- None => false,
}
}
@@ -1583,12 +1597,21 @@ fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
fn add_pre_link_objects(
cmd: &mut dyn Linker,
sess: &Session,
+ flavor: LinkerFlavor,
link_output_kind: LinkOutputKind,
self_contained: bool,
) {
+ // FIXME: we are currently missing some infra here (per-linker-flavor CRT objects),
+ // so Fuchsia has to be special-cased.
let opts = &sess.target;
- let objects =
- if self_contained { &opts.pre_link_objects_fallback } else { &opts.pre_link_objects };
+ let empty = Default::default();
+ let objects = if self_contained {
+ &opts.pre_link_objects_self_contained
+ } else if !(sess.target.os == "fuchsia" && flavor == LinkerFlavor::Gcc) {
+ &opts.pre_link_objects
+ } else {
+ &empty
+ };
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
cmd.add_object(&get_object_file_path(sess, obj, self_contained));
}
@@ -1601,9 +1624,11 @@ fn add_post_link_objects(
link_output_kind: LinkOutputKind,
self_contained: bool,
) {
- let opts = &sess.target;
- let objects =
- if self_contained { &opts.post_link_objects_fallback } else { &opts.post_link_objects };
+ let objects = if self_contained {
+ &sess.target.post_link_objects_self_contained
+ } else {
+ &sess.target.post_link_objects
+ };
for obj in objects.get(&link_output_kind).iter().copied().flatten() {
cmd.add_object(&get_object_file_path(sess, obj, self_contained));
}
@@ -1703,6 +1728,13 @@ fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor
/// that are necessary for the linking. They are only present in symbol table but not actually
/// used in any sections, so the linker will therefore pick relevant rlibs for linking, but
/// unused `#[no_mangle]` or `#[used]` can still be discard by GC sections.
+///
+/// There's a few internal crates in the standard library (aka libcore and
+/// libstd) which actually have a circular dependence upon one another. This
+/// currently arises through "weak lang items" where libcore requires things
+/// like `rust_begin_unwind` but libstd ends up defining it. To get this
+/// circular dependence to work correctly we declare some of these things
+/// in this synthetic object.
fn add_linked_symbol_object(
cmd: &mut dyn Linker,
sess: &Session,
@@ -1882,12 +1914,12 @@ fn linker_with_args<'a>(
out_filename: &Path,
codegen_results: &CodegenResults,
) -> Result<Command, ErrorGuaranteed> {
- let crt_objects_fallback = crt_objects_fallback(sess, crate_type);
+ let self_contained = self_contained(sess, crate_type);
let cmd = &mut *super::linker::get_linker(
sess,
path,
flavor,
- crt_objects_fallback,
+ self_contained,
&codegen_results.crate_info.target_cpu,
);
let link_output_kind = link_output_kind(sess, crate_type);
@@ -1914,7 +1946,7 @@ fn linker_with_args<'a>(
// ------------ Object code and libraries, order-dependent ------------
// Pre-link CRT objects.
- add_pre_link_objects(cmd, sess, link_output_kind, crt_objects_fallback);
+ add_pre_link_objects(cmd, sess, flavor, link_output_kind, self_contained);
add_linked_symbol_object(
cmd,
@@ -1947,7 +1979,6 @@ fn linker_with_args<'a>(
// Upstream rust libraries are not supposed to depend on our local native
// libraries as that would violate the structure of the DAG, in that
// scenario they are required to link to them as well in a shared fashion.
- // (The current implementation still doesn't prevent it though, see the FIXME below.)
//
// Note that upstream rust libraries may contain native dependencies as
// well, but they also can't depend on what we just started to add to the
@@ -1968,15 +1999,16 @@ fn linker_with_args<'a>(
// and move this option back to the top.
cmd.add_as_needed();
- // FIXME: Move this below to other native libraries
- // (or alternatively link all native libraries after their respective crates).
- // This change is somewhat breaking in practice due to local static libraries being linked
- // as whole-archive (#85144), so removing whole-archive may be a pre-requisite.
+ // Local native libraries of all kinds.
+ //
+ // If `-Zlink-native-libraries=false` is set, then the assumption is that an
+ // external build system already has the native dependencies defined, and it
+ // will provide them to the linker itself.
if sess.opts.unstable_opts.link_native_libraries {
add_local_native_libraries(cmd, sess, codegen_results);
}
- // Upstream rust libraries and their non-bundled static libraries
+ // Upstream rust libraries and their (possibly bundled) static native libraries.
add_upstream_rust_crates(
cmd,
sess,
@@ -1986,24 +2018,54 @@ fn linker_with_args<'a>(
tmpdir,
);
- // Upstream dynamic native libraries linked with `#[link]` attributes at and `-l`
- // command line options.
- // If -Zlink-native-libraries=false is set, then the assumption is that an
- // external build system already has the native dependencies defined, and it
- // will provide them to the linker itself.
+ // Dynamic native libraries from upstream crates.
+ //
+ // FIXME: Merge this to `add_upstream_rust_crates` so that all native libraries are linked
+ // together with their respective upstream crates, and in their originally specified order.
+ // This may be slightly breaking due to our use of `--as-needed` and needs a crater run.
if sess.opts.unstable_opts.link_native_libraries {
add_upstream_native_libraries(cmd, sess, codegen_results);
}
// Link with the import library generated for any raw-dylib functions.
for (raw_dylib_name, raw_dylib_imports) in
- collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
+ collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
{
cmd.add_object(&archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir,
+ true,
+ ));
+ }
+ // As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case
+ // they are used within inlined functions or instantiated generic functions. We do this *after*
+ // handling the raw-dylib symbols in the current crate to make sure that those are chosen first
+ // by the linker.
+ let (_, dependency_linkage) = codegen_results
+ .crate_info
+ .dependency_formats
+ .iter()
+ .find(|(ty, _)| *ty == crate_type)
+ .expect("failed to find crate type in dependency format list");
+ let native_libraries_from_nonstatics = codegen_results
+ .crate_info
+ .native_libraries
+ .iter()
+ .filter_map(|(cnum, libraries)| {
+ (dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries)
+ })
+ .flatten();
+ for (raw_dylib_name, raw_dylib_imports) in
+ collate_raw_dylibs(sess, native_libraries_from_nonstatics)?
+ {
+ cmd.add_object(&archive_builder_builder.create_dll_import_lib(
+ sess,
+ &raw_dylib_name,
+ &raw_dylib_imports,
+ tmpdir,
+ false,
));
}
@@ -2024,7 +2086,7 @@ fn linker_with_args<'a>(
cmd,
sess,
link_output_kind,
- crt_objects_fallback,
+ self_contained,
flavor,
crate_type,
codegen_results,
@@ -2040,7 +2102,7 @@ fn linker_with_args<'a>(
// ------------ Object code and libraries, order-dependent ------------
// Post-link CRT objects.
- add_post_link_objects(cmd, sess, link_output_kind, crt_objects_fallback);
+ add_post_link_objects(cmd, sess, link_output_kind, self_contained);
// ------------ Late order-dependent options ------------
@@ -2057,7 +2119,7 @@ fn add_order_independent_options(
cmd: &mut dyn Linker,
sess: &Session,
link_output_kind: LinkOutputKind,
- crt_objects_fallback: bool,
+ self_contained: bool,
flavor: LinkerFlavor,
crate_type: CrateType,
codegen_results: &CodegenResults,
@@ -2070,7 +2132,10 @@ fn add_order_independent_options(
add_link_script(cmd, sess, tmpdir, crate_type);
- if sess.target.os == "fuchsia" && crate_type == CrateType::Executable {
+ if sess.target.os == "fuchsia"
+ && crate_type == CrateType::Executable
+ && flavor != LinkerFlavor::Gcc
+ {
let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
"asan/"
} else {
@@ -2086,7 +2151,7 @@ fn add_order_independent_options(
// Make the binary compatible with data execution prevention schemes.
cmd.add_no_exec();
- if crt_objects_fallback {
+ if self_contained {
cmd.no_crt_objects();
}
@@ -2099,11 +2164,11 @@ fn add_order_independent_options(
});
}
- if flavor == LinkerFlavor::PtxLinker {
+ if flavor == LinkerFlavor::Ptx {
// Provide the linker with fallback to internal `target-cpu`.
cmd.arg("--fallback-arch");
cmd.arg(&codegen_results.crate_info.target_cpu);
- } else if flavor == LinkerFlavor::BpfLinker {
+ } else if flavor == LinkerFlavor::Bpf {
cmd.arg("--cpu");
cmd.arg(&codegen_results.crate_info.target_cpu);
cmd.arg("--cpu-features");
@@ -2115,7 +2180,7 @@ fn add_order_independent_options(
cmd.linker_plugin_lto();
- add_library_search_dirs(cmd, sess, crt_objects_fallback);
+ add_library_search_dirs(cmd, sess, self_contained);
cmd.output_filename(out_filename);
@@ -2319,72 +2384,25 @@ fn add_upstream_rust_crates<'a>(
// crates.
let deps = &codegen_results.crate_info.used_crates;
- // There's a few internal crates in the standard library (aka libcore and
- // libstd) which actually have a circular dependence upon one another. This
- // currently arises through "weak lang items" where libcore requires things
- // like `rust_begin_unwind` but libstd ends up defining it. To get this
- // circular dependence to work correctly in all situations we'll need to be
- // sure to correctly apply the `--start-group` and `--end-group` options to
- // GNU linkers, otherwise if we don't use any other symbol from the standard
- // library it'll get discarded and the whole application won't link.
- //
- // In this loop we're calculating the `group_end`, after which crate to
- // pass `--end-group` and `group_start`, before which crate to pass
- // `--start-group`. We currently do this by passing `--end-group` after
- // the first crate (when iterating backwards) that requires a lang item
- // defined somewhere else. Once that's set then when we've defined all the
- // necessary lang items we'll pass `--start-group`.
- //
- // Note that this isn't amazing logic for now but it should do the trick
- // for the current implementation of the standard library.
- let mut group_end = None;
- let mut group_start = None;
- // Crates available for linking thus far.
- let mut available = FxHashSet::default();
- // Crates required to satisfy dependencies discovered so far.
- let mut required = FxHashSet::default();
-
- let info = &codegen_results.crate_info;
- for &cnum in deps.iter().rev() {
- if let Some(missing) = info.missing_lang_items.get(&cnum) {
- let missing_crates = missing.iter().map(|i| info.lang_item_to_crate.get(i).copied());
- required.extend(missing_crates);
- }
-
- required.insert(Some(cnum));
- available.insert(Some(cnum));
-
- if required.len() > available.len() && group_end.is_none() {
- group_end = Some(cnum);
- }
- if required.len() == available.len() && group_end.is_some() {
- group_start = Some(cnum);
- break;
- }
- }
-
- // If we didn't end up filling in all lang items from upstream crates then
- // we'll be filling it in with our crate. This probably means we're the
- // standard library itself, so skip this for now.
- if group_end.is_some() && group_start.is_none() {
- group_end = None;
- }
-
let mut compiler_builtins = None;
let search_path = OnceCell::new();
for &cnum in deps.iter() {
- if group_start == Some(cnum) {
- cmd.group_start();
- }
-
// We may not pass all crates through to the linker. Some crates may
// appear statically in an existing dylib, meaning we'll pick up all the
// symbols from the dylib.
let src = &codegen_results.crate_info.used_crate_source[&cnum];
match data[cnum.as_usize() - 1] {
_ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
- add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+ add_static_crate(
+ cmd,
+ sess,
+ archive_builder_builder,
+ codegen_results,
+ tmpdir,
+ cnum,
+ &Default::default(),
+ );
}
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
@@ -2394,17 +2412,41 @@ fn add_upstream_rust_crates<'a>(
}
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
Linkage::Static => {
- add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+ let bundled_libs = if sess.opts.unstable_opts.packed_bundled_libs {
+ codegen_results.crate_info.native_libraries[&cnum]
+ .iter()
+ .filter_map(|lib| lib.filename)
+ .collect::<FxHashSet<_>>()
+ } else {
+ Default::default()
+ };
+ add_static_crate(
+ cmd,
+ sess,
+ archive_builder_builder,
+ codegen_results,
+ tmpdir,
+ cnum,
+ &bundled_libs,
+ );
// Link static native libs with "-bundle" modifier only if the crate they originate from
// is being linked statically to the current crate. If it's linked dynamically
// or is an rlib already included via some other dylib crate, the symbols from
// native libs will have already been included in that dylib.
//
- // If -Zlink-native-libraries=false is set, then the assumption is that an
+ // If `-Zlink-native-libraries=false` is set, then the assumption is that an
// external build system already has the native dependencies defined, and it
// will provide them to the linker itself.
if sess.opts.unstable_opts.link_native_libraries {
+ if sess.opts.unstable_opts.packed_bundled_libs {
+ // If rlib contains native libs as archives, unpack them to tmpdir.
+ let rlib = &src.rlib.as_ref().unwrap().0;
+ archive_builder_builder
+ .extract_bundled_libs(rlib, tmpdir, &bundled_libs)
+ .unwrap_or_else(|e| sess.fatal(e));
+ }
+
let mut last = (None, NativeLibKind::Unspecified, None);
for lib in &codegen_results.crate_info.native_libraries[&cnum] {
let Some(name) = lib.name else {
@@ -2437,6 +2479,14 @@ fn add_upstream_rust_crates<'a>(
bundle: Some(false),
whole_archive: Some(false) | None,
} => {
+ // HACK/FIXME: Fixup a circular dependency between libgcc and libc
+ // with glibc. This logic should be moved to the libc crate.
+ if sess.target.os == "linux"
+ && sess.target.env == "gnu"
+ && name == "c"
+ {
+ cmd.link_staticlib("gcc", false);
+ }
cmd.link_staticlib(name, lib.verbatim.unwrap_or(false));
}
NativeLibKind::LinkArg => {
@@ -2446,20 +2496,23 @@ fn add_upstream_rust_crates<'a>(
| NativeLibKind::Framework { .. }
| NativeLibKind::Unspecified
| NativeLibKind::RawDylib => {}
- NativeLibKind::Static {
- bundle: Some(true) | None,
- whole_archive: _,
- } => {}
+ NativeLibKind::Static { bundle: Some(true) | None, whole_archive } => {
+ if sess.opts.unstable_opts.packed_bundled_libs {
+ // If rlib contains native libs as archives, they are unpacked to tmpdir.
+ let path = tmpdir.join(lib.filename.unwrap().as_str());
+ if whole_archive == Some(true) {
+ cmd.link_whole_rlib(&path);
+ } else {
+ cmd.link_rlib(&path);
+ }
+ }
+ }
}
}
}
}
Linkage::Dynamic => add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0),
}
-
- if group_end == Some(cnum) {
- cmd.group_end();
- }
}
// compiler-builtins are always placed last to ensure that they're
@@ -2468,7 +2521,15 @@ fn add_upstream_rust_crates<'a>(
// was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
// is used)
if let Some(cnum) = compiler_builtins {
- add_static_crate(cmd, sess, archive_builder_builder, codegen_results, tmpdir, cnum);
+ add_static_crate(
+ cmd,
+ sess,
+ archive_builder_builder,
+ codegen_results,
+ tmpdir,
+ cnum,
+ &Default::default(),
+ );
}
// Converts a library file-stem into a cc -l argument
@@ -2501,6 +2562,7 @@ fn add_upstream_rust_crates<'a>(
codegen_results: &CodegenResults,
tmpdir: &Path,
cnum: CrateNum,
+ bundled_lib_file_names: &FxHashSet<Symbol>,
) {
let src = &codegen_results.crate_info.used_crate_source[&cnum];
let cratepath = &src.rlib.as_ref().unwrap().0;
@@ -2529,6 +2591,7 @@ fn add_upstream_rust_crates<'a>(
let dst = tmpdir.join(cratepath.file_name().unwrap());
let name = cratepath.file_name().unwrap().to_str().unwrap();
let name = &name[3..name.len() - 5]; // chop off lib/.rlib
+ let bundled_lib_file_names = bundled_lib_file_names.clone();
sess.prof.generic_activity_with_arg("link_altering_rlib", name).run(|| {
let canonical_name = name.replace('-', "_");
@@ -2562,6 +2625,15 @@ fn add_upstream_rust_crates<'a>(
let skip_because_lto =
upstream_rust_objects_already_included && is_rust_object && is_builtins;
+ // We skip native libraries because:
+ // 1. This native libraries won't be used from the generated rlib,
+ // so we can throw them away to avoid the copying work.
+ // 2. We can't allow it to be a single remaining entry in archive
+ // as some linkers may complain on that.
+ if bundled_lib_file_names.contains(&Symbol::intern(f)) {
+ return true;
+ }
+
if skip_because_cfg_say_so || skip_because_lto {
return true;
}
@@ -2657,7 +2729,7 @@ fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
}
}
-fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
+pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
match sess.lto() {
config::Lto::Fat => true,
config::Lto::Thin => {
@@ -2674,11 +2746,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let os = &sess.target.os;
let llvm_target = &sess.target.llvm_target;
if sess.target.vendor != "apple"
- || !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
+ || !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos")
|| (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
{
return;
}
+
+ if os == "macos" && flavor != LinkerFlavor::Lld(LldFlavor::Ld64) {
+ return;
+ }
+
let sdk_name = match (arch.as_ref(), os.as_ref()) {
("aarch64", "tvos") => "appletvos",
("x86_64", "tvos") => "appletvsimulator",
@@ -2694,6 +2771,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
("aarch64", "watchos") => "watchos",
("arm", "watchos") => "watchos",
+ (_, "macos") => "macosx",
_ => {
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
return;
@@ -2777,20 +2855,24 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let LinkerFlavor::Gcc = flavor {
match ld_impl {
LdImpl::Lld => {
- let tools_path = sess.get_tools_search_paths(false);
- let gcc_ld_dir = tools_path
- .into_iter()
- .map(|p| p.join("gcc-ld"))
- .find(|p| {
- p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()
- })
- .unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
- cmd.arg({
- let mut arg = OsString::from("-B");
- arg.push(gcc_ld_dir);
- arg
- });
- cmd.arg(format!("-Wl,-rustc-lld-flavor={}", sess.target.lld_flavor.as_str()));
+ // Implement the "self-contained" part of -Zgcc-ld
+ // by adding rustc distribution directories to the tool search path.
+ for path in sess.get_tools_search_paths(false) {
+ cmd.arg({
+ let mut arg = OsString::from("-B");
+ arg.push(path.join("gcc-ld"));
+ arg
+ });
+ }
+ // Implement the "linker flavor" part of -Zgcc-ld
+ // by asking cc to use some kind of lld.
+ cmd.arg("-fuse-ld=lld");
+ if sess.target.lld_flavor != LldFlavor::Ld {
+ // Tell clang to use a non-default LLD flavor.
+ // Gcc doesn't understand the target option, but we currently assume
+ // that gcc is not used for Apple and Wasm targets (#97402).
+ cmd.arg(format!("--target={}", sess.target.llvm_target));
+ }
}
}
} else {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index ce51b2e95..e505543b2 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1,4 +1,3 @@
-use super::archive;
use super::command::Command;
use super::symbol_export;
use rustc_span::symbol::sym;
@@ -11,6 +10,7 @@ use std::path::{Path, PathBuf};
use std::{env, mem, str};
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
+use rustc_metadata::find_native_static_library;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
use rustc_middle::ty::TyCtxt;
@@ -126,29 +126,26 @@ pub fn get_linker<'a>(
// to the linker args construction.
assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp");
match flavor {
- LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
- Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
- }
- LinkerFlavor::Em => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Gcc => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false })
as Box<dyn Linker>
}
-
+ LinkerFlavor::Ld if sess.target.os == "l4re" => {
+ Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>
+ }
LinkerFlavor::Lld(LldFlavor::Ld)
| LinkerFlavor::Lld(LldFlavor::Ld64)
| LinkerFlavor::Ld => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true })
as Box<dyn Linker>
}
-
+ LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
+ Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
+ }
LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
-
- LinkerFlavor::PtxLinker => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
-
- LinkerFlavor::BpfLinker => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
-
- LinkerFlavor::L4Bender => Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>,
+ LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
+ LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
+ LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
}
}
@@ -186,8 +183,6 @@ pub trait Linker {
fn no_default_libraries(&mut self);
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType, symbols: &[String]);
fn subsystem(&mut self, subsystem: &str);
- fn group_start(&mut self);
- fn group_end(&mut self);
fn linker_plugin_lto(&mut self);
fn add_eh_frame_header(&mut self) {}
fn add_no_exec(&mut self) {}
@@ -519,7 +514,7 @@ impl<'a> Linker for GccLinker<'a> {
// -force_load is the macOS equivalent of --whole-archive, but it
// involves passing the full path to the library to link.
self.linker_arg("-force_load");
- let lib = archive::find_library(lib, verbatim, search_path, &self.sess);
+ let lib = find_native_static_library(lib, Some(verbatim), search_path, &self.sess);
self.linker_arg(&lib);
}
}
@@ -733,18 +728,6 @@ impl<'a> Linker for GccLinker<'a> {
self.hint_dynamic(); // Reset to default before returning the composed command line.
}
- fn group_start(&mut self) {
- if self.takes_hints() {
- self.linker_arg("--start-group");
- }
- }
-
- fn group_end(&mut self) {
- if self.takes_hints() {
- self.linker_arg("--end-group");
- }
- }
-
fn linker_plugin_lto(&mut self) {
match self.sess.opts.cg.linker_plugin_lto {
LinkerPluginLto::Disabled => {
@@ -1022,10 +1005,6 @@ impl<'a> Linker for MsvcLinker<'a> {
}
}
- // MSVC doesn't need group indicators
- fn group_start(&mut self) {}
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {
// Do nothing
}
@@ -1168,10 +1147,6 @@ impl<'a> Linker for EmLinker<'a> {
// noop
}
- // Appears not necessary on Emscripten
- fn group_start(&mut self) {}
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {
// Do nothing
}
@@ -1347,10 +1322,6 @@ impl<'a> Linker for WasmLd<'a> {
fn subsystem(&mut self, _subsystem: &str) {}
- // Not needed for now with LLD
- fn group_start(&mut self) {}
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {
// Do nothing for now
}
@@ -1479,14 +1450,6 @@ impl<'a> Linker for L4Bender<'a> {
self.hint_static(); // Reset to default before returning the composed command line.
}
- fn group_start(&mut self) {
- self.cmd.arg("--start-group");
- }
-
- fn group_end(&mut self) {
- self.cmd.arg("--end-group");
- }
-
fn linker_plugin_lto(&mut self) {}
fn control_flow_guard(&mut self) {}
@@ -1667,10 +1630,6 @@ impl<'a> Linker for PtxLinker<'a> {
fn subsystem(&mut self, _subsystem: &str) {}
- fn group_start(&mut self) {}
-
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {}
}
@@ -1780,9 +1739,5 @@ impl<'a> Linker for BpfLinker<'a> {
fn subsystem(&mut self, _subsystem: &str) {}
- fn group_start(&mut self) {}
-
- fn group_end(&mut self) {}
-
fn linker_plugin_lto(&mut self) {}
}
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 0302c2881..99ddd1764 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -117,6 +117,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
"riscv32" => Architecture::Riscv32,
"riscv64" => Architecture::Riscv64,
"sparc64" => Architecture::Sparc64,
+ "avr" => Architecture::Avr,
+ "msp430" => Architecture::Msp430,
+ "hexagon" => Architecture::Hexagon,
+ "bpf" => Architecture::Bpf,
// Unsupported architecture.
_ => return None,
};
@@ -187,12 +191,12 @@ pub enum MetadataPosition {
Last,
}
-// For rlibs we "pack" rustc metadata into a dummy object file. When rustc
-// creates a dylib crate type it will pass `--whole-archive` (or the
-// platform equivalent) to include all object files from an rlib into the
-// final dylib itself. This causes linkers to iterate and try to include all
-// files located in an archive, so if metadata is stored in an archive then
-// it needs to be of a form that the linker will be able to process.
+// For rlibs we "pack" rustc metadata into a dummy object file.
+//
+// Historically it was needed because rustc linked rlibs as whole-archive in some cases.
+// In that case linkers try to include all files located in an archive, so if metadata is stored
+// in an archive then it needs to be of a form that the linker is able to process.
+// Now it's not clear whether metadata still needs to be wrapped into an object file or not.
//
// Note, though, that we don't actually want this metadata to show up in any
// final output of the compiler. Instead this is purely for rustc's own
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index e6b605575..8d7e2c5cf 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -103,18 +103,14 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
}
})
.map(|def_id| {
- let (export_level, used) = if special_runtime_crate {
- let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
- // We won't link right if these symbols are stripped during LTO.
- let used = match name {
- "rust_eh_personality"
- | "rust_eh_register_frames"
- | "rust_eh_unregister_frames" => true,
- _ => false,
- };
- (SymbolExportLevel::Rust, used)
+ // We won't link right if this symbol is stripped during LTO.
+ let name = tcx.symbol_name(Instance::mono(tcx, def_id.to_def_id())).name;
+ let used = name == "rust_eh_personality";
+
+ let export_level = if special_runtime_crate {
+ SymbolExportLevel::Rust
} else {
- (symbol_export_level(tcx, def_id.to_def_id()), false)
+ symbol_export_level(tcx, def_id.to_def_id())
};
let codegen_attrs = tcx.codegen_fn_attrs(def_id.to_def_id());
debug!(
@@ -544,7 +540,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
.map(|fnabi| (fnabi.conv, &fnabi.args[..]))
.unwrap_or((Conv::Rust, &[]));
- // Decorate symbols with prefices, suffices and total number of bytes of arguments.
+ // Decorate symbols with prefixes, suffixes and total number of bytes of arguments.
// Reference: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names?view=msvc-170
let (prefix, suffix) = match conv {
Conv::X86Fastcall => ("@", "@"),
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 1b5ad8710..68f3b19b7 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -15,7 +15,7 @@ use rustc_data_structures::profiling::TimingGuard;
use rustc_data_structures::profiling::VerboseTimingGuard;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::Emitter;
-use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
+use rustc_errors::{translation::Translate, DiagnosticId, FatalError, Handler, Level};
use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_incremental::{
@@ -256,8 +256,11 @@ impl ModuleConfig {
{
MergeFunctions::Disabled => false,
MergeFunctions::Trampolines | MergeFunctions::Aliases => {
- sess.opts.optimize == config::OptLevel::Default
- || sess.opts.optimize == config::OptLevel::Aggressive
+ use config::OptLevel::*;
+ match sess.opts.optimize {
+ Aggressive | Default | SizeMin | Size => true,
+ Less | No => false,
+ }
}
},
@@ -1737,6 +1740,16 @@ impl SharedEmitter {
}
}
+impl Translate for SharedEmitter {
+ fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
+ None
+ }
+
+ fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
+ panic!("shared emitter attempted to translate a diagnostic");
+ }
+}
+
impl Emitter for SharedEmitter {
fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
let fluent_args = self.to_fluent_args(diag.args());
@@ -1758,14 +1771,6 @@ impl Emitter for SharedEmitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
None
}
-
- fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
- None
- }
-
- fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
- panic!("shared emitter attempted to translate a diagnostic");
- }
}
impl SharedEmitterMain {
@@ -1887,7 +1892,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
}
});
- sess.cgu_reuse_tracker.check_expected_reuse(sess.diagnostic());
+ sess.cgu_reuse_tracker.check_expected_reuse(sess);
sess.abort_if_errors();