summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs241
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs151
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs63
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs112
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs356
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs104
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs208
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/abi.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/misc.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/write.rs1
22 files changed, 906 insertions, 447 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 6cce95427..0dc0dee86 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -11,7 +11,7 @@ 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;
-use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
+use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Lto, Strip};
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
use rustc_session::cstore::DllImport;
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
@@ -23,20 +23,23 @@ use rustc_session::{filesearch, Session};
use rustc_span::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile;
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 rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy};
+use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, Target};
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use super::command::Command;
use super::linker::{self, Linker};
use super::metadata::{create_rmeta_file, MetadataPosition};
use super::rpath::{self, RPathConfig};
-use crate::{looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib};
+use crate::{
+ errors, looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib,
+};
use cc::windows_registry;
use regex::Regex;
use tempfile::Builder as TempFileBuilder;
+use itertools::Itertools;
use std::borrow::Borrow;
use std::cell::OnceCell;
use std::collections::BTreeSet;
@@ -93,7 +96,7 @@ pub fn link_binary<'a>(
let tmpdir = TempFileBuilder::new()
.prefix("rustc")
.tempdir()
- .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err)));
+ .unwrap_or_else(|error| sess.emit_fatal(errors::CreateTempDir { error }));
let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps);
let out_filename = out_filename(
sess,
@@ -206,11 +209,29 @@ pub fn link_binary<'a>(
}
pub fn each_linked_rlib(
+ sess: &Session,
info: &CrateInfo,
f: &mut dyn FnMut(CrateNum, &Path),
-) -> Result<(), String> {
+) -> Result<(), errors::LinkRlibError> {
let crates = info.used_crates.iter();
let mut fmts = None;
+
+ let lto_active = matches!(sess.lto(), Lto::Fat | Lto::Thin);
+ if lto_active {
+ for combination in info.dependency_formats.iter().combinations(2) {
+ let (ty1, list1) = &combination[0];
+ let (ty2, list2) = &combination[1];
+ if list1 != list2 {
+ return Err(errors::LinkRlibError::IncompatibleDependencyFormats {
+ ty1: format!("{ty1:?}"),
+ ty2: format!("{ty2:?}"),
+ list1: format!("{list1:?}"),
+ list2: format!("{list2:?}"),
+ });
+ }
+ }
+ }
+
for (ty, list) in info.dependency_formats.iter() {
match ty {
CrateType::Executable
@@ -220,30 +241,31 @@ pub fn each_linked_rlib(
fmts = Some(list);
break;
}
+ CrateType::Dylib if lto_active => {
+ fmts = Some(list);
+ break;
+ }
_ => {}
}
}
let Some(fmts) = fmts else {
- return Err("could not find formats for rlibs".to_string());
+ return Err(errors::LinkRlibError::MissingFormat);
};
for &cnum in crates {
match fmts.get(cnum.as_usize() - 1) {
Some(&Linkage::NotLinked | &Linkage::IncludedFromDylib) => continue,
Some(_) => {}
- None => return Err("could not find formats for rlibs".to_string()),
+ None => return Err(errors::LinkRlibError::MissingFormat),
}
- let name = info.crate_name[&cnum];
+ let crate_name = info.crate_name[&cnum];
let used_crate_source = &info.used_crate_source[&cnum];
if let Some((path, _)) = &used_crate_source.rlib {
f(cnum, &path);
} else {
if used_crate_source.rmeta.is_some() {
- return Err(format!(
- "could not find rlib for: `{}`, found rmeta (metadata) file",
- name
- ));
+ return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name });
} else {
- return Err(format!("could not find rlib for: `{}`", name));
+ return Err(errors::LinkRlibError::NotFound { crate_name });
}
}
}
@@ -340,10 +362,7 @@ fn link_rlib<'a>(
// -whole-archive and it isn't clear how we can currently handle such a
// situation correctly.
// See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897
- sess.err(
- "the linking modifiers `+bundle` and `+whole-archive` are not compatible \
- with each other when generating rlibs",
- );
+ sess.emit_err(errors::IncompatibleLinkingModifiers);
}
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
NativeLibKind::Static { bundle: Some(false), .. }
@@ -365,12 +384,8 @@ fn link_rlib<'a>(
));
continue;
}
- ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| {
- sess.fatal(&format!(
- "failed to add native library {}: {}",
- location.to_string_lossy(),
- e
- ));
+ ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| {
+ sess.emit_fatal(errors::AddNativeLibrary { library_path: location, error });
});
}
}
@@ -386,8 +401,8 @@ fn link_rlib<'a>(
true,
);
- ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| {
- sess.fatal(&format!("failed to add native library {}: {}", output_path.display(), e));
+ ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| {
+ sess.emit_fatal(errors::AddNativeLibrary { library_path: output_path, error });
});
}
@@ -452,14 +467,11 @@ fn collate_raw_dylibs<'a, 'b>(
// FIXME: when we add support for ordinals, figure out if we need to do anything
// if we have two DllImport values with the same name but different ordinals.
if import.calling_convention != old_import.calling_convention {
- sess.span_err(
- import.span,
- &format!(
- "multiple declarations of external function `{}` from \
- library `{}` have different calling conventions",
- import.name, name,
- ),
- );
+ sess.emit_err(errors::MultipleExternalFuncDecl {
+ span: import.span,
+ function: import.name,
+ library_name: &name,
+ });
}
}
}
@@ -502,7 +514,7 @@ fn link_staticlib<'a>(
)?;
let mut all_native_libs = vec![];
- let res = each_linked_rlib(&codegen_results.crate_info, &mut |cnum, path| {
+ let res = each_linked_rlib(sess, &codegen_results.crate_info, &mut |cnum, path| {
let name = codegen_results.crate_info.crate_name[&cnum];
let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
@@ -561,7 +573,7 @@ fn link_staticlib<'a>(
all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
});
if let Err(e) = res {
- sess.fatal(&e);
+ sess.emit_fatal(e);
}
ab.build(out_filename);
@@ -674,9 +686,7 @@ fn link_dwarf_object<'a>(
}) {
Ok(()) => {}
Err(e) => {
- sess.struct_err("linking dwarf objects with thorin failed")
- .note(&format!("{:?}", e))
- .emit();
+ sess.emit_err(errors::ThorinErrorWrapper(e));
sess.abort_if_errors();
}
}
@@ -749,8 +759,7 @@ fn link_natively<'a>(
// then it should not default to linking executables as pie. Different
// versions of gcc seem to use different quotes in the error message so
// don't check for them.
- if sess.target.linker_is_gnu
- && flavor != LinkerFlavor::Ld
+ if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
&& unknown_arg_regex.is_match(&out)
&& out.contains("-no-pie")
&& cmd.get_args().iter().any(|e| e.to_string_lossy() == "-no-pie")
@@ -768,8 +777,7 @@ fn link_natively<'a>(
// Detect '-static-pie' used with an older version of gcc or clang not supporting it.
// Fallback from '-static-pie' to '-static' in that case.
- if sess.target.linker_is_gnu
- && flavor != LinkerFlavor::Ld
+ if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
&& unknown_arg_regex.is_match(&out)
&& (out.contains("-static-pie") || out.contains("--no-dynamic-linker"))
&& cmd.get_args().iter().any(|e| e.to_string_lossy() == "-static-pie")
@@ -882,29 +890,20 @@ fn link_natively<'a>(
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
let escaped_output = escape_string(&output);
- let mut err = sess.struct_err(&format!(
- "linking with `{}` failed: {}",
- linker_path.display(),
- prog.status
- ));
- err.note(&format!("{:?}", &cmd)).note(&escaped_output);
- if escaped_output.contains("undefined reference to") {
- err.help(
- "some `extern` functions couldn't be found; some native libraries may \
- need to be installed or have their path specified",
- );
- err.note("use the `-l` flag to specify native libraries to link");
- err.note("use the `cargo:rustc-link-lib` directive to specify the native \
- libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)");
- }
- err.emit();
-
+ // FIXME: Add UI tests for this error.
+ let err = errors::LinkingFailed {
+ linker_path: &linker_path,
+ exit_status: prog.status,
+ command: &cmd,
+ escaped_output: &escaped_output,
+ };
+ sess.diagnostic().emit_err(err);
// If MSVC's `link.exe` was expected but the return code
// is not a Microsoft LNK error then suggest a way to fix or
// install the Visual Studio build tools.
if let Some(code) = prog.status.code() {
if sess.target.is_like_msvc
- && flavor == LinkerFlavor::Msvc
+ && flavor == LinkerFlavor::Msvc(Lld::No)
// Respect the command line override
&& sess.opts.cg.linker.is_none()
// Match exactly "link.exe"
@@ -980,9 +979,10 @@ fn link_natively<'a>(
but `link.exe` was not found",
);
sess.note_without_error(
- "please ensure that VS 2013, VS 2015, VS 2017, VS 2019 or VS 2022 \
- was installed with the Visual C++ option",
+ "please ensure that Visual Studio 2017 or later, or Build Tools \
+ for Visual Studio were installed with the Visual C++ option.",
);
+ sess.note_without_error("VS Code is a different product, and is not sufficient.");
}
sess.abort_if_errors();
}
@@ -1035,16 +1035,36 @@ fn link_natively<'a>(
if sess.target.is_like_osx {
match (strip, crate_type) {
- (Strip::Debuginfo, _) => strip_symbols_in_osx(sess, &out_filename, Some("-S")),
+ (Strip::Debuginfo, _) => {
+ strip_symbols_with_external_utility(sess, "strip", &out_filename, Some("-S"))
+ }
// Per the manpage, `-x` is the maximum safe strip level for dynamic libraries. (#93988)
(Strip::Symbols, CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro) => {
- strip_symbols_in_osx(sess, &out_filename, Some("-x"))
+ strip_symbols_with_external_utility(sess, "strip", &out_filename, Some("-x"))
+ }
+ (Strip::Symbols, _) => {
+ strip_symbols_with_external_utility(sess, "strip", &out_filename, None)
}
- (Strip::Symbols, _) => strip_symbols_in_osx(sess, &out_filename, None),
(Strip::None, _) => {}
}
}
+ if sess.target.os == "illumos" {
+ // Many illumos systems will have both the native 'strip' utility and
+ // the GNU one. Use the native version explicitly and do not rely on
+ // what's in the path.
+ let stripcmd = "/usr/bin/strip";
+ match strip {
+ // Always preserve the symbol table (-x).
+ Strip::Debuginfo => {
+ strip_symbols_with_external_utility(sess, stripcmd, &out_filename, Some("-x"))
+ }
+ // Strip::Symbols is handled via the --strip-all linker option.
+ Strip::Symbols => {}
+ Strip::None => {}
+ }
+ }
+
Ok(())
}
@@ -1056,8 +1076,13 @@ fn strip_value(sess: &Session) -> Strip {
}
}
-fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Option<&str>) {
- let mut cmd = Command::new("strip");
+fn strip_symbols_with_external_utility<'a>(
+ sess: &'a Session,
+ util: &str,
+ out_filename: &Path,
+ option: Option<&str>,
+) {
+ let mut cmd = Command::new(util);
if let Some(option) = option {
cmd.arg(option);
}
@@ -1068,14 +1093,14 @@ fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Opti
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
sess.struct_warn(&format!(
- "stripping debug info with `strip` failed: {}",
- prog.status
+ "stripping debug info with `{}` failed: {}",
+ util, prog.status
))
.note(&escape_string(&output))
.emit();
}
}
- Err(e) => sess.fatal(&format!("unable to run `strip`: {}", e)),
+ Err(e) => sess.fatal(&format!("unable to run `{}`: {}", util, e)),
}
}
@@ -1091,11 +1116,12 @@ fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut d
// both executables and dynamic shared objects. Everywhere else the runtimes
// are currently distributed as static libraries which should be linked to
// executables only.
- let needs_runtime = match crate_type {
- CrateType::Executable => true,
- CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => sess.target.is_like_osx,
- CrateType::Rlib | CrateType::Staticlib => false,
- };
+ let needs_runtime = !sess.target.is_like_android
+ && match crate_type {
+ CrateType::Executable => true,
+ CrateType::Dylib | CrateType::Cdylib | CrateType::ProcMacro => sess.target.is_like_osx,
+ CrateType::Rlib | CrateType::Staticlib => false,
+ };
if !needs_runtime {
return;
@@ -1187,7 +1213,10 @@ 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::Gcc => {
+ LinkerFlavor::Gnu(Cc::Yes, _)
+ | LinkerFlavor::Darwin(Cc::Yes, _)
+ | LinkerFlavor::WasmLld(Cc::Yes)
+ | LinkerFlavor::Unix(Cc::Yes) => {
if cfg!(any(target_os = "solaris", target_os = "illumos")) {
// On historical Solaris systems, "cc" may have
// been Sun Studio, which is not flag-compatible
@@ -1200,9 +1229,14 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
"cc"
}
}
- LinkerFlavor::Ld => "ld",
- LinkerFlavor::Lld(_) => "lld",
- LinkerFlavor::Msvc => "link.exe",
+ LinkerFlavor::Gnu(_, Lld::Yes)
+ | LinkerFlavor::Darwin(_, Lld::Yes)
+ | LinkerFlavor::WasmLld(..)
+ | LinkerFlavor::Msvc(Lld::Yes) => "lld",
+ LinkerFlavor::Gnu(..) | LinkerFlavor::Darwin(..) | LinkerFlavor::Unix(..) => {
+ "ld"
+ }
+ LinkerFlavor::Msvc(..) => "link.exe",
LinkerFlavor::EmCc => {
if cfg!(windows) {
"emcc.bat"
@@ -1227,15 +1261,20 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|| stem == "clang"
|| stem.ends_with("-clang")
{
- LinkerFlavor::Gcc
+ LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target)
} else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") {
- LinkerFlavor::Lld(LldFlavor::Wasm)
- } else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") {
- LinkerFlavor::Ld
- } else if stem == "link" || stem == "lld-link" {
- LinkerFlavor::Msvc
+ LinkerFlavor::WasmLld(Cc::No)
+ } else if stem == "ld" || stem.ends_with("-ld") {
+ LinkerFlavor::from_cli(LinkerFlavorCli::Ld, &sess.target)
+ } else if stem == "ld.lld" {
+ LinkerFlavor::Gnu(Cc::No, Lld::Yes)
+ } else if stem == "link" {
+ LinkerFlavor::Msvc(Lld::No)
+ } else if stem == "lld-link" {
+ LinkerFlavor::Msvc(Lld::Yes)
} else if stem == "lld" || stem == "rust-lld" {
- LinkerFlavor::Lld(sess.target.lld_flavor)
+ let lld_flavor = sess.target.linker_flavor.lld_flavor();
+ LinkerFlavor::from_cli(LinkerFlavorCli::Lld(lld_flavor), &sess.target)
} else {
// fall back to the value in the target spec
sess.target.linker_flavor
@@ -1249,7 +1288,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
- let linker_flavor = sess.opts.cg.linker_flavor.map(LinkerFlavor::from_cli);
+ let linker_flavor =
+ sess.opts.cg.linker_flavor.map(|flavor| LinkerFlavor::from_cli(flavor, &sess.target));
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
return ret;
}
@@ -1320,7 +1360,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
let verbatim = lib.verbatim.unwrap_or(false);
if sess.target.is_like_msvc {
Some(format!("{}{}", name, if verbatim { "" } else { ".lib" }))
- } else if sess.target.linker_is_gnu {
+ } else if sess.target.linker_flavor.is_gnu() {
Some(format!("-l{}{}", if verbatim { ":" } else { "" }, name))
} else {
Some(format!("-l{}", name))
@@ -1607,7 +1647,7 @@ fn add_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) {
+ } else if !(sess.target.os == "fuchsia" && matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))) {
&opts.pre_link_objects
} else {
&empty
@@ -1647,7 +1687,7 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor)
fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_type: CrateType) {
match (crate_type, &sess.target.link_script) {
(CrateType::Cdylib | CrateType::Executable, Some(script)) => {
- if !sess.target.linker_is_gnu {
+ if !sess.target.linker_flavor.is_gnu() {
sess.fatal("can only use link script when linking with GNU-like linker");
}
@@ -1890,7 +1930,7 @@ fn add_rpath_args(
out_filename: out_filename.to_path_buf(),
has_rpath: sess.target.has_rpath,
is_like_osx: sess.target.is_like_osx,
- linker_is_gnu: sess.target.linker_is_gnu,
+ linker_is_gnu: sess.target.linker_flavor.is_gnu(),
};
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
}
@@ -2134,7 +2174,7 @@ fn add_order_independent_options(
if sess.target.os == "fuchsia"
&& crate_type == CrateType::Executable
- && flavor != LinkerFlavor::Gcc
+ && !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
{
let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
"asan/"
@@ -2747,12 +2787,12 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let llvm_target = &sess.target.llvm_target;
if sess.target.vendor != "apple"
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos")
- || (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
+ || !matches!(flavor, LinkerFlavor::Darwin(..))
{
return;
}
- if os == "macos" && flavor != LinkerFlavor::Lld(LldFlavor::Ld64) {
+ if os == "macos" && !matches!(flavor, LinkerFlavor::Darwin(Cc::No, _)) {
return;
}
@@ -2786,10 +2826,10 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
};
match flavor {
- LinkerFlavor::Gcc => {
+ LinkerFlavor::Darwin(Cc::Yes, _) => {
cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
}
- LinkerFlavor::Lld(LldFlavor::Ld64) => {
+ LinkerFlavor::Darwin(Cc::No, _) => {
cmd.args(&["-syslibroot", &sdk_root]);
}
_ => unreachable!(),
@@ -2852,7 +2892,10 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let Some(ld_impl) = sess.opts.unstable_opts.gcc_ld {
- if let LinkerFlavor::Gcc = flavor {
+ if let LinkerFlavor::Gnu(Cc::Yes, _)
+ | LinkerFlavor::Darwin(Cc::Yes, _)
+ | LinkerFlavor::WasmLld(Cc::Yes) = flavor
+ {
match ld_impl {
LdImpl::Lld => {
// Implement the "self-contained" part of -Zgcc-ld
@@ -2867,7 +2910,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
// 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 {
+ if !flavor.is_gnu() {
// 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).
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index e505543b2..c49b19bdf 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -1,5 +1,6 @@
use super::command::Command;
use super::symbol_export;
+use crate::errors;
use rustc_span::symbol::sym;
use std::ffi::{OsStr, OsString};
@@ -16,7 +17,7 @@ use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, S
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
use rustc_session::Session;
-use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor};
+use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld};
use cc::windows_registry;
@@ -56,8 +57,13 @@ pub fn get_linker<'a>(
let mut cmd = match linker.to_str() {
Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker),
_ => match flavor {
- LinkerFlavor::Lld(f) => Command::lld(linker, f),
- LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => {
+ LinkerFlavor::Gnu(Cc::No, Lld::Yes)
+ | LinkerFlavor::Darwin(Cc::No, Lld::Yes)
+ | LinkerFlavor::WasmLld(Cc::No)
+ | LinkerFlavor::Msvc(Lld::Yes) => Command::lld(linker, flavor.lld_flavor()),
+ LinkerFlavor::Msvc(Lld::No)
+ if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() =>
+ {
Command::new(msvc_tool.as_ref().map_or(linker, |t| t.path()))
}
_ => Command::new(linker),
@@ -68,9 +74,7 @@ pub fn get_linker<'a>(
// To comply with the Windows App Certification Kit,
// MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
let t = &sess.target;
- if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link))
- && t.vendor == "uwp"
- {
+ if matches!(flavor, LinkerFlavor::Msvc(..)) && t.vendor == "uwp" {
if let Some(ref tool) = msvc_tool {
let original_path = tool.path();
if let Some(ref root_lib_path) = original_path.ancestors().nth(4) {
@@ -126,23 +130,22 @@ pub fn get_linker<'a>(
// to the linker args construction.
assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp");
match flavor {
- 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" => {
+ LinkerFlavor::Unix(Cc::No) 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::WasmLld(Cc::No) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
+ LinkerFlavor::Gnu(cc, _)
+ | LinkerFlavor::Darwin(cc, _)
+ | LinkerFlavor::WasmLld(cc)
+ | LinkerFlavor::Unix(cc) => Box::new(GccLinker {
+ cmd,
+ sess,
+ target_cpu,
+ hinted_static: false,
+ is_ld: cc == Cc::No,
+ is_gnu: flavor.is_gnu(),
+ }) as Box<dyn Linker>,
+ LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { 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>,
@@ -211,6 +214,7 @@ pub struct GccLinker<'a> {
hinted_static: bool, // Keeps track of the current hinting mode.
// Link as ld
is_ld: bool,
+ is_gnu: bool,
}
impl<'a> GccLinker<'a> {
@@ -359,7 +363,7 @@ impl<'a> Linker for GccLinker<'a> {
fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) {
match output_kind {
LinkOutputKind::DynamicNoPicExe => {
- if !self.is_ld && self.sess.target.linker_is_gnu {
+ if !self.is_ld && self.is_gnu {
self.cmd.arg("-no-pie");
}
}
@@ -373,7 +377,7 @@ impl<'a> Linker for GccLinker<'a> {
LinkOutputKind::StaticNoPicExe => {
// `-static` works for both gcc wrapper and ld.
self.cmd.arg("-static");
- if !self.is_ld && self.sess.target.linker_is_gnu {
+ if !self.is_ld && self.is_gnu {
self.cmd.arg("-no-pie");
}
}
@@ -431,26 +435,26 @@ impl<'a> Linker for GccLinker<'a> {
// FIXME(81490): ld64 doesn't support these flags but macOS 11
// has -needed-l{} / -needed_library {}
// but we have no way to detect that here.
- self.sess.warn("`as-needed` modifier not implemented yet for ld64");
- } else if self.sess.target.linker_is_gnu && !self.sess.target.is_like_windows {
+ self.sess.emit_warning(errors::Ld64UnimplementedModifier);
+ } else if self.is_gnu && !self.sess.target.is_like_windows {
self.linker_arg("--no-as-needed");
} else {
- self.sess.warn("`as-needed` modifier not supported for current linker");
+ self.sess.emit_warning(errors::LinkerUnsupportedModifier);
}
}
self.hint_dynamic();
- self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
+ self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },));
if !as_needed {
if self.sess.target.is_like_osx {
// See above FIXME comment
- } else if self.sess.target.linker_is_gnu && !self.sess.target.is_like_windows {
+ } else if self.is_gnu && !self.sess.target.is_like_windows {
self.linker_arg("--as-needed");
}
}
}
fn link_staticlib(&mut self, lib: &str, verbatim: bool) {
self.hint_static();
- self.cmd.arg(format!("-l{}{}", if verbatim { ":" } else { "" }, lib));
+ self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },));
}
fn link_rlib(&mut self, lib: &Path) {
self.hint_static();
@@ -489,7 +493,7 @@ impl<'a> Linker for GccLinker<'a> {
// FIXME(81490): ld64 as of macOS 11 supports the -needed_framework
// flag but we have no way to detect that here.
// self.cmd.arg("-needed_framework").arg(framework);
- self.sess.warn("`as-needed` modifier not implemented yet for ld64");
+ self.sess.emit_warning(errors::Ld64UnimplementedModifier);
}
self.cmd.arg("-framework").arg(framework);
}
@@ -504,11 +508,8 @@ impl<'a> Linker for GccLinker<'a> {
self.hint_static();
let target = &self.sess.target;
if !target.is_like_osx {
- self.linker_arg("--whole-archive").cmd.arg(format!(
- "-l{}{}",
- if verbatim { ":" } else { "" },
- lib
- ));
+ self.linker_arg("--whole-archive");
+ self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },));
self.linker_arg("--no-whole-archive");
} else {
// -force_load is the macOS equivalent of --whole-archive, but it
@@ -553,21 +554,19 @@ impl<'a> Linker for GccLinker<'a> {
// eliminate the metadata. If we're building an executable, however,
// --gc-sections drops the size of hello world from 1.8MB to 597K, a 67%
// reduction.
- } else if (self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm)
- && !keep_metadata
- {
+ } else if (self.is_gnu || self.sess.target.is_like_wasm) && !keep_metadata {
self.linker_arg("--gc-sections");
}
}
fn no_gc_sections(&mut self) {
- if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm {
+ if self.is_gnu || self.sess.target.is_like_wasm {
self.linker_arg("--no-gc-sections");
}
}
fn optimize(&mut self) {
- if !self.sess.target.linker_is_gnu && !self.sess.target.is_like_wasm {
+ if !self.is_gnu && !self.sess.target.is_like_wasm {
return;
}
@@ -581,7 +580,7 @@ impl<'a> Linker for GccLinker<'a> {
}
fn pgo_gen(&mut self) {
- if !self.sess.target.linker_is_gnu {
+ if !self.is_gnu {
return;
}
@@ -611,7 +610,13 @@ impl<'a> Linker for GccLinker<'a> {
match strip {
Strip::None => {}
Strip::Debuginfo => {
- self.linker_arg("--strip-debug");
+ // The illumos linker does not support --strip-debug although
+ // it does support --strip-all as a compatibility alias for -s.
+ // The --strip-debug case is handled by running an external
+ // `strip` utility as a separate step after linking.
+ if self.sess.target.os != "illumos" {
+ self.linker_arg("--strip-debug");
+ }
}
Strip::Symbols => {
self.linker_arg("--strip-all");
@@ -667,8 +672,8 @@ impl<'a> Linker for GccLinker<'a> {
writeln!(f, "_{}", sym)?;
}
};
- if let Err(e) = res {
- self.sess.fatal(&format!("failed to write lib.def file: {}", e));
+ if let Err(error) = res {
+ self.sess.emit_fatal(errors::LibDefWriteFailure { error });
}
} else if is_windows {
let res: io::Result<()> = try {
@@ -682,8 +687,8 @@ impl<'a> Linker for GccLinker<'a> {
writeln!(f, " {}", symbol)?;
}
};
- if let Err(e) = res {
- self.sess.fatal(&format!("failed to write list.def file: {}", e));
+ if let Err(error) = res {
+ self.sess.emit_fatal(errors::LibDefWriteFailure { error });
}
} else {
// Write an LD version script
@@ -699,8 +704,8 @@ impl<'a> Linker for GccLinker<'a> {
}
writeln!(f, "\n local:\n *;\n}};")?;
};
- if let Err(e) = res {
- self.sess.fatal(&format!("failed to write version script: {}", e));
+ if let Err(error) = res {
+ self.sess.emit_fatal(errors::VersionScriptWriteFailure { error });
}
}
@@ -752,13 +757,13 @@ impl<'a> Linker for GccLinker<'a> {
fn add_no_exec(&mut self) {
if self.sess.target.is_like_windows {
self.linker_arg("--nxcompat");
- } else if self.sess.target.linker_is_gnu {
+ } else if self.is_gnu {
self.linker_arg("-znoexecstack");
}
}
fn add_as_needed(&mut self) {
- if self.sess.target.linker_is_gnu && !self.sess.target.is_like_windows {
+ if self.is_gnu && !self.sess.target.is_like_windows {
self.linker_arg("--as-needed");
} else if self.sess.target.is_like_solaris {
// -z ignore is the Solaris equivalent to the GNU ld --as-needed option
@@ -917,9 +922,8 @@ impl<'a> Linker for MsvcLinker<'a> {
self.cmd.arg(arg);
}
}
- Err(err) => {
- self.sess
- .warn(&format!("error enumerating natvis directory: {}", err));
+ Err(error) => {
+ self.sess.emit_warning(errors::NoNatvisDirectory { error });
}
}
}
@@ -973,8 +977,8 @@ impl<'a> Linker for MsvcLinker<'a> {
writeln!(f, " {}", symbol)?;
}
};
- if let Err(e) = res {
- self.sess.fatal(&format!("failed to write lib.def file: {}", e));
+ if let Err(error) = res {
+ self.sess.emit_fatal(errors::LibDefWriteFailure { error });
}
let mut arg = OsString::from("/DEF:");
arg.push(path);
@@ -1174,22 +1178,19 @@ impl<'a> WasmLd<'a> {
// sharing memory and instantiating the module multiple times. As a
// result if it were exported then we'd just have no sharing.
//
- // * `--export=__wasm_init_memory` - when using `--passive-segments` the
- // linker will synthesize this function, and so we need to make sure
- // that our usage of `--export` below won't accidentally cause this
- // function to get deleted.
- //
- // * `--export=*tls*` - when `#[thread_local]` symbols are used these
- // symbols are how the TLS segments are initialized and configured.
+ // On wasm32-unknown-unknown, we also export symbols for glue code to use:
+ // * `--export=*tls*` - when `#[thread_local]` symbols are used these
+ // symbols are how the TLS segments are initialized and configured.
if sess.target_features.contains(&sym::atomics) {
cmd.arg("--shared-memory");
cmd.arg("--max-memory=1073741824");
cmd.arg("--import-memory");
- cmd.arg("--export=__wasm_init_memory");
- cmd.arg("--export=__wasm_init_tls");
- cmd.arg("--export=__tls_size");
- cmd.arg("--export=__tls_align");
- cmd.arg("--export=__tls_base");
+ if sess.target.os == "unknown" {
+ cmd.arg("--export=__wasm_init_tls");
+ cmd.arg("--export=__tls_size");
+ cmd.arg("--export=__tls_align");
+ cmd.arg("--export=__tls_base");
+ }
}
WasmLd { cmd, sess }
}
@@ -1314,10 +1315,12 @@ impl<'a> Linker for WasmLd<'a> {
// LLD will hide these otherwise-internal symbols since it only exports
// symbols explicitly passed via the `--export` flags above and hides all
- // others. Various bits and pieces of tooling use this, so be sure these
- // symbols make their way out of the linker as well.
- self.cmd.arg("--export=__heap_base");
- self.cmd.arg("--export=__data_end");
+ // others. Various bits and pieces of wasm32-unknown-unknown tooling use
+ // this, so be sure these symbols make their way out of the linker as well.
+ if self.sess.target.os == "unknown" {
+ self.cmd.arg("--export=__heap_base");
+ self.cmd.arg("--export=__data_end");
+ }
}
fn subsystem(&mut self, _subsystem: &str) {}
@@ -1438,7 +1441,7 @@ impl<'a> Linker for L4Bender<'a> {
fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) {
// ToDo, not implemented, copy from GCC
- self.sess.warn("exporting symbols not implemented yet for L4Bender");
+ self.sess.emit_warning(errors::L4BenderExportingSymbolsUnimplemented);
return;
}
@@ -1730,8 +1733,8 @@ impl<'a> Linker for BpfLinker<'a> {
writeln!(f, "{}", sym)?;
}
};
- if let Err(e) = res {
- self.sess.fatal(&format!("failed to write symbols file: {}", e));
+ if let Err(error) = res {
+ self.sess.emit_fatal(errors::SymbolFileWriteFailure { error });
} else {
self.cmd.arg("--export-symbols").arg(&path);
}
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 8d7e2c5cf..c2ecc4160 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -13,7 +13,7 @@ use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::Instance;
use rustc_middle::ty::{self, SymbolName, TyCtxt};
-use rustc_session::config::CrateType;
+use rustc_session::config::{CrateType, OomStrategy};
use rustc_target::spec::SanitizerSet;
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
@@ -76,7 +76,7 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, cnum: CrateNum) -> DefIdMap<
// let it through if it's included statically.
match tcx.hir().get_by_def_id(def_id) {
Node::ForeignItem(..) => {
- tcx.is_statically_included_foreign_item(def_id).then_some(def_id)
+ tcx.native_library(def_id).map_or(false, |library| library.kind.is_statically_included()).then_some(def_id)
}
// Only consider nodes that actually have exported symbols.
@@ -206,6 +206,15 @@ fn exported_symbols_provider_local<'tcx>(
},
));
}
+
+ symbols.push((
+ ExportedSymbol::NoDefId(SymbolName::new(tcx, OomStrategy::SYMBOL)),
+ SymbolExportInfo {
+ level: SymbolExportLevel::Rust,
+ kind: SymbolExportKind::Text,
+ used: false,
+ },
+ ));
}
if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() {
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 68f3b19b7..d0ac016b0 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -2,11 +2,11 @@ use super::link::{self, ensure_removed};
use super::lto::{self, SerializedModule};
use super::symbol_export::symbol_name_for_instance_in_crate;
+use crate::errors;
+use crate::traits::*;
use crate::{
CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
};
-
-use crate::traits::*;
use jobserver::{Acquired, Client};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::memmap::Mmap;
@@ -15,7 +15,10 @@ 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::{translation::Translate, DiagnosticId, FatalError, Handler, Level};
+use rustc_errors::{
+ translation::{to_fluent_args, Translate},
+ DiagnosticId, FatalError, Handler, Level,
+};
use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_incremental::{
@@ -113,7 +116,6 @@ pub struct ModuleConfig {
pub vectorize_slp: bool,
pub merge_functions: bool,
pub inline_threshold: Option<u32>,
- pub new_llvm_pass_manager: Option<bool>,
pub emit_lifetime_markers: bool,
pub llvm_plugins: Vec<String>,
}
@@ -265,7 +267,6 @@ impl ModuleConfig {
},
inline_threshold: sess.opts.cg.inline_threshold,
- new_llvm_pass_manager: sess.opts.unstable_opts.new_llvm_pass_manager,
emit_lifetime_markers: sess.emit_lifetime_markers(),
llvm_plugins: if_regular!(sess.opts.unstable_opts.llvm_plugins.clone(), vec![]),
}
@@ -532,7 +533,7 @@ fn produce_final_output_artifacts(
// Produce final compile outputs.
let copy_gracefully = |from: &Path, to: &Path| {
if let Err(e) = fs::copy(from, to) {
- sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e));
+ sess.emit_err(errors::CopyPath::new(from, to, e));
}
};
@@ -548,7 +549,7 @@ fn produce_final_output_artifacts(
ensure_removed(sess.diagnostic(), &path);
}
} else {
- let ext = crate_output
+ let extension = crate_output
.temp_path(output_type, None)
.extension()
.unwrap()
@@ -559,19 +560,11 @@ fn produce_final_output_artifacts(
if crate_output.outputs.contains_key(&output_type) {
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
// no good solution for this case, so warn the user.
- sess.warn(&format!(
- "ignoring emit path because multiple .{} files \
- were produced",
- ext
- ));
+ sess.emit_warning(errors::IgnoringEmitPath { extension });
} else if crate_output.single_output_file.is_some() {
// 3) Multiple codegen units, with `-o some_name`. We have
// no good solution for this case, so warn the user.
- sess.warn(&format!(
- "ignoring -o because multiple .{} files \
- were produced",
- ext
- ));
+ sess.emit_warning(errors::IgnoringOutput { extension });
} else {
// 4) Multiple codegen units, but no explicit name. We
// just leave the `foo.0.x` files in place.
@@ -882,14 +875,12 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
);
match link_or_copy(&source_file, &output_path) {
Ok(_) => Some(output_path),
- Err(err) => {
- let diag_handler = cgcx.create_diag_handler();
- diag_handler.err(&format!(
- "unable to copy {} to {}: {}",
- source_file.display(),
- output_path.display(),
- err
- ));
+ Err(error) => {
+ cgcx.create_diag_handler().emit_err(errors::CopyPathBuf {
+ source_file,
+ output_path,
+ error,
+ });
None
}
}
@@ -1008,6 +999,14 @@ fn start_executing_work<B: ExtraBackendMethods>(
let coordinator_send = tx_to_llvm_workers;
let sess = tcx.sess;
+ let mut each_linked_rlib_for_lto = Vec::new();
+ drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| {
+ if link::ignored_for_lto(sess, crate_info, cnum) {
+ return;
+ }
+ each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
+ }));
+
// Compute the set of symbols we need to retain when doing LTO (if we need to)
let exported_symbols = {
let mut exported_symbols = FxHashMap::default();
@@ -1029,7 +1028,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
}
Lto::Fat | Lto::Thin => {
exported_symbols.insert(LOCAL_CRATE, copy_symbols(LOCAL_CRATE));
- for &cnum in tcx.crates(()).iter() {
+ for &(cnum, ref _path) in &each_linked_rlib_for_lto {
exported_symbols.insert(cnum, copy_symbols(cnum));
}
Some(Arc::new(exported_symbols))
@@ -1049,14 +1048,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
})
.expect("failed to spawn helper thread");
- let mut each_linked_rlib_for_lto = Vec::new();
- drop(link::each_linked_rlib(crate_info, &mut |cnum, path| {
- if link::ignored_for_lto(sess, crate_info, cnum) {
- return;
- }
- each_linked_rlib_for_lto.push((cnum, path.to_path_buf()));
- }));
-
let ol =
if tcx.sess.opts.unstable_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() {
// If we know that we won’t be doing codegen, create target machines without optimisation.
@@ -1639,7 +1630,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
llvm_start_time: &mut Option<VerboseTimingGuard<'a>>,
) {
if config.time_module && llvm_start_time.is_none() {
- *llvm_start_time = Some(prof.extra_verbose_generic_activity("LLVM_passes", "crate"));
+ *llvm_start_time = Some(prof.verbose_generic_activity("LLVM_passes"));
}
}
}
@@ -1752,7 +1743,7 @@ impl Translate for SharedEmitter {
impl Emitter for SharedEmitter {
fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
- let fluent_args = self.to_fluent_args(diag.args());
+ let fluent_args = to_fluent_args(diag.args());
drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
msg: self.translate_messages(&diag.message, &fluent_args).to_string(),
code: diag.code.clone(),
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index b98ff4957..84b89cd71 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -39,7 +39,7 @@ use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::Symbol;
use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType};
-use rustc_target::abi::{Align, VariantIdx};
+use rustc_target::abi::{Align, Size, VariantIdx};
use std::collections::BTreeSet;
use std::convert::TryFrom;
@@ -151,7 +151,12 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(&ty::Array(_, len), &ty::Slice(_)) => {
cx.const_usize(len.eval_usize(cx.tcx(), ty::ParamEnv::reveal_all()))
}
- (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
+ (
+ &ty::Dynamic(ref data_a, _, src_dyn_kind),
+ &ty::Dynamic(ref data_b, _, target_dyn_kind),
+ ) => {
+ assert_eq!(src_dyn_kind, target_dyn_kind);
+
let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() {
@@ -167,11 +172,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
if let Some(entry_idx) = vptr_entry_idx {
let ptr_ty = cx.type_i8p();
let ptr_align = cx.tcx().data_layout.pointer_align.abi;
- let vtable_ptr_ty = cx.scalar_pair_element_backend_type(
- cx.layout_of(cx.tcx().mk_mut_ptr(target)),
- 1,
- true,
- );
+ let vtable_ptr_ty = vtable_ptr_ty(cx, target, target_dyn_kind);
let llvtable = bx.pointercast(old_info, bx.type_ptr_to(ptr_ty));
let gep = bx.inbounds_gep(
ptr_ty,
@@ -187,18 +188,32 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
old_info
}
}
- (_, &ty::Dynamic(ref data, ..)) => {
- let vtable_ptr_ty = cx.scalar_pair_element_backend_type(
- cx.layout_of(cx.tcx().mk_mut_ptr(target)),
- 1,
- true,
- );
+ (_, &ty::Dynamic(ref data, _, target_dyn_kind)) => {
+ let vtable_ptr_ty = vtable_ptr_ty(cx, target, target_dyn_kind);
cx.const_ptrcast(meth::get_vtable(cx, source, data.principal()), vtable_ptr_ty)
}
_ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
}
}
+// Returns the vtable pointer type of a `dyn` or `dyn*` type
+fn vtable_ptr_ty<'tcx, Cx: CodegenMethods<'tcx>>(
+ cx: &Cx,
+ target: Ty<'tcx>,
+ kind: ty::DynKind,
+) -> <Cx as BackendTypes>::Type {
+ cx.scalar_pair_element_backend_type(
+ cx.layout_of(match kind {
+ // vtable is the second field of `*mut dyn Trait`
+ ty::Dyn => cx.tcx().mk_mut_ptr(target),
+ // vtable is the second field of `dyn* Trait`
+ ty::DynStar => target,
+ }),
+ 1,
+ true,
+ )
+}
+
/// Coerces `src` to `dst_ty`. `src_ty` must be a pointer.
pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
@@ -248,6 +263,29 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}
+/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type.
+pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+ bx: &mut Bx,
+ src: Bx::Value,
+ src_ty_and_layout: TyAndLayout<'tcx>,
+ dst_ty: Ty<'tcx>,
+ old_info: Option<Bx::Value>,
+) -> (Bx::Value, Bx::Value) {
+ debug!("cast_to_dyn_star: {:?} => {:?}", src_ty_and_layout.ty, dst_ty);
+ assert!(
+ matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
+ "destination type must be a dyn*"
+ );
+ // FIXME(dyn-star): this is probably not the best way to check if this is
+ // a pointer, and really we should ensure that the value is a suitable
+ // pointer earlier in the compilation process.
+ let src = match src_ty_and_layout.pointee_info_at(bx.cx(), Size::ZERO) {
+ Some(_) => bx.ptrtoint(src, bx.cx().type_isize()),
+ None => bx.bitcast(src, bx.type_isize()),
+ };
+ (src, unsized_info(bx, src_ty_and_layout.ty, dst_ty, old_info))
+}
+
/// Coerces `src`, which is a reference to a value of type `src_ty`,
/// to a value of type `dst_ty`, and stores the result in `dst`.
pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
@@ -299,40 +337,26 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub fn cast_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
- op: hir::BinOpKind,
- lhs: Bx::Value,
- rhs: Bx::Value,
-) -> Bx::Value {
- cast_shift_rhs(bx, op, lhs, rhs)
-}
-
-fn cast_shift_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
- bx: &mut Bx,
- op: hir::BinOpKind,
lhs: Bx::Value,
rhs: Bx::Value,
) -> Bx::Value {
// Shifts may have any size int on the rhs
- if op.is_shift() {
- let mut rhs_llty = bx.cx().val_ty(rhs);
- let mut lhs_llty = bx.cx().val_ty(lhs);
- if bx.cx().type_kind(rhs_llty) == TypeKind::Vector {
- rhs_llty = bx.cx().element_type(rhs_llty)
- }
- if bx.cx().type_kind(lhs_llty) == TypeKind::Vector {
- lhs_llty = bx.cx().element_type(lhs_llty)
- }
- let rhs_sz = bx.cx().int_width(rhs_llty);
- let lhs_sz = bx.cx().int_width(lhs_llty);
- if lhs_sz < rhs_sz {
- bx.trunc(rhs, lhs_llty)
- } else if lhs_sz > rhs_sz {
- // FIXME (#1877: If in the future shifting by negative
- // values is no longer undefined then this is wrong.
- bx.zext(rhs, lhs_llty)
- } else {
- rhs
- }
+ let mut rhs_llty = bx.cx().val_ty(rhs);
+ let mut lhs_llty = bx.cx().val_ty(lhs);
+ if bx.cx().type_kind(rhs_llty) == TypeKind::Vector {
+ rhs_llty = bx.cx().element_type(rhs_llty)
+ }
+ if bx.cx().type_kind(lhs_llty) == TypeKind::Vector {
+ lhs_llty = bx.cx().element_type(lhs_llty)
+ }
+ let rhs_sz = bx.cx().int_width(rhs_llty);
+ let lhs_sz = bx.cx().int_width(lhs_llty);
+ if lhs_sz < rhs_sz {
+ bx.trunc(rhs, lhs_llty)
+ } else if lhs_sz > rhs_sz {
+ // FIXME (#1877: If in the future shifting by negative
+ // values is no longer undefined then this is wrong.
+ bx.zext(rhs, lhs_llty)
} else {
rhs
}
@@ -475,7 +499,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(rust_main, start_ty, vec![arg_argc, arg_argv])
};
- let result = bx.call(start_ty, start_fn, &args, None);
+ let result = bx.call(start_ty, None, start_fn, &args, None);
let cast = bx.intcast(result, cx.type_int(), true);
bx.ret(cast);
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index 8ca1a6084..71f9179d0 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -1,7 +1,6 @@
#![allow(non_camel_case_types)]
use rustc_errors::struct_span_err;
-use rustc_hir as hir;
use rustc_hir::LangItem;
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
@@ -140,7 +139,7 @@ pub fn build_unchecked_lshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
lhs: Bx::Value,
rhs: Bx::Value,
) -> Bx::Value {
- let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shl, lhs, rhs);
+ let rhs = base::cast_shift_expr_rhs(bx, lhs, rhs);
// #1877, #10183: Ensure that input is always valid
let rhs = shift_mask_rhs(bx, rhs);
bx.shl(lhs, rhs)
@@ -152,7 +151,7 @@ pub fn build_unchecked_rshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
lhs: Bx::Value,
rhs: Bx::Value,
) -> Bx::Value {
- let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
+ let rhs = base::cast_shift_expr_rhs(bx, lhs, rhs);
// #1877, #10183: Ensure that input is always valid
let rhs = shift_mask_rhs(bx, rhs);
let is_signed = lhs_t.is_signed();
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 135ed680d..e05646e1e 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -666,10 +666,8 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S
hcx.while_hashing_spans(false, |hcx| {
ct.to_valtree().hash_stable(hcx, &mut hasher)
});
- // Note: Don't use `StableHashResult` impl of `u64` here directly, since that
- // would lead to endianness problems.
- let hash: u128 = hasher.finish();
- (hash.to_le() as u64).to_le()
+ let hash: u64 = hasher.finish();
+ hash
});
if cpp_like_debuginfo(tcx) {
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
new file mode 100644
index 000000000..ebb531f1c
--- /dev/null
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -0,0 +1,356 @@
+//! Errors emitted by codegen_ssa
+
+use crate::back::command::Command;
+use rustc_errors::{
+ fluent, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
+ IntoDiagnosticArg,
+};
+use rustc_macros::Diagnostic;
+use rustc_span::{Span, Symbol};
+use std::borrow::Cow;
+use std::io::Error;
+use std::path::{Path, PathBuf};
+use std::process::ExitStatus;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_lib_def_write_failure)]
+pub struct LibDefWriteFailure {
+ pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_version_script_write_failure)]
+pub struct VersionScriptWriteFailure {
+ pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_symbol_file_write_failure)]
+pub struct SymbolFileWriteFailure {
+ pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_ld64_unimplemented_modifier)]
+pub struct Ld64UnimplementedModifier;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_linker_unsupported_modifier)]
+pub struct LinkerUnsupportedModifier;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_L4Bender_exporting_symbols_unimplemented)]
+pub struct L4BenderExportingSymbolsUnimplemented;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_no_natvis_directory)]
+pub struct NoNatvisDirectory {
+ pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_copy_path_buf)]
+pub struct CopyPathBuf {
+ pub source_file: PathBuf,
+ pub output_path: PathBuf,
+ pub error: Error,
+}
+
+// Reports Paths using `Debug` implementation rather than Path's `Display` implementation.
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_copy_path)]
+pub struct CopyPath<'a> {
+ from: DebugArgPath<'a>,
+ to: DebugArgPath<'a>,
+ error: Error,
+}
+
+impl<'a> CopyPath<'a> {
+ pub fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> {
+ CopyPath { from: DebugArgPath(from), to: DebugArgPath(to), error }
+ }
+}
+
+struct DebugArgPath<'a>(pub &'a Path);
+
+impl IntoDiagnosticArg for DebugArgPath<'_> {
+ fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+ DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0)))
+ }
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_ignoring_emit_path)]
+pub struct IgnoringEmitPath {
+ pub extension: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_ignoring_output)]
+pub struct IgnoringOutput {
+ pub extension: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_create_temp_dir)]
+pub struct CreateTempDir {
+ pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_incompatible_linking_modifiers)]
+pub struct IncompatibleLinkingModifiers;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_add_native_library)]
+pub struct AddNativeLibrary {
+ pub library_path: PathBuf,
+ pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_multiple_external_func_decl)]
+pub struct MultipleExternalFuncDecl<'a> {
+ #[primary_span]
+ pub span: Span,
+ pub function: Symbol,
+ pub library_name: &'a str,
+}
+
+#[derive(Diagnostic)]
+pub enum LinkRlibError {
+ #[diag(codegen_ssa_rlib_missing_format)]
+ MissingFormat,
+
+ #[diag(codegen_ssa_rlib_only_rmeta_found)]
+ OnlyRmetaFound { crate_name: Symbol },
+
+ #[diag(codegen_ssa_rlib_not_found)]
+ NotFound { crate_name: Symbol },
+
+ #[diag(codegen_ssa_rlib_incompatible_dependency_formats)]
+ IncompatibleDependencyFormats { ty1: String, ty2: String, list1: String, list2: String },
+}
+
+pub struct ThorinErrorWrapper(pub thorin::Error);
+
+impl IntoDiagnostic<'_> for ThorinErrorWrapper {
+ fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag;
+ match self.0 {
+ thorin::Error::ReadInput(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_read_input_failure);
+ diag
+ }
+ thorin::Error::ParseFileKind(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_input_file_kind);
+ diag
+ }
+ thorin::Error::ParseObjectFile(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_input_object_file);
+ diag
+ }
+ thorin::Error::ParseArchiveFile(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_input_archive_file);
+ diag
+ }
+ thorin::Error::ParseArchiveMember(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_archive_member);
+ diag
+ }
+ thorin::Error::InvalidInputKind => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_invalid_input_kind);
+ diag
+ }
+ thorin::Error::DecompressData(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_decompress_data);
+ diag
+ }
+ thorin::Error::NamelessSection(_, offset) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_section_without_name);
+ diag.set_arg("offset", format!("0x{:08x}", offset));
+ diag
+ }
+ thorin::Error::RelocationWithInvalidSymbol(section, offset) => {
+ diag =
+ handler.struct_err(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol);
+ diag.set_arg("section", section);
+ diag.set_arg("offset", format!("0x{:08x}", offset));
+ diag
+ }
+ thorin::Error::MultipleRelocations(section, offset) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_relocations);
+ diag.set_arg("section", section);
+ diag.set_arg("offset", format!("0x{:08x}", offset));
+ diag
+ }
+ thorin::Error::UnsupportedRelocation(section, offset) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_unsupported_relocation);
+ diag.set_arg("section", section);
+ diag.set_arg("offset", format!("0x{:08x}", offset));
+ diag
+ }
+ thorin::Error::MissingDwoName(id) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_dwo_name);
+ diag.set_arg("id", format!("0x{:08x}", id));
+ diag
+ }
+ thorin::Error::NoCompilationUnits => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_no_compilation_units);
+ diag
+ }
+ thorin::Error::NoDie => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_no_die);
+ diag
+ }
+ thorin::Error::TopLevelDieNotUnit => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_top_level_die_not_unit);
+ diag
+ }
+ thorin::Error::MissingRequiredSection(section) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_required_section);
+ diag.set_arg("section", section);
+ diag
+ }
+ thorin::Error::ParseUnitAbbreviations(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit_abbreviations);
+ diag
+ }
+ thorin::Error::ParseUnitAttribute(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit_attribute);
+ diag
+ }
+ thorin::Error::ParseUnitHeader(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit_header);
+ diag
+ }
+ thorin::Error::ParseUnit(_) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit);
+ diag
+ }
+ thorin::Error::IncompatibleIndexVersion(section, format, actual) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_incompatible_index_version);
+ diag.set_arg("section", section);
+ diag.set_arg("actual", actual);
+ diag.set_arg("format", format);
+ diag
+ }
+ thorin::Error::OffsetAtIndex(_, index) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_offset_at_index);
+ diag.set_arg("index", index);
+ diag
+ }
+ thorin::Error::StrAtOffset(_, offset) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_str_at_offset);
+ diag.set_arg("offset", format!("0x{:08x}", offset));
+ diag
+ }
+ thorin::Error::ParseIndex(_, section) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_index);
+ diag.set_arg("section", section);
+ diag
+ }
+ thorin::Error::UnitNotInIndex(unit) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_unit_not_in_index);
+ diag.set_arg("unit", format!("0x{:08x}", unit));
+ diag
+ }
+ thorin::Error::RowNotInIndex(_, row) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_row_not_in_index);
+ diag.set_arg("row", row);
+ diag
+ }
+ thorin::Error::SectionNotInRow => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_section_not_in_row);
+ diag
+ }
+ thorin::Error::EmptyUnit(unit) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_empty_unit);
+ diag.set_arg("unit", format!("0x{:08x}", unit));
+ diag
+ }
+ thorin::Error::MultipleDebugInfoSection => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_debug_info_section);
+ diag
+ }
+ thorin::Error::MultipleDebugTypesSection => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_debug_types_section);
+ diag
+ }
+ thorin::Error::NotSplitUnit => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_not_split_unit);
+ diag
+ }
+ thorin::Error::DuplicateUnit(unit) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_duplicate_unit);
+ diag.set_arg("unit", format!("0x{:08x}", unit));
+ diag
+ }
+ thorin::Error::MissingReferencedUnit(unit) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_referenced_unit);
+ diag.set_arg("unit", format!("0x{:08x}", unit));
+ diag
+ }
+ thorin::Error::NoOutputObjectCreated => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_not_output_object_created);
+ diag
+ }
+ thorin::Error::MixedInputEncodings => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_mixed_input_encodings);
+ diag
+ }
+ thorin::Error::Io(e) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_io);
+ diag.set_arg("error", format!("{e}"));
+ diag
+ }
+ thorin::Error::ObjectRead(e) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_object_read);
+ diag.set_arg("error", format!("{e}"));
+ diag
+ }
+ thorin::Error::ObjectWrite(e) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_object_write);
+ diag.set_arg("error", format!("{e}"));
+ diag
+ }
+ thorin::Error::GimliRead(e) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_gimli_read);
+ diag.set_arg("error", format!("{e}"));
+ diag
+ }
+ thorin::Error::GimliWrite(e) => {
+ diag = handler.struct_err(fluent::codegen_ssa_thorin_gimli_write);
+ diag.set_arg("error", format!("{e}"));
+ diag
+ }
+ _ => unimplemented!("Untranslated thorin error"),
+ }
+ }
+}
+
+pub struct LinkingFailed<'a> {
+ pub linker_path: &'a PathBuf,
+ pub exit_status: ExitStatus,
+ pub command: &'a Command,
+ pub escaped_output: &'a str,
+}
+
+impl IntoDiagnostic<'_> for LinkingFailed<'_> {
+ fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = handler.struct_err(fluent::codegen_ssa_linking_failed);
+ diag.set_arg("linker_path", format!("{}", self.linker_path.display()));
+ diag.set_arg("exit_status", format!("{}", self.exit_status));
+
+ diag.note(format!("{:?}", self.command)).note(self.escaped_output);
+
+ // Trying to match an error from OS linkers
+ // which by now we have no way to translate.
+ if self.escaped_output.contains("undefined reference to") {
+ diag.note(fluent::codegen_ssa_extern_funcs_not_found)
+ .note(fluent::codegen_ssa_specify_libraries_to_link)
+ .note(fluent::codegen_ssa_use_cargo_directive);
+ }
+ diag
+ }
+}
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index e736b2aba..ceebe4d41 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -1,12 +1,12 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(box_patterns)]
#![feature(try_blocks)]
-#![cfg_attr(bootstrap, feature(let_else))]
#![feature(once_cell)]
#![feature(associated_type_bounds)]
#![feature(strict_provenance)]
#![feature(int_roundings)]
#![feature(if_let_guard)]
+#![feature(never_type)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]
@@ -44,6 +44,7 @@ pub mod base;
pub mod common;
pub mod coverageinfo;
pub mod debuginfo;
+pub mod errors;
pub mod glue;
pub mod meth;
pub mod mir;
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index a6b226ef7..29b7c9b0a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -63,7 +63,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
}
}
- fn lltarget<Bx: BuilderMethods<'a, 'tcx>>(
+ /// Get a basic block (creating it if necessary), possibly with a landing
+ /// pad next to it.
+ fn llbb_with_landing_pad<Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
target: mir::BasicBlock,
@@ -73,32 +75,36 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
let target_funclet = fx.cleanup_kinds[target].funclet_bb(target);
match (self.funclet_bb, target_funclet) {
(None, None) => (lltarget, false),
- (Some(f), Some(t_f)) if f == t_f || !base::wants_msvc_seh(fx.cx.tcx().sess) => {
- (lltarget, false)
- }
// jump *into* cleanup - need a landing pad if GNU, cleanup pad if MSVC
(None, Some(_)) => (fx.landing_pad_for(target), false),
(Some(_), None) => span_bug!(span, "{:?} - jump out of cleanup?", self.terminator),
- (Some(_), Some(_)) => (fx.landing_pad_for(target), true),
+ (Some(f), Some(t_f)) => {
+ if f == t_f || !base::wants_msvc_seh(fx.cx.tcx().sess) {
+ (lltarget, false)
+ } else {
+ (fx.landing_pad_for(target), true)
+ }
+ }
}
}
- /// Create a basic block.
- fn llblock<Bx: BuilderMethods<'a, 'tcx>>(
+ /// Get a basic block (creating it if necessary), possibly with cleanup
+ /// stuff in it or next to it.
+ fn llbb_with_cleanup<Bx: BuilderMethods<'a, 'tcx>>(
&self,
fx: &mut FunctionCx<'a, 'tcx, Bx>,
target: mir::BasicBlock,
) -> Bx::BasicBlock {
- let (lltarget, is_cleanupret) = self.lltarget(fx, target);
+ let (lltarget, is_cleanupret) = self.llbb_with_landing_pad(fx, target);
if is_cleanupret {
// MSVC cross-funclet jump - need a trampoline
-
- debug!("llblock: creating cleanup trampoline for {:?}", target);
+ debug_assert!(base::wants_msvc_seh(fx.cx.tcx().sess));
+ debug!("llbb_with_cleanup: creating cleanup trampoline for {:?}", target);
let name = &format!("{:?}_cleanup_trampoline_{:?}", self.bb, target);
- let trampoline = Bx::append_block(fx.cx, fx.llfn, name);
- let mut trampoline_bx = Bx::build(fx.cx, trampoline);
+ let trampoline_llbb = Bx::append_block(fx.cx, fx.llfn, name);
+ let mut trampoline_bx = Bx::build(fx.cx, trampoline_llbb);
trampoline_bx.cleanup_ret(self.funclet(fx).unwrap(), Some(lltarget));
- trampoline
+ trampoline_llbb
} else {
lltarget
}
@@ -110,10 +116,11 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
bx: &mut Bx,
target: mir::BasicBlock,
) {
- let (lltarget, is_cleanupret) = self.lltarget(fx, target);
+ let (lltarget, is_cleanupret) = self.llbb_with_landing_pad(fx, target);
if is_cleanupret {
- // micro-optimization: generate a `ret` rather than a jump
+ // MSVC micro-optimization: generate a `ret` rather than a jump
// to a trampoline.
+ debug_assert!(base::wants_msvc_seh(fx.cx.tcx().sess));
bx.cleanup_ret(self.funclet(fx).unwrap(), Some(lltarget));
} else {
bx.br(lltarget);
@@ -138,7 +145,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
let unwind_block = if let Some(cleanup) = cleanup.filter(|_| fn_abi.can_unwind) {
- Some(self.llblock(fx, cleanup))
+ Some(self.llbb_with_cleanup(fx, cleanup))
} else if fx.mir[self.bb].is_cleanup
&& fn_abi.can_unwind
&& !base::wants_msvc_seh(fx.cx.tcx().sess)
@@ -162,9 +169,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
} else {
fx.unreachable_block()
};
- let invokeret =
- bx.invoke(fn_ty, fn_ptr, &llargs, ret_llbb, unwind_block, self.funclet(fx));
- bx.apply_attrs_callsite(&fn_abi, invokeret);
+ let invokeret = bx.invoke(
+ fn_ty,
+ Some(&fn_abi),
+ fn_ptr,
+ &llargs,
+ ret_llbb,
+ unwind_block,
+ self.funclet(fx),
+ );
if fx.mir[self.bb].is_cleanup {
bx.do_not_inline(invokeret);
}
@@ -178,8 +191,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
fx.store_return(bx, ret_dest, &fn_abi.ret, invokeret);
}
} else {
- let llret = bx.call(fn_ty, fn_ptr, &llargs, self.funclet(fx));
- bx.apply_attrs_callsite(&fn_abi, llret);
+ let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx));
if fx.mir[self.bb].is_cleanup {
// Cleanup is always the cold path. Don't inline
// drop glue. Also, when there is a deeply-nested
@@ -226,7 +238,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
options,
line_spans,
instance,
- Some((ret_llbb, self.llblock(fx, cleanup), self.funclet(fx))),
+ Some((ret_llbb, self.llbb_with_cleanup(fx, cleanup), self.funclet(fx))),
);
} else {
bx.codegen_inline_asm(template, &operands, options, line_spans, instance, None);
@@ -276,8 +288,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if target_iter.len() == 1 {
// If there are two targets (one conditional, one fallback), emit br instead of switch
let (test_value, target) = target_iter.next().unwrap();
- let lltrue = helper.llblock(self, target);
- let llfalse = helper.llblock(self, targets.otherwise());
+ let lltrue = helper.llbb_with_cleanup(self, target);
+ let llfalse = helper.llbb_with_cleanup(self, targets.otherwise());
if switch_ty == bx.tcx().types.bool {
// Don't generate trivial icmps when switching on bool
match test_value {
@@ -294,8 +306,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} else {
bx.switch(
discr.immediate(),
- helper.llblock(self, targets.otherwise()),
- target_iter.map(|(value, target)| (value, helper.llblock(self, target))),
+ helper.llbb_with_cleanup(self, targets.otherwise()),
+ target_iter.map(|(value, target)| (value, helper.llbb_with_cleanup(self, target))),
);
}
}
@@ -525,7 +537,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let cond = bx.expect(cond, expected);
// Create the failure block and the conditional branch to it.
- let lltarget = helper.llblock(self, target);
+ let lltarget = helper.llbb_with_cleanup(self, target);
let panic_block = bx.append_sibling_block("panic");
if expected {
bx.cond_br(cond, lltarget, panic_block);
@@ -1454,20 +1466,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// bar();
// }
Some(&mir::TerminatorKind::Abort) => {
- let cs_bb =
+ let cs_llbb =
Bx::append_block(self.cx, self.llfn, &format!("cs_funclet{:?}", bb));
- let cp_bb =
+ let cp_llbb =
Bx::append_block(self.cx, self.llfn, &format!("cp_funclet{:?}", bb));
- ret_llbb = cs_bb;
+ ret_llbb = cs_llbb;
- let mut cs_bx = Bx::build(self.cx, cs_bb);
- let cs = cs_bx.catch_switch(None, None, &[cp_bb]);
+ let mut cs_bx = Bx::build(self.cx, cs_llbb);
+ let cs = cs_bx.catch_switch(None, None, &[cp_llbb]);
// The "null" here is actually a RTTI type descriptor for the
// C++ personality function, but `catch (...)` has no type so
// it's null. The 64 here is actually a bitfield which
// represents that this is a catch-all block.
- let mut cp_bx = Bx::build(self.cx, cp_bb);
+ let mut cp_bx = Bx::build(self.cx, cp_llbb);
let null = cp_bx.const_null(
cp_bx.type_i8p_ext(cp_bx.cx().data_layout().instruction_address_space),
);
@@ -1476,10 +1488,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
cp_bx.br(llbb);
}
_ => {
- let cleanup_bb =
+ let cleanup_llbb =
Bx::append_block(self.cx, self.llfn, &format!("funclet_{:?}", bb));
- ret_llbb = cleanup_bb;
- let mut cleanup_bx = Bx::build(self.cx, cleanup_bb);
+ ret_llbb = cleanup_llbb;
+ let mut cleanup_bx = Bx::build(self.cx, cleanup_llbb);
funclet = cleanup_bx.cleanup_pad(None, &[]);
cleanup_bx.br(llbb);
}
@@ -1487,19 +1499,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.funclets[bb] = Some(funclet);
ret_llbb
} else {
- let bb = Bx::append_block(self.cx, self.llfn, "cleanup");
- let mut bx = Bx::build(self.cx, bb);
+ let cleanup_llbb = Bx::append_block(self.cx, self.llfn, "cleanup");
+ let mut cleanup_bx = Bx::build(self.cx, cleanup_llbb);
let llpersonality = self.cx.eh_personality();
let llretty = self.landing_pad_type();
- let lp = bx.cleanup_landing_pad(llretty, llpersonality);
+ let lp = cleanup_bx.cleanup_landing_pad(llretty, llpersonality);
- let slot = self.get_personality_slot(&mut bx);
- slot.storage_live(&mut bx);
- Pair(bx.extract_value(lp, 0), bx.extract_value(lp, 1)).store(&mut bx, slot);
+ let slot = self.get_personality_slot(&mut cleanup_bx);
+ slot.storage_live(&mut cleanup_bx);
+ Pair(cleanup_bx.extract_value(lp, 0), cleanup_bx.extract_value(lp, 1))
+ .store(&mut cleanup_bx, slot);
- bx.br(llbb);
- bx.llbb()
+ cleanup_bx.br(llbb);
+ cleanup_llbb
}
}
@@ -1533,8 +1546,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
- let llret = bx.call(fn_ty, fn_ptr, &[], None);
- bx.apply_attrs_callsite(&fn_abi, llret);
+ let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], None);
bx.do_not_inline(llret);
bx.unreachable();
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 2b931bfc9..da9aaf00e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -148,10 +148,10 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let debug_context = cx.create_function_debug_context(instance, &fn_abi, llfn, &mir);
let start_llbb = Bx::append_block(cx, llfn, "start");
- let mut bx = Bx::build(cx, start_llbb);
+ let mut start_bx = Bx::build(cx, start_llbb);
if mir.basic_blocks.iter().any(|bb| bb.is_cleanup) {
- bx.set_personality_fn(cx.eh_personality());
+ start_bx.set_personality_fn(cx.eh_personality());
}
let cleanup_kinds = analyze::cleanup_kinds(&mir);
@@ -180,7 +180,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
caller_location: None,
};
- fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut bx);
+ fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
// Evaluate all required consts; codegen later assumes that CTFE will never fail.
let mut all_consts_ok = true;
@@ -206,29 +206,29 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// Allocate variable and temp allocas
fx.locals = {
- let args = arg_local_refs(&mut bx, &mut fx, &memory_locals);
+ let args = arg_local_refs(&mut start_bx, &mut fx, &memory_locals);
let mut allocate_local = |local| {
let decl = &mir.local_decls[local];
- let layout = bx.layout_of(fx.monomorphize(decl.ty));
+ let layout = start_bx.layout_of(fx.monomorphize(decl.ty));
assert!(!layout.ty.has_erasable_regions());
if local == mir::RETURN_PLACE && fx.fn_abi.ret.is_indirect() {
debug!("alloc: {:?} (return place) -> place", local);
- let llretptr = bx.get_param(0);
+ let llretptr = start_bx.get_param(0);
return LocalRef::Place(PlaceRef::new_sized(llretptr, layout));
}
if memory_locals.contains(local) {
debug!("alloc: {:?} -> place", local);
if layout.is_unsized() {
- LocalRef::UnsizedPlace(PlaceRef::alloca_unsized_indirect(&mut bx, layout))
+ LocalRef::UnsizedPlace(PlaceRef::alloca_unsized_indirect(&mut start_bx, layout))
} else {
- LocalRef::Place(PlaceRef::alloca(&mut bx, layout))
+ LocalRef::Place(PlaceRef::alloca(&mut start_bx, layout))
}
} else {
debug!("alloc: {:?} -> operand", local);
- LocalRef::new_operand(&mut bx, layout)
+ LocalRef::new_operand(&mut start_bx, layout)
}
};
@@ -240,7 +240,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
};
// Apply debuginfo to the newly allocated locals.
- fx.debug_introduce_locals(&mut bx);
+ fx.debug_introduce_locals(&mut start_bx);
// Codegen the body of each block using reverse postorder
for (bb, _) in traversal::reverse_postorder(&mir) {
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 37b1e0362..e6ba642a7 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -352,7 +352,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
// Allocate an appropriate region on the stack, and copy the value into it
let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
- let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, max_align);
+ let lldst = bx.byte_array_alloca(llsize, max_align);
bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags);
// Store the allocated region and the extra to the indirect place.
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 13d8f6edd..9c18df564 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -400,6 +400,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
downcast
}
+ pub fn project_type<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
+ &self,
+ bx: &mut Bx,
+ ty: Ty<'tcx>,
+ ) -> Self {
+ let mut downcast = *self;
+ downcast.layout = bx.cx().layout_of(ty);
+
+ // Cast to the appropriate type.
+ let variant_ty = bx.cx().backend_type(downcast.layout);
+ downcast.llval = bx.pointercast(downcast.llval, bx.cx().type_ptr_to(variant_ty));
+
+ downcast
+ }
+
pub fn storage_live<Bx: BuilderMethods<'a, 'tcx, Value = V>>(&self, bx: &mut Bx) {
bx.lifetime_start(self.llval, self.layout.size);
}
@@ -442,6 +457,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::ProjectionElem::Field(ref field, _) => {
cg_base.project_field(bx, field.index())
}
+ mir::ProjectionElem::OpaqueCast(ty) => cg_base.project_type(bx, ty),
mir::ProjectionElem::Index(index) => {
let index = &mir::Operand::Copy(mir::Place::from(index));
let index = self.codegen_operand(bx, index);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 56852b0fc..4aab31fbf 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -4,7 +4,6 @@ use super::{FunctionCx, LocalRef};
use crate::base;
use crate::common::{self, IntPredicate};
-use crate::meth::get_vtable;
use crate::traits::*;
use crate::MemFlags;
@@ -250,7 +249,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandValue::Pair(lldata, llextra)
}
mir::CastKind::Pointer(PointerCast::MutToConstPointer)
- | mir::CastKind::Misc
+ | mir::CastKind::PtrToPtr
if bx.cx().is_backend_scalar_pair(operand.layout) =>
{
if let OperandValue::Pair(data_ptr, meta) = operand.val {
@@ -273,24 +272,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
mir::CastKind::DynStar => {
- let data = match operand.val {
+ let (lldata, llextra) = match operand.val {
OperandValue::Ref(_, _, _) => todo!(),
- OperandValue::Immediate(v) => v,
- OperandValue::Pair(_, _) => todo!(),
+ OperandValue::Immediate(v) => (v, None),
+ OperandValue::Pair(v, l) => (v, Some(l)),
};
- let trait_ref =
- if let ty::Dynamic(data, _, ty::DynStar) = cast.ty.kind() {
- data.principal()
- } else {
- bug!("Only valid to do a DynStar cast into a DynStar type")
- };
- let vtable = get_vtable(bx.cx(), source.ty(self.mir, bx.tcx()), trait_ref);
- OperandValue::Pair(data, vtable)
+ let (lldata, llextra) =
+ base::cast_to_dyn_star(&mut bx, lldata, operand.layout, cast.ty, llextra);
+ OperandValue::Pair(lldata, llextra)
}
mir::CastKind::Pointer(
PointerCast::MutToConstPointer | PointerCast::ArrayToPointer,
)
- | mir::CastKind::Misc
+ | mir::CastKind::IntToInt
+ | mir::CastKind::FloatToInt
+ | mir::CastKind::FloatToFloat
+ | mir::CastKind::IntToFloat
+ | mir::CastKind::PtrToPtr
+ | mir::CastKind::FnPtrToPtr
+
// Since int2ptr can have arbitrary integer types as input (so we have to do
// sign extension and all that), it is currently best handled in the same code
// path as the other integer-to-X casts.
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 0e259bcd1..83407ee8f 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -13,17 +13,25 @@ pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted
const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
+ // tidy-alphabetical-start
("aclass", Some(sym::arm_target_feature)),
- ("mclass", Some(sym::arm_target_feature)),
- ("rclass", Some(sym::arm_target_feature)),
- ("dsp", Some(sym::arm_target_feature)),
- ("neon", Some(sym::arm_target_feature)),
+ ("aes", Some(sym::arm_target_feature)),
("crc", Some(sym::arm_target_feature)),
("crypto", Some(sym::arm_target_feature)),
- ("aes", Some(sym::arm_target_feature)),
- ("sha2", Some(sym::arm_target_feature)),
- ("i8mm", Some(sym::arm_target_feature)),
+ ("d32", Some(sym::arm_target_feature)),
("dotprod", Some(sym::arm_target_feature)),
+ ("dsp", Some(sym::arm_target_feature)),
+ ("fp-armv8", Some(sym::arm_target_feature)),
+ ("i8mm", Some(sym::arm_target_feature)),
+ ("mclass", Some(sym::arm_target_feature)),
+ ("neon", Some(sym::arm_target_feature)),
+ ("rclass", Some(sym::arm_target_feature)),
+ ("sha2", Some(sym::arm_target_feature)),
+ // This is needed for inline assembly, but shouldn't be stabilized as-is
+ // since it should be enabled per-function using #[instruction_set], not
+ // #[target_feature].
+ ("thumb-mode", Some(sym::arm_target_feature)),
+ ("thumb2", Some(sym::arm_target_feature)),
("v5te", Some(sym::arm_target_feature)),
("v6", Some(sym::arm_target_feature)),
("v6k", Some(sym::arm_target_feature)),
@@ -33,104 +41,97 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("vfp2", Some(sym::arm_target_feature)),
("vfp3", Some(sym::arm_target_feature)),
("vfp4", Some(sym::arm_target_feature)),
- ("fp-armv8", Some(sym::arm_target_feature)),
- // This is needed for inline assembly, but shouldn't be stabilized as-is
- // since it should be enabled per-function using #[instruction_set], not
- // #[target_feature].
- ("thumb-mode", Some(sym::arm_target_feature)),
- ("thumb2", Some(sym::arm_target_feature)),
- ("d32", Some(sym::arm_target_feature)),
+ // tidy-alphabetical-end
];
const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- // FEAT_AdvSimd & FEAT_FP
- ("neon", None),
- // FEAT_FP16
- ("fp16", None),
- // FEAT_SVE
- ("sve", None),
+ // tidy-alphabetical-start
+ // FEAT_AES
+ ("aes", None),
+ // FEAT_BF16
+ ("bf16", None),
+ // FEAT_BTI
+ ("bti", None),
// FEAT_CRC
("crc", None),
- // FEAT_RAS
- ("ras", None),
- // FEAT_LSE
- ("lse", None),
- // FEAT_RDM
- ("rdm", None),
- // FEAT_RCPC
- ("rcpc", None),
- // FEAT_RCPC2
- ("rcpc2", None),
- // FEAT_DotProd
- ("dotprod", None),
- // FEAT_TME
- ("tme", None),
- // FEAT_FHM
- ("fhm", None),
// FEAT_DIT
("dit", None),
- // FEAT_FLAGM
- ("flagm", None),
- // FEAT_SSBS
- ("ssbs", None),
- // FEAT_SB
- ("sb", None),
- // FEAT_PAUTH (address authentication)
- ("paca", None),
- // FEAT_PAUTH (generic authentication)
- ("pacg", None),
+ // FEAT_DotProd
+ ("dotprod", None),
// FEAT_DPB
("dpb", None),
// FEAT_DPB2
("dpb2", None),
- // FEAT_SVE2
- ("sve2", None),
- // FEAT_SVE2_AES
- ("sve2-aes", None),
- // FEAT_SVE2_SM4
- ("sve2-sm4", None),
- // FEAT_SVE2_SHA3
- ("sve2-sha3", None),
- // FEAT_SVE2_BitPerm
- ("sve2-bitperm", None),
- // FEAT_FRINTTS
- ("frintts", None),
- // FEAT_I8MM
- ("i8mm", None),
// FEAT_F32MM
("f32mm", None),
// FEAT_F64MM
("f64mm", None),
- // FEAT_BF16
- ("bf16", None),
- // FEAT_RAND
- ("rand", None),
- // FEAT_BTI
- ("bti", None),
- // FEAT_MTE
- ("mte", None),
- // FEAT_JSCVT
- ("jsconv", None),
// FEAT_FCMA
("fcma", None),
- // FEAT_AES
- ("aes", None),
+ // FEAT_FHM
+ ("fhm", None),
+ // FEAT_FLAGM
+ ("flagm", None),
+ // FEAT_FP16
+ ("fp16", None),
+ // FEAT_FRINTTS
+ ("frintts", None),
+ // FEAT_I8MM
+ ("i8mm", None),
+ // FEAT_JSCVT
+ ("jsconv", None),
+ // FEAT_LOR
+ ("lor", None),
+ // FEAT_LSE
+ ("lse", None),
+ // FEAT_MTE
+ ("mte", None),
+ // FEAT_AdvSimd & FEAT_FP
+ ("neon", None),
+ // FEAT_PAUTH (address authentication)
+ ("paca", None),
+ // FEAT_PAUTH (generic authentication)
+ ("pacg", None),
+ // FEAT_PAN
+ ("pan", None),
+ // FEAT_PMUv3
+ ("pmuv3", None),
+ // FEAT_RAND
+ ("rand", None),
+ // FEAT_RAS
+ ("ras", None),
+ // FEAT_RCPC
+ ("rcpc", None),
+ // FEAT_RCPC2
+ ("rcpc2", None),
+ // FEAT_RDM
+ ("rdm", None),
+ // FEAT_SB
+ ("sb", None),
// FEAT_SHA1 & FEAT_SHA256
("sha2", None),
// FEAT_SHA512 & FEAT_SHA3
("sha3", None),
// FEAT_SM3 & FEAT_SM4
("sm4", None),
- // FEAT_PAN
- ("pan", None),
- // FEAT_LOR
- ("lor", None),
- // FEAT_VHE
- ("vh", None),
- // FEAT_PMUv3
- ("pmuv3", None),
// FEAT_SPE
("spe", None),
+ // FEAT_SSBS
+ ("ssbs", None),
+ // FEAT_SVE
+ ("sve", None),
+ // FEAT_SVE2
+ ("sve2", None),
+ // FEAT_SVE2_AES
+ ("sve2-aes", None),
+ // FEAT_SVE2_BitPerm
+ ("sve2-bitperm", None),
+ // FEAT_SVE2_SHA3
+ ("sve2-sha3", None),
+ // FEAT_SVE2_SM4
+ ("sve2-sm4", None),
+ // FEAT_TME
+ ("tme", None),
("v8.1a", Some(sym::aarch64_ver_target_feature)),
("v8.2a", Some(sym::aarch64_ver_target_feature)),
("v8.3a", Some(sym::aarch64_ver_target_feature)),
@@ -138,6 +139,9 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("v8.5a", Some(sym::aarch64_ver_target_feature)),
("v8.6a", Some(sym::aarch64_ver_target_feature)),
("v8.7a", Some(sym::aarch64_ver_target_feature)),
+ // FEAT_VHE
+ ("vh", None),
+ // tidy-alphabetical-end
];
const AARCH64_TIED_FEATURES: &[&[&str]] = &[
@@ -145,6 +149,7 @@ const AARCH64_TIED_FEATURES: &[&[&str]] = &[
];
const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
+ // tidy-alphabetical-start
("adx", None),
("aes", None),
("avx", None),
@@ -194,69 +199,80 @@ const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("xsavec", None),
("xsaveopt", None),
("xsaves", None),
+ // tidy-alphabetical-end
];
const HEXAGON_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
+ // tidy-alphabetical-start
("hvx", Some(sym::hexagon_target_feature)),
("hvx-length128b", Some(sym::hexagon_target_feature)),
+ // tidy-alphabetical-end
];
const POWERPC_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
+ // tidy-alphabetical-start
("altivec", Some(sym::powerpc_target_feature)),
("power8-altivec", Some(sym::powerpc_target_feature)),
- ("power9-altivec", Some(sym::powerpc_target_feature)),
("power8-vector", Some(sym::powerpc_target_feature)),
+ ("power9-altivec", Some(sym::powerpc_target_feature)),
("power9-vector", Some(sym::powerpc_target_feature)),
("vsx", Some(sym::powerpc_target_feature)),
+ // tidy-alphabetical-end
];
const MIPS_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
+ // tidy-alphabetical-start
("fp64", Some(sym::mips_target_feature)),
("msa", Some(sym::mips_target_feature)),
("virt", Some(sym::mips_target_feature)),
+ // tidy-alphabetical-end
];
const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- ("m", Some(sym::riscv_target_feature)),
+ // tidy-alphabetical-start
("a", Some(sym::riscv_target_feature)),
("c", Some(sym::riscv_target_feature)),
- ("f", Some(sym::riscv_target_feature)),
("d", Some(sym::riscv_target_feature)),
("e", Some(sym::riscv_target_feature)),
+ ("f", Some(sym::riscv_target_feature)),
+ ("m", Some(sym::riscv_target_feature)),
("v", Some(sym::riscv_target_feature)),
- ("zfinx", Some(sym::riscv_target_feature)),
- ("zdinx", Some(sym::riscv_target_feature)),
- ("zhinx", Some(sym::riscv_target_feature)),
- ("zhinxmin", Some(sym::riscv_target_feature)),
- ("zfh", Some(sym::riscv_target_feature)),
- ("zfhmin", Some(sym::riscv_target_feature)),
("zba", Some(sym::riscv_target_feature)),
("zbb", Some(sym::riscv_target_feature)),
("zbc", Some(sym::riscv_target_feature)),
- ("zbs", Some(sym::riscv_target_feature)),
("zbkb", Some(sym::riscv_target_feature)),
("zbkc", Some(sym::riscv_target_feature)),
("zbkx", Some(sym::riscv_target_feature)),
+ ("zbs", Some(sym::riscv_target_feature)),
+ ("zdinx", Some(sym::riscv_target_feature)),
+ ("zfh", Some(sym::riscv_target_feature)),
+ ("zfhmin", Some(sym::riscv_target_feature)),
+ ("zfinx", Some(sym::riscv_target_feature)),
+ ("zhinx", Some(sym::riscv_target_feature)),
+ ("zhinxmin", Some(sym::riscv_target_feature)),
+ ("zk", Some(sym::riscv_target_feature)),
+ ("zkn", Some(sym::riscv_target_feature)),
("zknd", Some(sym::riscv_target_feature)),
("zkne", Some(sym::riscv_target_feature)),
("zknh", Some(sym::riscv_target_feature)),
- ("zksed", Some(sym::riscv_target_feature)),
- ("zksh", Some(sym::riscv_target_feature)),
("zkr", Some(sym::riscv_target_feature)),
- ("zkn", Some(sym::riscv_target_feature)),
("zks", Some(sym::riscv_target_feature)),
- ("zk", Some(sym::riscv_target_feature)),
+ ("zksed", Some(sym::riscv_target_feature)),
+ ("zksh", Some(sym::riscv_target_feature)),
("zkt", Some(sym::riscv_target_feature)),
+ // tidy-alphabetical-end
];
const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- ("simd128", None),
+ // tidy-alphabetical-start
("atomics", Some(sym::wasm_target_feature)),
- ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
("bulk-memory", Some(sym::wasm_target_feature)),
("mutable-globals", Some(sym::wasm_target_feature)),
+ ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
("reference-types", Some(sym::wasm_target_feature)),
("sign-ext", Some(sym::wasm_target_feature)),
+ ("simd128", None),
+ // tidy-alphabetical-end
];
const BPF_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[("alu32", Some(sym::bpf_target_feature))];
diff --git a/compiler/rustc_codegen_ssa/src/traits/abi.rs b/compiler/rustc_codegen_ssa/src/traits/abi.rs
index a00d78daf..60d8f2a9e 100644
--- a/compiler/rustc_codegen_ssa/src/traits/abi.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/abi.rs
@@ -1,8 +1,5 @@
use super::BackendTypes;
-use rustc_middle::ty::Ty;
-use rustc_target::abi::call::FnAbi;
pub trait AbiBuilderMethods<'tcx>: BackendTypes {
- fn apply_attrs_callsite(&mut self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, callsite: Self::Value);
fn get_param(&mut self, index: usize) -> Self::Value;
}
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 779bd3ea2..87e347c61 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -134,8 +134,6 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
opt_level: config::OptLevel,
target_features: &[String],
) -> TargetMachineFactoryFn<Self>;
- fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
- fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str>;
fn spawn_thread<F, T>(_time_trace: bool, f: F) -> std::thread::JoinHandle<T>
where
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 10cf8948b..01408f39f 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -17,6 +17,7 @@ use crate::MemFlags;
use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
use rustc_middle::ty::Ty;
use rustc_span::Span;
+use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange};
use rustc_target::spec::HasTargetSpec;
@@ -71,6 +72,7 @@ pub trait BuilderMethods<'a, 'tcx>:
fn invoke(
&mut self,
llty: Self::Type,
+ fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
llfn: Self::Value,
args: &[Self::Value],
then: Self::BasicBlock,
@@ -133,8 +135,7 @@ pub trait BuilderMethods<'a, 'tcx>:
fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value;
fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
- fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
- fn array_alloca(&mut self, ty: Self::Type, len: Self::Value, align: Align) -> Self::Value;
+ fn byte_array_alloca(&mut self, len: Self::Value, align: Align) -> Self::Value;
fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value;
fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value;
@@ -320,6 +321,7 @@ pub trait BuilderMethods<'a, 'tcx>:
fn call(
&mut self,
llty: Self::Type,
+ fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
llfn: Self::Value,
args: &[Self::Value],
funclet: Option<&Self::Funclet>,
diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
index 7755e6793..450672fb9 100644
--- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
@@ -5,7 +5,7 @@ use rustc_span::Span;
use rustc_target::abi::call::FnAbi;
pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
- /// Remember to add all intrinsics here, in `compiler/rustc_typeck/src/check/mod.rs`,
+ /// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`,
/// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics,
/// add them to `compiler/rustc_codegen_llvm/src/context.rs`.
fn codegen_intrinsic_call(
diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs
index 4266e42ec..04e2b8796 100644
--- a/compiler/rustc_codegen_ssa/src/traits/misc.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs
@@ -15,12 +15,8 @@ pub trait MiscMethods<'tcx>: BackendTypes {
fn eh_personality(&self) -> Self::Value;
fn sess(&self) -> &Session;
fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>;
- fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
- fn compiler_used_statics(&self) -> &RefCell<Vec<Self::Value>>;
fn set_frame_pointer_type(&self, llfn: Self::Function);
fn apply_target_cpu_attr(&self, llfn: Self::Function);
- fn create_used_variable(&self);
- fn create_compiler_used_variable(&self);
/// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists.
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>;
}
diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index 8158e8dd0..bdc6a91cf 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -5,7 +5,6 @@ use crate::common::TypeKind;
use crate::mir::place::PlaceRef;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Ty};
-use rustc_span::DUMMY_SP;
use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
use rustc_target::abi::{AddressSpace, Integer};
@@ -75,16 +74,16 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
}
fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
- ty.is_sized(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
+ ty.is_sized(self.tcx(), ty::ParamEnv::reveal_all())
}
fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
- ty.is_freeze(self.tcx().at(DUMMY_SP), ty::ParamEnv::reveal_all())
+ ty.is_freeze(self.tcx(), ty::ParamEnv::reveal_all())
}
fn type_has_metadata(&self, ty: Ty<'tcx>) -> bool {
let param_env = ty::ParamEnv::reveal_all();
- if ty.is_sized(self.tcx().at(DUMMY_SP), param_env) {
+ if ty.is_sized(self.tcx(), param_env) {
return false;
}
diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs
index e54ec34f1..e0e8ffa89 100644
--- a/compiler/rustc_codegen_ssa/src/traits/write.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/write.rs
@@ -9,7 +9,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
type Module: Send + Sync;
type TargetMachine;
type ModuleBuffer: ModuleBufferMethods;
- type Context: ?Sized;
type ThinData: Send + Sync;
type ThinBuffer: ThinBufferMethods;