summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/assert_module_sources.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs67
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs131
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs27
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs36
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs51
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs50
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs89
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs24
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs23
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs43
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/locals.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs55
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/size_of_val.rs (renamed from compiler/rustc_codegen_ssa/src/glue.rs)96
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs403
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/write.rs8
27 files changed, 482 insertions, 729 deletions
diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
index 16bb7b12b..a5bd10ecb 100644
--- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
+++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
@@ -149,7 +149,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
self.cgu_reuse_tracker.set_expectation(
cgu_name,
- &user_path,
+ user_path,
attr.span,
expected_reuse,
comp_kind,
@@ -199,8 +199,8 @@ impl fmt::Display for CguReuse {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
CguReuse::No => write!(f, "No"),
- CguReuse::PreLto => write!(f, "PreLto "),
- CguReuse::PostLto => write!(f, "PostLto "),
+ CguReuse::PreLto => write!(f, "PreLto"),
+ CguReuse::PostLto => write!(f, "PostLto"),
}
}
}
@@ -278,13 +278,13 @@ impl CguReuseTracker {
if error {
let at_least = if at_least { 1 } else { 0 };
- errors::IncorrectCguReuseType {
+ sess.emit_err(errors::IncorrectCguReuseType {
span: *error_span,
cgu_user_name,
actual_reuse,
expected_reuse,
at_least,
- };
+ });
}
} else {
sess.emit_fatal(errors::CguNotRecorded { cgu_user_name, cgu_name });
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 1c464b3ec..4dc28adf3 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -175,8 +175,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
) -> io::Result<()> {
let mut archive_path = archive_path.to_path_buf();
if self.sess.target.llvm_target.contains("-apple-macosx") {
- if let Some(new_archive_path) =
- try_extract_macho_fat_archive(&self.sess, &archive_path)?
+ if let Some(new_archive_path) = try_extract_macho_fat_archive(self.sess, &archive_path)?
{
archive_path = new_archive_path
}
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index dd9d277fb..b0d22ad0a 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::temp_dir::MaybeTempDir;
-use rustc_errors::{ErrorGuaranteed, Handler};
+use rustc_errors::{DiagCtxt, ErrorGuaranteed};
use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize};
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_metadata::find_native_static_library;
@@ -44,7 +44,7 @@ use tempfile::Builder as TempFileBuilder;
use itertools::Itertools;
use std::cell::OnceCell;
use std::collections::BTreeSet;
-use std::ffi::OsString;
+use std::ffi::{OsStr, OsString};
use std::fs::{read, File, OpenOptions};
use std::io::{BufWriter, Write};
use std::ops::Deref;
@@ -52,10 +52,10 @@ use std::path::{Path, PathBuf};
use std::process::{ExitStatus, Output, Stdio};
use std::{env, fmt, fs, io, mem, str};
-pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
+pub fn ensure_removed(dcx: &DiagCtxt, path: &Path) {
if let Err(e) = fs::remove_file(path) {
if e.kind() != io::ErrorKind::NotFound {
- diag_handler.err(format!("failed to remove {}: {}", path.display(), e));
+ dcx.err(format!("failed to remove {}: {}", path.display(), e));
}
}
}
@@ -143,7 +143,7 @@ pub fn link_binary<'a>(
}
}
if sess.opts.json_artifact_notifications {
- sess.parse_sess.span_diagnostic.emit_artifact_notification(&out_filename, "link");
+ sess.dcx().emit_artifact_notification(&out_filename, "link");
}
if sess.prof.enabled() {
@@ -183,13 +183,13 @@ pub fn link_binary<'a>(
|preserve_objects: bool, preserve_dwarf_objects: bool, module: &CompiledModule| {
if !preserve_objects {
if let Some(ref obj) = module.object {
- ensure_removed(sess.diagnostic(), obj);
+ ensure_removed(sess.dcx(), obj);
}
}
if !preserve_dwarf_objects {
if let Some(ref dwo_obj) = module.dwarf_object {
- ensure_removed(sess.diagnostic(), dwo_obj);
+ ensure_removed(sess.dcx(), dwo_obj);
}
}
};
@@ -208,7 +208,7 @@ pub fn link_binary<'a>(
// Remove the temporary files if output goes to stdout
for temp in tempfiles_for_stdout_output {
- ensure_removed(sess.diagnostic(), &temp);
+ ensure_removed(sess.dcx(), &temp);
}
// If no requested outputs require linking, then the object temporaries should
@@ -277,7 +277,7 @@ pub fn each_linked_rlib(
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);
+ f(cnum, path);
} else {
if used_crate_source.rmeta.is_some() {
return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name });
@@ -524,7 +524,7 @@ fn link_staticlib<'a>(
&& !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
- let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, &lib));
+ let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
let relevant_libs: FxHashSet<_> = relevant.filter_map(|lib| lib.filename).collect();
let bundled_libs: FxHashSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
@@ -689,7 +689,7 @@ fn link_dwarf_object<'a>(
// Adding an executable is primarily done to make `thorin` check that all the referenced
// dwarf objects are found in the end.
package.add_executable(
- &executable_out_filename,
+ executable_out_filename,
thorin::MissingReferencedObjectBehaviour::Skip,
)?;
@@ -928,7 +928,7 @@ fn link_natively<'a>(
command: &cmd,
escaped_output,
};
- sess.diagnostic().emit_err(err);
+ sess.dcx().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.
@@ -945,7 +945,7 @@ fn link_natively<'a>(
{
let is_vs_installed = windows_registry::find_vs_version().is_ok();
let has_linker = windows_registry::find_tool(
- &sess.opts.target_triple.triple(),
+ sess.opts.target_triple.triple(),
"link.exe",
)
.is_some();
@@ -1038,14 +1038,14 @@ fn link_natively<'a>(
if sess.target.is_like_osx {
match (strip, crate_type) {
(Strip::Debuginfo, _) => {
- strip_symbols_with_external_utility(sess, "strip", &out_filename, Some("-S"))
+ 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_with_external_utility(sess, "strip", &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_with_external_utility(sess, "strip", out_filename, None)
}
(Strip::None, _) => {}
}
@@ -1059,7 +1059,7 @@ fn link_natively<'a>(
match strip {
// Always preserve the symbol table (-x).
Strip::Debuginfo => {
- strip_symbols_with_external_utility(sess, stripcmd, &out_filename, Some("-x"))
+ strip_symbols_with_external_utility(sess, stripcmd, out_filename, Some("-x"))
}
// Strip::Symbols is handled via the --strip-all linker option.
Strip::Symbols => {}
@@ -1245,13 +1245,13 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
// rpath to the library as well (the rpath should be absolute, see
// PR #41352 for details).
let filename = format!("rustc{channel}_rt.{name}");
- let path = find_sanitizer_runtime(&sess, &filename);
+ let path = find_sanitizer_runtime(sess, &filename);
let rpath = path.to_str().expect("non-utf8 component in path");
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
linker.link_dylib(&filename, false, true);
} else {
let filename = format!("librustc{channel}_rt.{name}.a");
- let path = find_sanitizer_runtime(&sess, &filename).join(&filename);
+ let path = find_sanitizer_runtime(sess, &filename).join(&filename);
linker.link_whole_rlib(&path);
}
}
@@ -1477,7 +1477,7 @@ fn print_native_static_libs(
sess.emit_note(errors::StaticLibraryNativeArtifacts);
// Prefix for greppability
// Note: This must not be translated as tools are allowed to depend on this exact string.
- sess.note_without_error(format!("native-static-libs: {}", &lib_args.join(" ")));
+ sess.note(format!("native-static-libs: {}", &lib_args.join(" ")));
}
}
}
@@ -1685,7 +1685,7 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
// Returns true if linker is located within sysroot
fn detect_self_contained_mingw(sess: &Session) -> bool {
- let (linker, _) = linker_and_flavor(&sess);
+ let (linker, _) = linker_and_flavor(sess);
// Assume `-C linker=rust-lld` as self-contained mode
if linker == Path::new("rust-lld") {
return true;
@@ -1737,7 +1737,7 @@ fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfC
LinkSelfContainedDefault::InferredForMingw => {
sess.host == sess.target
&& sess.target.vendor != "uwp"
- && detect_self_contained_mingw(&sess)
+ && detect_self_contained_mingw(sess)
}
}
};
@@ -2243,9 +2243,9 @@ fn linker_with_args<'a>(
// ------------ Late order-dependent options ------------
// Doesn't really make sense.
- // FIXME: In practice built-in target specs use this for arbitrary order-independent options,
- // introduce a target spec option for order-independent linker options, migrate built-in specs
- // to it and remove the option.
+ // FIXME: In practice built-in target specs use this for arbitrary order-independent options.
+ // Introduce a target spec option for order-independent linker options, migrate built-in specs
+ // to it and remove the option. Currently the last holdout is wasm32-unknown-emscripten.
add_post_link_args(cmd, sess, flavor);
Ok(cmd.take_cmd())
@@ -2378,6 +2378,11 @@ fn add_order_independent_options(
cmd.control_flow_guard();
}
+ // OBJECT-FILES-NO, AUDIT-ORDER
+ if sess.opts.unstable_opts.ehcont_guard {
+ cmd.ehcont_guard();
+ }
+
add_rpath_args(cmd, sess, codegen_results, out_filename);
}
@@ -2432,7 +2437,7 @@ fn add_native_libs_from_crate(
// If rlib contains native libs as archives, unpack them to tmpdir.
let rlib = &codegen_results.crate_info.used_crate_source[&cnum].rlib.as_ref().unwrap().0;
archive_builder_builder
- .extract_bundled_libs(rlib, tmpdir, &bundled_libs)
+ .extract_bundled_libs(rlib, tmpdir, bundled_libs)
.unwrap_or_else(|e| sess.emit_fatal(e));
}
@@ -2485,7 +2490,7 @@ fn add_native_libs_from_crate(
cmd.link_whole_staticlib(
name,
verbatim,
- &search_paths.get_or_init(|| archive_search_paths(sess)),
+ search_paths.get_or_init(|| archive_search_paths(sess)),
);
} else {
cmd.link_staticlib(name, verbatim)
@@ -2522,7 +2527,7 @@ fn add_native_libs_from_crate(
NativeLibKind::WasmImportModule => {}
NativeLibKind::LinkArg => {
if link_static {
- cmd.arg(name);
+ cmd.linker_arg(OsStr::new(name), verbatim);
}
}
}
@@ -2719,7 +2724,7 @@ fn rehome_sysroot_lib_dir<'a>(sess: &'a Session, lib_dir: &Path) -> PathBuf {
// already had `fix_windows_verbatim_for_gcc()` applied if needed.
sysroot_lib_path
} else {
- fix_windows_verbatim_for_gcc(&lib_dir)
+ fix_windows_verbatim_for_gcc(lib_dir)
}
}
@@ -2756,7 +2761,7 @@ fn add_static_crate<'a>(
let mut link_upstream = |path: &Path| {
let rlib_path = if let Some(dir) = path.parent() {
let file_name = path.file_name().expect("rlib path has no file name path component");
- rehome_sysroot_lib_dir(sess, &dir).join(file_name)
+ rehome_sysroot_lib_dir(sess, dir).join(file_name)
} else {
fix_windows_verbatim_for_gcc(path)
};
@@ -2793,7 +2798,7 @@ fn add_static_crate<'a>(
let canonical = f.replace('-', "_");
let is_rust_object =
- canonical.starts_with(&canonical_name) && looks_like_rust_object_file(&f);
+ canonical.starts_with(&canonical_name) && looks_like_rust_object_file(f);
// If we're performing LTO and this is a rust-generated object
// file, then we don't need the object file as it's part of the
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 09434513e..eeb57d4d0 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -45,7 +45,7 @@ pub fn get_linker<'a>(
self_contained: bool,
target_cpu: &'a str,
) -> Box<dyn Linker + 'a> {
- let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");
+ let msvc_tool = windows_registry::find_tool(sess.opts.target_triple.triple(), "link.exe");
// If our linker looks like a batch script on Windows then to execute this
// we'll need to spawn `cmd` explicitly. This is primarily done to handle
@@ -78,7 +78,7 @@ pub fn get_linker<'a>(
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) {
+ if let Some(root_lib_path) = original_path.ancestors().nth(4) {
let arch = match t.arch.as_ref() {
"x86_64" => Some("x64"),
"x86" => Some("x86"),
@@ -185,6 +185,7 @@ pub trait Linker {
fn optimize(&mut self);
fn pgo_gen(&mut self);
fn control_flow_guard(&mut self);
+ fn ehcont_guard(&mut self);
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]);
fn no_crt_objects(&mut self);
fn no_default_libraries(&mut self);
@@ -195,6 +196,14 @@ pub trait Linker {
fn add_no_exec(&mut self) {}
fn add_as_needed(&mut self) {}
fn reset_per_library_state(&mut self) {}
+ fn linker_arg(&mut self, arg: &OsStr, verbatim: bool) {
+ self.linker_args(&[arg], verbatim);
+ }
+ fn linker_args(&mut self, args: &[&OsStr], _verbatim: bool) {
+ args.into_iter().for_each(|a| {
+ self.cmd().arg(a);
+ });
+ }
}
impl dyn Linker + '_ {
@@ -222,38 +231,12 @@ pub struct GccLinker<'a> {
}
impl<'a> GccLinker<'a> {
- /// Passes an argument directly to the linker.
- ///
- /// When the linker is not ld-like such as when using a compiler as a linker, the argument is
- /// prepended by `-Wl,`.
- fn linker_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
- self.linker_args(&[arg]);
- self
+ fn linker_arg(&mut self, arg: impl AsRef<OsStr>) {
+ Linker::linker_arg(self, arg.as_ref(), false);
}
-
- /// Passes a series of arguments directly to the linker.
- ///
- /// When the linker is ld-like, the arguments are simply appended to the command. When the
- /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
- /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
- /// single argument is appended to the command to ensure that the order of the arguments is
- /// preserved by the compiler.
- fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) -> &mut Self {
- if self.is_ld {
- args.into_iter().for_each(|a| {
- self.cmd.arg(a);
- });
- } else {
- if !args.is_empty() {
- let mut s = OsString::from("-Wl");
- for a in args {
- s.push(",");
- s.push(a);
- }
- self.cmd.arg(s);
- }
- }
- self
+ fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) {
+ let args_vec: Vec<&OsStr> = args.iter().map(|x| x.as_ref()).collect();
+ Linker::linker_args(self, &args_vec, false);
}
fn takes_hints(&self) -> bool {
@@ -360,6 +343,30 @@ impl<'a> GccLinker<'a> {
}
impl<'a> Linker for GccLinker<'a> {
+ /// Passes a series of arguments directly to the linker.
+ ///
+ /// When the linker is ld-like, the arguments are simply appended to the command. When the
+ /// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
+ /// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
+ /// single argument is appended to the command to ensure that the order of the arguments is
+ /// preserved by the compiler.
+ fn linker_args(&mut self, args: &[&OsStr], verbatim: bool) {
+ if self.is_ld || verbatim {
+ args.into_iter().for_each(|a| {
+ self.cmd.arg(a);
+ });
+ } else {
+ if !args.is_empty() {
+ let mut s = OsString::from("-Wl");
+ for a in args {
+ s.push(",");
+ s.push(a);
+ }
+ self.cmd.arg(s);
+ }
+ }
+ }
+
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
@@ -519,7 +526,7 @@ impl<'a> Linker for GccLinker<'a> {
// -force_load is the macOS equivalent of --whole-archive, but it
// involves passing the full path to the library to link.
self.linker_arg("-force_load");
- let lib = find_native_static_library(lib, verbatim, search_path, &self.sess);
+ let lib = find_native_static_library(lib, verbatim, search_path, self.sess);
self.linker_arg(&lib);
}
}
@@ -530,7 +537,7 @@ impl<'a> Linker for GccLinker<'a> {
self.linker_arg("-force_load");
self.linker_arg(&lib);
} else {
- self.linker_arg("--whole-archive").cmd.arg(lib);
+ self.linker_args(&[OsString::from("--whole-archive"), lib.into()]);
self.linker_arg("--no-whole-archive");
}
}
@@ -605,6 +612,8 @@ impl<'a> Linker for GccLinker<'a> {
fn control_flow_guard(&mut self) {}
+ fn ehcont_guard(&mut self) {}
+
fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
// MacOS linker doesn't support stripping symbols directly anymore.
if self.sess.target.is_like_osx {
@@ -914,6 +923,12 @@ impl<'a> Linker for MsvcLinker<'a> {
self.cmd.arg("/guard:cf");
}
+ fn ehcont_guard(&mut self) {
+ if self.sess.target.pointer_width == 64 {
+ self.cmd.arg("/guard:ehcont");
+ }
+ }
+
fn debuginfo(&mut self, strip: Strip, natvis_debugger_visualizers: &[PathBuf]) {
match strip {
Strip::None => {
@@ -1127,6 +1142,8 @@ impl<'a> Linker for EmLinker<'a> {
fn control_flow_guard(&mut self) {}
+ fn ehcont_guard(&mut self) {}
+
fn debuginfo(&mut self, _strip: Strip, _: &[PathBuf]) {
// Preserve names or generate source maps depending on debug info
// For more information see https://emscripten.org/docs/tools_reference/emcc.html#emcc-g
@@ -1291,6 +1308,8 @@ impl<'a> Linker for WasmLd<'a> {
}
fn optimize(&mut self) {
+ // The -O flag is, as of late 2023, only used for merging of strings and debuginfo, and
+ // only differentiates -O0 and -O1. It does not apply to LTO.
self.cmd.arg(match self.sess.opts.optimize {
OptLevel::No => "-O0",
OptLevel::Less => "-O1",
@@ -1319,6 +1338,8 @@ impl<'a> Linker for WasmLd<'a> {
fn control_flow_guard(&mut self) {}
+ fn ehcont_guard(&mut self) {}
+
fn no_crt_objects(&mut self) {}
fn no_default_libraries(&mut self) {}
@@ -1341,7 +1362,31 @@ impl<'a> Linker for WasmLd<'a> {
fn subsystem(&mut self, _subsystem: &str) {}
fn linker_plugin_lto(&mut self) {
- // Do nothing for now
+ match self.sess.opts.cg.linker_plugin_lto {
+ LinkerPluginLto::Disabled => {
+ // Nothing to do
+ }
+ LinkerPluginLto::LinkerPluginAuto => {
+ self.push_linker_plugin_lto_args();
+ }
+ LinkerPluginLto::LinkerPlugin(_) => {
+ self.push_linker_plugin_lto_args();
+ }
+ }
+ }
+}
+
+impl<'a> WasmLd<'a> {
+ fn push_linker_plugin_lto_args(&mut self) {
+ let opt_level = match self.sess.opts.optimize {
+ config::OptLevel::No => "O0",
+ config::OptLevel::Less => "O1",
+ config::OptLevel::Default => "O2",
+ config::OptLevel::Aggressive => "O3",
+ // wasm-ld only handles integer LTO opt levels. Use O2
+ config::OptLevel::Size | config::OptLevel::SizeMin => "O2",
+ };
+ self.cmd.arg(&format!("--lto-{opt_level}"));
}
}
@@ -1472,6 +1517,8 @@ impl<'a> Linker for L4Bender<'a> {
fn control_flow_guard(&mut self) {}
+ fn ehcont_guard(&mut self) {}
+
fn no_crt_objects(&mut self) {}
}
@@ -1590,7 +1637,7 @@ impl<'a> Linker for AixLinker<'a> {
fn link_whole_staticlib(&mut self, lib: &str, verbatim: bool, search_path: &[PathBuf]) {
self.hint_static();
- let lib = find_native_static_library(lib, verbatim, search_path, &self.sess);
+ let lib = find_native_static_library(lib, verbatim, search_path, self.sess);
self.cmd.arg(format!("-bkeepfile:{}", lib.to_str().unwrap()));
}
@@ -1613,6 +1660,8 @@ impl<'a> Linker for AixLinker<'a> {
fn control_flow_guard(&mut self) {}
+ fn ehcont_guard(&mut self) {}
+
fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
match strip {
Strip::None => {}
@@ -1699,7 +1748,9 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) -
let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
if info.level.is_below_threshold(export_threshold) {
- symbols.push(symbol_export::symbol_name_for_instance_in_crate(tcx, symbol, cnum));
+ symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate(
+ tcx, symbol, cnum,
+ ));
}
});
@@ -1835,6 +1886,8 @@ impl<'a> Linker for PtxLinker<'a> {
fn control_flow_guard(&mut self) {}
+ fn ehcont_guard(&mut self) {}
+
fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, _symbols: &[String]) {}
fn subsystem(&mut self, _subsystem: &str) {}
@@ -1931,6 +1984,8 @@ impl<'a> Linker for BpfLinker<'a> {
fn control_flow_guard(&mut self) {}
+ fn ehcont_guard(&mut self) {}
+
fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
let path = tmpdir.join("symbols");
let res: io::Result<()> = try {
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index cb60ed729..b683e1b45 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -12,9 +12,9 @@ use object::{
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
+use rustc_metadata::creader::MetadataLoader;
use rustc_metadata::fs::METADATA_FILENAME;
use rustc_metadata::EncodedMetadata;
-use rustc_session::cstore::MetadataLoader;
use rustc_session::Session;
use rustc_span::sym;
use rustc_target::abi::Endian;
@@ -158,11 +158,12 @@ pub(super) fn get_metadata_xcoff<'a>(path: &Path, data: &'a [u8]) -> Result<&'a
file.symbols().find(|sym| sym.name() == Ok(AIX_METADATA_SYMBOL_NAME))
{
let offset = metadata_symbol.address() as usize;
+ // The offset specifies the location of rustc metadata in the .info section of XCOFF.
+ // Each string stored in .info section of XCOFF is preceded by a 4-byte length field.
if offset < 4 {
return Err(format!("Invalid metadata symbol offset: {offset}"));
}
- // The offset specifies the location of rustc metadata in the comment section.
- // The metadata is preceded by a 4-byte length field.
+ // XCOFF format uses big-endian byte order.
let len = u32::from_be_bytes(info_data[(offset - 4)..offset].try_into().unwrap()) as usize;
if offset + len > (info_data.len() as usize) {
return Err(format!(
@@ -226,6 +227,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
let mut file = write::Object::new(binary_format, architecture, endianness);
if sess.target.is_like_osx {
+ if macho_is_arm64e(&sess.target) {
+ file.set_macho_cpu_subtype(object::macho::CPU_SUBTYPE_ARM64E);
+ }
+
file.set_macho_build_version(macho_object_build_version_for_target(&sess.target))
}
if binary_format == BinaryFormat::Coff {
@@ -385,6 +390,11 @@ fn macho_object_build_version_for_target(target: &Target) -> object::write::Mach
build_version
}
+/// Is Apple's CPU subtype `arm64e`s
+fn macho_is_arm64e(target: &Target) -> bool {
+ return target.llvm_target.starts_with("arm64e");
+}
+
pub enum MetadataPosition {
First,
Last,
@@ -469,8 +479,11 @@ pub fn create_wrapper_file(
file.add_section(Vec::new(), b".text".to_vec(), SectionKind::Text);
file.section_mut(section).flags =
SectionFlags::Xcoff { s_flags: xcoff::STYP_INFO as u32 };
-
- let len = data.len() as u32;
+ // Encode string stored in .info section of XCOFF.
+ // FIXME: The length of data here is not guaranteed to fit in a u32.
+ // We may have to split the data into multiple pieces in order to
+ // store in .info section.
+ let len: u32 = data.len().try_into().unwrap();
let offset = file.append_section_data(section, &len.to_be_bytes(), 1);
// Add a symbol referring to the data in .info section.
file.add_symbol(Symbol {
@@ -515,7 +528,7 @@ pub fn create_compressed_metadata_file(
symbol_name: &str,
) -> Vec<u8> {
let mut packed_metadata = rustc_metadata::METADATA_HEADER.to_vec();
- packed_metadata.write_all(&(metadata.raw_data().len() as u32).to_be_bytes()).unwrap();
+ packed_metadata.write_all(&(metadata.raw_data().len() as u64).to_le_bytes()).unwrap();
packed_metadata.extend(metadata.raw_data());
let Some(mut file) = create_object_file(sess) else {
@@ -590,7 +603,7 @@ pub fn create_compressed_metadata_file_for_xcoff(
section: SymbolSection::Section(data_section),
flags: SymbolFlags::None,
});
- let len = data.len() as u32;
+ let len: u32 = data.len().try_into().unwrap();
let offset = file.append_section_data(section, &len.to_be_bytes(), 1);
// Add a symbol referring to the rustc metadata.
file.add_symbol(Symbol {
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 9cd439410..ff667eecf 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -16,7 +16,7 @@ use rustc_middle::ty::{self, SymbolName, TyCtxt};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_middle::util::Providers;
use rustc_session::config::{CrateType, OomStrategy};
-use rustc_target::spec::SanitizerSet;
+use rustc_target::spec::{SanitizerSet, TlsModel};
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
crates_export_threshold(tcx.crate_types())
@@ -548,6 +548,12 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
let mut undecorated = symbol_name_for_instance_in_crate(tcx, symbol, instantiating_crate);
+ // thread local will not be a function call,
+ // so it is safe to return before windows symbol decoration check.
+ if let Some(name) = maybe_emutls_symbol_name(tcx, symbol, &undecorated) {
+ return name;
+ }
+
let target = &tcx.sess.target;
if !target.is_like_windows {
// Mach-O has a global "_" suffix and `object` crate will handle it.
@@ -608,6 +614,32 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
format!("{prefix}{undecorated}{suffix}{args_in_bytes}")
}
+pub fn exporting_symbol_name_for_instance_in_crate<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ symbol: ExportedSymbol<'tcx>,
+ cnum: CrateNum,
+) -> String {
+ let undecorated = symbol_name_for_instance_in_crate(tcx, symbol, cnum);
+ maybe_emutls_symbol_name(tcx, symbol, &undecorated).unwrap_or(undecorated)
+}
+
+fn maybe_emutls_symbol_name<'tcx>(
+ tcx: TyCtxt<'tcx>,
+ symbol: ExportedSymbol<'tcx>,
+ undecorated: &str,
+) -> Option<String> {
+ if matches!(tcx.sess.tls_model(), TlsModel::Emulated)
+ && let ExportedSymbol::NonGeneric(def_id) = symbol
+ && tcx.is_thread_local_static(def_id)
+ {
+ // When using emutls, LLVM will add the `__emutls_v.` prefix to thread local symbols,
+ // and exported symbol name need to match this.
+ Some(format!("__emutls_v.{undecorated}"))
+ } else {
+ None
+ }
+}
+
fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, String> {
// Build up a map from DefId to a `NativeLib` structure, where
// `NativeLib` internally contains information about
@@ -621,7 +653,7 @@ fn wasm_import_module_map(tcx: TyCtxt<'_>, cnum: CrateNum) -> FxHashMap<DefId, S
let mut ret = FxHashMap::default();
for (def_id, lib) in tcx.foreign_modules(cnum).iter() {
- let module = def_id_to_native_lib.get(&def_id).and_then(|s| s.wasm_import_module());
+ let module = def_id_to_native_lib.get(def_id).and_then(|s| s.wasm_import_module());
let Some(module) = module else { continue };
ret.extend(lib.foreign_items.iter().map(|id| {
assert_eq!(id.krate, cnum);
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 3d6a21243..d80ef1eba 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -14,7 +14,7 @@ use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::profiling::{SelfProfilerRef, 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::Translate, DiagCtxt, DiagnosticId, FatalError, Level};
use rustc_errors::{DiagnosticMessage, Style};
use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -355,7 +355,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
/// how to call the compiler with the same arguments.
pub expanded_args: Vec<String>,
- /// Handler to use for diagnostics produced during codegen.
+ /// Emitter to use for diagnostics produced during codegen.
pub diag_emitter: SharedEmitter,
/// LLVM optimizations for which we want to print remarks.
pub remark: Passes,
@@ -370,8 +370,8 @@ pub struct CodegenContext<B: WriteBackendMethods> {
}
impl<B: WriteBackendMethods> CodegenContext<B> {
- pub fn create_diag_handler(&self) -> Handler {
- Handler::with_emitter(Box::new(self.diag_emitter.clone()))
+ pub fn create_dcx(&self) -> DiagCtxt {
+ DiagCtxt::with_emitter(Box::new(self.diag_emitter.clone()))
}
pub fn config(&self, kind: ModuleKind) -> &ModuleConfig {
@@ -569,7 +569,7 @@ fn produce_final_output_artifacts(
}
if !sess.opts.cg.save_temps && !keep_numbered {
// The user just wants `foo.x`, not `foo.#module-name#.x`.
- ensure_removed(sess.diagnostic(), &path);
+ ensure_removed(sess.dcx(), &path);
}
} else {
let extension = crate_output
@@ -660,19 +660,19 @@ fn produce_final_output_artifacts(
for module in compiled_modules.modules.iter() {
if let Some(ref path) = module.object {
if !keep_numbered_objects {
- ensure_removed(sess.diagnostic(), path);
+ ensure_removed(sess.dcx(), path);
}
}
if let Some(ref path) = module.dwarf_object {
if !keep_numbered_objects {
- ensure_removed(sess.diagnostic(), path);
+ ensure_removed(sess.dcx(), path);
}
}
if let Some(ref path) = module.bytecode {
if !keep_numbered_bitcode {
- ensure_removed(sess.diagnostic(), path);
+ ensure_removed(sess.dcx(), path);
}
}
}
@@ -680,7 +680,7 @@ fn produce_final_output_artifacts(
if !user_wants_bitcode {
if let Some(ref allocator_module) = compiled_modules.allocator_module {
if let Some(ref path) = allocator_module.bytecode {
- ensure_removed(sess.diagnostic(), path);
+ ensure_removed(sess.dcx(), path);
}
}
}
@@ -836,10 +836,10 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
module: ModuleCodegen<B::Module>,
module_config: &ModuleConfig,
) -> Result<WorkItemResult<B>, FatalError> {
- let diag_handler = cgcx.create_diag_handler();
+ let dcx = cgcx.create_dcx();
unsafe {
- B::optimize(cgcx, &diag_handler, &module, module_config)?;
+ B::optimize(cgcx, &dcx, &module, module_config)?;
}
// After we've done the initial round of optimizations we need to
@@ -892,7 +892,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap();
let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| {
- let source_file = in_incr_comp_dir(&incr_comp_session_dir, saved_path);
+ let source_file = in_incr_comp_dir(incr_comp_session_dir, saved_path);
debug!(
"copying preexisting module `{}` from {:?} to {}",
module.name,
@@ -902,11 +902,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
match link_or_copy(&source_file, &output_path) {
Ok(_) => Some(output_path),
Err(error) => {
- cgcx.create_diag_handler().emit_err(errors::CopyPathBuf {
- source_file,
- output_path,
- error,
- });
+ cgcx.create_dcx().emit_err(errors::CopyPathBuf { source_file, output_path, error });
None
}
}
@@ -914,7 +910,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
let object = load_from_incr_comp_dir(
cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)),
- &module.source.saved_files.get("o").expect("no saved object file in work product"),
+ module.source.saved_files.get("o").expect("no saved object file in work product"),
);
let dwarf_object =
module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| {
@@ -924,7 +920,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
.expect(
"saved dwarf object in work product but `split_dwarf_path` returned `None`",
);
- load_from_incr_comp_dir(dwarf_obj_out, &saved_dwarf_object_file)
+ load_from_incr_comp_dir(dwarf_obj_out, saved_dwarf_object_file)
});
WorkItemResult::Finished(CompiledModule {
@@ -950,13 +946,13 @@ fn finish_intra_module_work<B: ExtraBackendMethods>(
module: ModuleCodegen<B::Module>,
module_config: &ModuleConfig,
) -> Result<WorkItemResult<B>, FatalError> {
- let diag_handler = cgcx.create_diag_handler();
+ let dcx = cgcx.create_dcx();
if !cgcx.opts.unstable_opts.combine_cgu
|| module.kind == ModuleKind::Metadata
|| module.kind == ModuleKind::Allocator
{
- let module = unsafe { B::codegen(cgcx, &diag_handler, module, module_config)? };
+ let module = unsafe { B::codegen(cgcx, &dcx, module, module_config)? };
Ok(WorkItemResult::Finished(module))
} else {
Ok(WorkItemResult::NeedsLink(module))
@@ -1609,11 +1605,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
let needs_link = mem::take(&mut needs_link);
if !needs_link.is_empty() {
assert!(compiled_modules.is_empty());
- let diag_handler = cgcx.create_diag_handler();
- let module = B::run_link(&cgcx, &diag_handler, needs_link).map_err(|_| ())?;
+ let dcx = cgcx.create_dcx();
+ let module = B::run_link(&cgcx, &dcx, needs_link).map_err(|_| ())?;
let module = unsafe {
- B::codegen(&cgcx, &diag_handler, module, cgcx.config(ModuleKind::Regular))
- .map_err(|_| ())?
+ B::codegen(&cgcx, &dcx, module, cgcx.config(ModuleKind::Regular)).map_err(|_| ())?
};
compiled_modules.push(module);
}
@@ -1856,13 +1851,13 @@ impl SharedEmitterMain {
match message {
Ok(SharedEmitterMessage::Diagnostic(diag)) => {
- let handler = sess.diagnostic();
+ let dcx = sess.dcx();
let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msg);
if let Some(code) = diag.code {
d.code(code);
}
d.replace_args(diag.args);
- handler.emit_diagnostic(&mut d);
+ dcx.emit_diagnostic(d);
}
Ok(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)) => {
let msg = msg.strip_prefix("error: ").unwrap_or(&msg).to_string();
@@ -1870,7 +1865,7 @@ impl SharedEmitterMain {
let mut err = match level {
Level::Error { lint: false } => sess.struct_err(msg).forget_guarantee(),
Level::Warning(_) => sess.struct_warn(msg),
- Level::Note => sess.struct_note_without_error(msg),
+ Level::Note => sess.struct_note(msg),
_ => bug!("Invalid inline asm diagnostic level"),
};
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 198e56963..1d5205ac6 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -148,10 +148,9 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(&ty::Array(_, len), &ty::Slice(_)) => {
cx.const_usize(len.eval_target_usize(cx.tcx(), ty::ParamEnv::reveal_all()))
}
- (
- &ty::Dynamic(ref data_a, _, src_dyn_kind),
- &ty::Dynamic(ref data_b, _, target_dyn_kind),
- ) if src_dyn_kind == target_dyn_kind => {
+ (&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind))
+ if 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() {
@@ -322,8 +321,13 @@ pub fn cast_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
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.
+ // We zero-extend even if the RHS is signed. So e.g. `(x: i32) << -1i8` will zero-extend the
+ // RHS to `255i32`. But then we mask the shift amount to be within the size of the LHS
+ // anyway so the result is `31` as it should be. All the extra bits introduced by zext
+ // are masked off so their value does not matter.
+ // FIXME: if we ever support 512bit integers, this will be wrong! For such large integers,
+ // the extra bits introduced by zext are *not* all masked away any more.
+ assert!(lhs_sz <= 256);
bx.zext(rhs, lhs_llty)
} else {
rhs
@@ -453,8 +457,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx.set_frame_pointer_type(llfn);
cx.apply_target_cpu_attr(llfn);
- let llbb = Bx::append_block(&cx, llfn, "top");
- let mut bx = Bx::build(&cx, llbb);
+ let llbb = Bx::append_block(cx, llfn, "top");
+ let mut bx = Bx::build(cx, llbb);
bx.insert_reference_to_gdb_debug_scripts_section_global();
@@ -680,7 +684,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
// Calculate the CGU reuse
let cgu_reuse = tcx.sess.time("find_cgu_reuse", || {
- codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::<Vec<_>>()
+ codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, cgu)).collect::<Vec<_>>()
});
crate::assert_module_sources::assert_module_sources(tcx, &|cgu_reuse_tracker| {
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 2e0840f2d..e529956b1 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -57,7 +57,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
);
}
- let attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(did));
+ let attrs = tcx.hir().attrs(tcx.local_def_id_to_hir_id(did));
let mut codegen_fn_attrs = CodegenFnAttrs::new();
if tcx.should_inherit_track_caller(did) {
codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
@@ -91,7 +91,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
Some(tcx.fn_sig(did))
} else {
tcx.sess
- .delay_span_bug(attr.span, "this attribute can only be applied to functions");
+ .span_delayed_bug(attr.span, "this attribute can only be applied to functions");
None
}
};
@@ -386,7 +386,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
[sym::arm, sym::a32] | [sym::arm, sym::t32] => {
if !tcx.sess.target.has_thumb_interworking {
struct_span_err!(
- tcx.sess.diagnostic(),
+ tcx.sess.dcx(),
attr.span,
E0779,
"target does not support `#[instruction_set]`"
@@ -403,7 +403,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
_ => {
struct_span_err!(
- tcx.sess.diagnostic(),
+ tcx.sess.dcx(),
attr.span,
E0779,
"invalid instruction set specified",
@@ -415,7 +415,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
[] => {
struct_span_err!(
- tcx.sess.diagnostic(),
+ tcx.sess.dcx(),
attr.span,
E0778,
"`#[instruction_set]` requires an argument"
@@ -425,7 +425,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
}
_ => {
struct_span_err!(
- tcx.sess.diagnostic(),
+ tcx.sess.dcx(),
attr.span,
E0779,
"cannot specify more than one instruction set"
@@ -443,7 +443,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
rustc_attr::parse_alignment(&literal.kind)
.map_err(|msg| {
struct_span_err!(
- tcx.sess.diagnostic(),
+ tcx.sess.dcx(),
attr.span,
E0589,
"invalid `repr(align)` attribute: {}",
@@ -469,27 +469,17 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
Some(MetaItemKind::List(ref items)) => {
inline_span = Some(attr.span);
if items.len() != 1 {
- struct_span_err!(
- tcx.sess.diagnostic(),
- attr.span,
- E0534,
- "expected one argument"
- )
- .emit();
+ struct_span_err!(tcx.sess.dcx(), attr.span, E0534, "expected one argument")
+ .emit();
InlineAttr::None
- } else if list_contains_name(&items, sym::always) {
+ } else if list_contains_name(items, sym::always) {
InlineAttr::Always
- } else if list_contains_name(&items, sym::never) {
+ } else if list_contains_name(items, sym::never) {
InlineAttr::Never
} else {
- struct_span_err!(
- tcx.sess.diagnostic(),
- items[0].span(),
- E0535,
- "invalid argument"
- )
- .help("valid inline arguments are `always` and `never`")
- .emit();
+ struct_span_err!(tcx.sess.dcx(), items[0].span(), E0535, "invalid argument")
+ .help("valid inline arguments are `always` and `never`")
+ .emit();
InlineAttr::None
}
@@ -503,7 +493,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
if !attr.has_name(sym::optimize) {
return ia;
}
- let err = |sp, s| struct_span_err!(tcx.sess.diagnostic(), sp, E0722, "{}", s).emit();
+ let err = |sp, s| struct_span_err!(tcx.sess.dcx(), sp, E0722, "{}", s).emit();
match attr.meta_kind() {
Some(MetaItemKind::Word) => {
err(attr.span, "expected one argument");
@@ -514,9 +504,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
if items.len() != 1 {
err(attr.span, "expected one argument");
OptimizeAttr::None
- } else if list_contains_name(&items, sym::size) {
+ } else if list_contains_name(items, sym::size) {
OptimizeAttr::Size
- } else if list_contains_name(&items, sym::speed) {
+ } else if list_contains_name(items, sym::speed) {
OptimizeAttr::Speed
} else {
err(items[0].span(), "invalid argument");
@@ -572,13 +562,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
if !codegen_fn_attrs.no_sanitize.is_empty() {
if codegen_fn_attrs.inline == InlineAttr::Always {
if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
- let hir_id = tcx.hir().local_def_id_to_hir_id(did);
+ let hir_id = tcx.local_def_id_to_hir_id(did);
tcx.struct_span_lint_hir(
lint::builtin::INLINE_NO_SANITIZE,
hir_id,
no_sanitize_span,
"`no_sanitize` will have no effect after inlining",
- |lint| lint.span_note(inline_span, "inlining requested here"),
+ |lint| {
+ lint.span_note(inline_span, "inlining requested here");
+ },
)
}
}
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 1a85eb8dd..dda30046b 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -216,7 +216,7 @@ fn push_debuginfo_type_name<'tcx>(
output.push(']');
}
}
- ty::Dynamic(ref trait_data, ..) => {
+ ty::Dynamic(trait_data, ..) => {
let auto_traits: SmallVec<[DefId; 4]> = trait_data.auto_traits().collect();
let has_enclosing_parens = if cpp_like_debuginfo {
@@ -249,7 +249,7 @@ fn push_debuginfo_type_name<'tcx>(
.projection_bounds()
.map(|bound| {
let ExistentialProjection { def_id: item_def_id, term, .. } =
- tcx.erase_late_bound_regions(bound);
+ tcx.instantiate_bound_regions_with_erased(bound);
// FIXME(associated_const_equality): allow for consts here
(item_def_id, term.ty().unwrap())
})
@@ -566,6 +566,9 @@ fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
Some(CoroutineKind::Async(CoroutineSource::Block)) => "async_block",
Some(CoroutineKind::Async(CoroutineSource::Closure)) => "async_closure",
Some(CoroutineKind::Async(CoroutineSource::Fn)) => "async_fn",
+ Some(CoroutineKind::AsyncGen(CoroutineSource::Block)) => "async_gen_block",
+ Some(CoroutineKind::AsyncGen(CoroutineSource::Closure)) => "async_gen_closure",
+ Some(CoroutineKind::AsyncGen(CoroutineSource::Fn)) => "async_gen_fn",
Some(CoroutineKind::Coroutine) => "coroutine",
None => "closure",
}
@@ -594,7 +597,7 @@ fn push_unqualified_item_name(
DefPathData::CrateRoot => {
output.push_str(tcx.crate_name(def_id.krate).as_str());
}
- DefPathData::ClosureExpr => {
+ DefPathData::Closure => {
let label = coroutine_kind_label(tcx.coroutine_kind(def_id));
push_disambiguated_special_name(
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index ed6ac9f9c..668d39afb 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -4,7 +4,7 @@ use crate::assert_module_sources::CguReuse;
use crate::back::command::Command;
use crate::fluent_generated as fluent;
use rustc_errors::{
- DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic,
+ DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic,
IntoDiagnosticArg,
};
use rustc_macros::Diagnostic;
@@ -210,192 +210,191 @@ pub enum LinkRlibError {
pub struct ThorinErrorWrapper(pub thorin::Error);
impl IntoDiagnostic<'_> for ThorinErrorWrapper {
- fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
+ fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
let mut diag;
match self.0 {
thorin::Error::ReadInput(_) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_read_input_failure);
+ diag = dcx.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 = dcx.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 = dcx.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 = dcx.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 = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_invalid_input_kind);
diag
}
thorin::Error::DecompressData(_) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_decompress_data);
+ diag = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_section_without_name);
diag.set_arg("offset", format!("0x{offset:08x}"));
diag
}
thorin::Error::RelocationWithInvalidSymbol(section, offset) => {
- diag =
- handler.struct_err(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol);
+ diag = dcx.struct_err(fluent::codegen_ssa_thorin_relocation_with_invalid_symbol);
diag.set_arg("section", section);
diag.set_arg("offset", format!("0x{offset:08x}"));
diag
}
thorin::Error::MultipleRelocations(section, offset) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_relocations);
+ diag = dcx.struct_err(fluent::codegen_ssa_thorin_multiple_relocations);
diag.set_arg("section", section);
diag.set_arg("offset", format!("0x{offset:08x}"));
diag
}
thorin::Error::UnsupportedRelocation(section, offset) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_unsupported_relocation);
+ diag = dcx.struct_err(fluent::codegen_ssa_thorin_unsupported_relocation);
diag.set_arg("section", section);
diag.set_arg("offset", format!("0x{offset:08x}"));
diag
}
thorin::Error::MissingDwoName(id) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_dwo_name);
+ diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_dwo_name);
diag.set_arg("id", format!("0x{id:08x}"));
diag
}
thorin::Error::NoCompilationUnits => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_no_compilation_units);
+ diag = dcx.struct_err(fluent::codegen_ssa_thorin_no_compilation_units);
diag
}
thorin::Error::NoDie => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_no_die);
+ diag = dcx.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 = dcx.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 = dcx.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 = dcx.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 = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_parse_unit_header);
diag
}
thorin::Error::ParseUnit(_) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_unit);
+ diag = dcx.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 = dcx.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 = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_str_at_offset);
diag.set_arg("offset", format!("0x{offset:08x}"));
diag
}
thorin::Error::ParseIndex(_, section) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_parse_index);
+ diag = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_unit_not_in_index);
diag.set_arg("unit", format!("0x{unit:08x}"));
diag
}
thorin::Error::RowNotInIndex(_, row) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_row_not_in_index);
+ diag = dcx.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 = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_empty_unit);
diag.set_arg("unit", format!("0x{unit:08x}"));
diag
}
thorin::Error::MultipleDebugInfoSection => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_multiple_debug_info_section);
+ diag = dcx.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 = dcx.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 = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_duplicate_unit);
diag.set_arg("unit", format!("0x{unit:08x}"));
diag
}
thorin::Error::MissingReferencedUnit(unit) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_missing_referenced_unit);
+ diag = dcx.struct_err(fluent::codegen_ssa_thorin_missing_referenced_unit);
diag.set_arg("unit", format!("0x{unit:08x}"));
diag
}
thorin::Error::NoOutputObjectCreated => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_not_output_object_created);
+ diag = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_mixed_input_encodings);
diag
}
thorin::Error::Io(e) => {
- diag = handler.struct_err(fluent::codegen_ssa_thorin_io);
+ diag = dcx.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 = dcx.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 = dcx.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 = dcx.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 = dcx.struct_err(fluent::codegen_ssa_thorin_gimli_write);
diag.set_arg("error", format!("{e}"));
diag
}
@@ -412,8 +411,8 @@ pub struct LinkingFailed<'a> {
}
impl IntoDiagnostic<'_> for LinkingFailed<'_> {
- fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
- let mut diag = handler.struct_err(fluent::codegen_ssa_linking_failed);
+ fn into_diagnostic(self, dcx: &DiagCtxt) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
+ let mut diag = dcx.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));
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 156c2904f..09fe138c6 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -1,7 +1,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
-#![cfg_attr(not(bootstrap), doc(rust_logo))]
-#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
-#![cfg_attr(not(bootstrap), allow(internal_features))]
+#![doc(rust_logo)]
+#![feature(rustdoc_internals)]
+#![allow(internal_features)]
#![feature(associated_type_bounds)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
@@ -27,8 +27,6 @@ extern crate rustc_middle;
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
-use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
-use rustc_fluent_macro::fluent_messages;
use rustc_hir::def_id::CrateNum;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
@@ -53,14 +51,14 @@ pub mod codegen_attrs;
pub mod common;
pub mod debuginfo;
pub mod errors;
-pub mod glue;
pub mod meth;
pub mod mir;
pub mod mono_item;
+pub mod size_of_val;
pub mod target_features;
pub mod traits;
-fluent_messages! { "../messages.ftl" }
+rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub struct ModuleCodegen<M> {
/// The name of the module. When the crate may be saved between
@@ -218,6 +216,7 @@ impl CodegenResults {
sess: &Session,
rlink_file: &Path,
codegen_results: &CodegenResults,
+ outputs: &OutputFilenames,
) -> Result<usize, io::Error> {
let mut encoder = FileEncoder::new(rlink_file)?;
encoder.emit_raw_bytes(RLINK_MAGIC);
@@ -226,10 +225,14 @@ impl CodegenResults {
encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
encoder.emit_str(sess.cfg_version);
Encodable::encode(codegen_results, &mut encoder);
- encoder.finish()
+ Encodable::encode(outputs, &mut encoder);
+ encoder.finish().map_err(|(_path, err)| err)
}
- pub fn deserialize_rlink(sess: &Session, data: Vec<u8>) -> Result<Self, CodegenErrors> {
+ pub fn deserialize_rlink(
+ sess: &Session,
+ data: Vec<u8>,
+ ) -> Result<(Self, OutputFilenames), CodegenErrors> {
// The Decodable machinery is not used here because it panics if the input data is invalid
// and because its internal representation may change.
if !data.starts_with(RLINK_MAGIC) {
@@ -258,6 +261,7 @@ impl CodegenResults {
}
let codegen_results = CodegenResults::decode(&mut decoder);
- Ok(codegen_results)
+ let outputs = OutputFilenames::decode(&mut decoder);
+ Ok((codegen_results, outputs))
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 2285e7f4e..c1de9b76f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -36,13 +36,13 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// Arguments get assigned to by means of the function being called
for arg in mir.args_iter() {
- analyzer.assign(arg, DefLocation::Argument);
+ analyzer.define(arg, DefLocation::Argument);
}
// If there exists a local definition that dominates all uses of that local,
// the definition should be visited first. Traverse blocks in an order that
// is a topological sort of dominance partial order.
- for (bb, data) in traversal::reverse_postorder(&mir) {
+ for (bb, data) in traversal::reverse_postorder(mir) {
analyzer.visit_basic_block_data(bb, data);
}
@@ -74,7 +74,7 @@ struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
}
impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
- fn assign(&mut self, local: mir::Local, location: DefLocation) {
+ fn define(&mut self, local: mir::Local, location: DefLocation) {
let kind = &mut self.locals[local];
match *kind {
LocalKind::ZST => {}
@@ -162,7 +162,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
debug!("visit_assign(place={:?}, rvalue={:?})", place, rvalue);
if let Some(local) = place.as_local() {
- self.assign(local, DefLocation::Body(location));
+ self.define(local, DefLocation::Assignment(location));
if self.locals[local] != LocalKind::Memory {
let decl_span = self.fx.mir.local_decls[local].source_info.span;
if !self.fx.rvalue_creates_operand(rvalue, decl_span) {
@@ -183,9 +183,14 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
fn visit_local(&mut self, local: mir::Local, context: PlaceContext, location: Location) {
match context {
- PlaceContext::MutatingUse(MutatingUseContext::Call)
- | PlaceContext::MutatingUse(MutatingUseContext::Yield) => {
- self.assign(local, DefLocation::Body(location));
+ PlaceContext::MutatingUse(MutatingUseContext::Call) => {
+ let call = location.block;
+ let TerminatorKind::Call { target, .. } =
+ self.fx.mir.basic_blocks[call].terminator().kind
+ else {
+ bug!()
+ };
+ self.define(local, DefLocation::CallReturn { call, target });
}
PlaceContext::NonUse(_)
@@ -197,7 +202,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
) => match &mut self.locals[local] {
LocalKind::ZST => {}
LocalKind::Memory => {}
- LocalKind::SSA(def) if def.dominates(location, &self.dominators) => {}
+ LocalKind::SSA(def) if def.dominates(location, self.dominators) => {}
// Reads from uninitialized variables (e.g., in dead code, after
// optimizations) require locals to be in (uninitialized) memory.
// N.B., there can be uninitialized reads of a local visited after
@@ -237,6 +242,8 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
}
}
}
+
+ PlaceContext::MutatingUse(MutatingUseContext::Yield) => bug!(),
}
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 3d2d8f8b5..a1662f25e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -47,7 +47,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
&self,
fx: &'b mut FunctionCx<'a, 'tcx, Bx>,
) -> Option<&'b Bx::Funclet> {
- let cleanup_kinds = (&fx.cleanup_kinds).as_ref()?;
+ let cleanup_kinds = fx.cleanup_kinds.as_ref()?;
let funclet_bb = cleanup_kinds[self.bb].funclet_bb(self.bb)?;
// If `landing_pad_for` hasn't been called yet to create the `Funclet`,
// it has to be now. This may not seem necessary, as RPO should lead
@@ -161,7 +161,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
) -> MergingSucc {
// If there is a cleanup block and the function we're calling can unwind, then
// do an invoke, otherwise do a call.
- let fn_ty = bx.fn_decl_backend_type(&fn_abi);
+ let fn_ty = bx.fn_decl_backend_type(fn_abi);
let fn_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() {
Some(bx.tcx().codegen_fn_attrs(fx.instance.def_id()))
@@ -204,9 +204,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
let invokeret = bx.invoke(
fn_ty,
fn_attrs,
- Some(&fn_abi),
+ Some(fn_abi),
fn_ptr,
- &llargs,
+ llargs,
ret_llbb,
unwind_block,
self.funclet(fx),
@@ -225,7 +225,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
}
MergingSucc::False
} else {
- let llret = bx.call(fn_ty, fn_attrs, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx));
+ let llret = bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, llargs, self.funclet(fx));
if fx.mir[self.bb].is_cleanup {
bx.apply_attrs_to_cleanup_callsite(llret);
}
@@ -273,7 +273,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
bx.codegen_inline_asm(
template,
- &operands,
+ operands,
options,
line_spans,
instance,
@@ -281,7 +281,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
);
MergingSucc::False
} else {
- bx.codegen_inline_asm(template, &operands, options, line_spans, instance, None);
+ bx.codegen_inline_asm(template, operands, options, line_spans, instance, None);
if let Some(target) = destination {
self.funclet_br(fx, bx, target, mergeable_succ)
@@ -318,7 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
discr: &mir::Operand<'tcx>,
targets: &SwitchTargets,
) {
- let discr = self.codegen_operand(bx, &discr);
+ let discr = self.codegen_operand(bx, discr);
let switch_ty = discr.layout.ty;
let mut target_iter = targets.iter();
if target_iter.len() == 1 {
@@ -498,7 +498,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
args = &args[..1];
(
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
- .get_fn(bx, vtable, ty, &fn_abi),
+ .get_fn(bx, vtable, ty, fn_abi),
fn_abi,
)
}
@@ -540,7 +540,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
debug!("args' = {:?}", args);
(
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
- .get_fn(bx, meta.immediate(), ty, &fn_abi),
+ .get_fn(bx, meta.immediate(), ty, fn_abi),
fn_abi,
)
}
@@ -864,7 +864,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// promotes any complex rvalues to constants.
if i == 2 && intrinsic == sym::simd_shuffle {
if let mir::Operand::Constant(constant) = arg {
- let (llval, ty) = self.simd_shuffle_indices(&bx, constant);
+ let (llval, ty) = self.simd_shuffle_indices(bx, constant);
return OperandRef {
val: Immediate(llval),
layout: bx.layout_of(ty),
@@ -881,7 +881,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
Self::codegen_intrinsic_call(
bx,
*instance.as_ref().unwrap(),
- &fn_abi,
+ fn_abi,
&args,
dest,
span,
@@ -937,7 +937,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx,
meta,
op.layout.ty,
- &fn_abi,
+ fn_abi,
));
llargs.push(data_ptr);
continue 'make_args;
@@ -948,7 +948,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx,
meta,
op.layout.ty,
- &fn_abi,
+ fn_abi,
));
llargs.push(data_ptr);
continue;
@@ -975,7 +975,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bx,
meta.immediate(),
op.layout.ty,
- &fn_abi,
+ fn_abi,
));
llargs.push(data_ptr.llval);
continue;
@@ -1587,9 +1587,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, reason.lang_item());
- let fn_ty = bx.fn_decl_backend_type(&fn_abi);
+ let fn_ty = bx.fn_decl_backend_type(fn_abi);
- let llret = bx.call(fn_ty, None, Some(&fn_abi), fn_ptr, &[], funclet.as_ref());
+ let llret = bx.call(fn_ty, None, Some(fn_abi), fn_ptr, &[], funclet.as_ref());
bx.apply_attrs_to_cleanup_callsite(llret);
bx.unreachable();
@@ -1662,10 +1662,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
} else {
- self.codegen_place(
- bx,
- mir::PlaceRef { local: dest.local, projection: &dest.projection },
- )
+ self.codegen_place(bx, mir::PlaceRef { local: dest.local, projection: dest.projection })
};
if fn_ret.is_indirect() {
if dest.align < dest.layout.align.abi {
@@ -1696,7 +1693,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
match dest {
Nothing => (),
- Store(dst) => bx.store_arg(&ret_abi, llval, dst),
+ Store(dst) => bx.store_arg(ret_abi, llval, dst),
IndirectOperand(tmp, index) => {
let op = bx.load_operand(tmp);
tmp.storage_dead(bx);
@@ -1708,7 +1705,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let op = if let PassMode::Cast { .. } = ret_abi.mode {
let tmp = PlaceRef::alloca(bx, ret_abi.layout);
tmp.storage_live(bx);
- bx.store_arg(&ret_abi, llval, tmp);
+ bx.store_arg(ret_abi, llval, tmp);
let op = bx.load_operand(tmp);
tmp.storage_dead(bx);
op
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 0dc30d21c..14915e816 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -398,7 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
- calculate_debuginfo_offset(bx, &var.projection, base.layout);
+ calculate_debuginfo_offset(bx, var.projection, base.layout);
// When targeting MSVC, create extra allocas for arguments instead of pointing multiple
// dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
@@ -416,7 +416,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if should_create_individual_allocas {
let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
- calculate_debuginfo_offset(bx, &var.projection, base);
+ calculate_debuginfo_offset(bx, var.projection, base);
// Create a variable which will be a pointer to the actual value
let ptr_ty = Ty::new_ptr(
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 136d06d56..a5bffc33d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -4,8 +4,8 @@ use super::FunctionCx;
use crate::common::IntPredicate;
use crate::errors;
use crate::errors::InvalidMonomorphization;
-use crate::glue;
use crate::meth;
+use crate::size_of_val;
use crate::traits::*;
use crate::MemFlags;
@@ -88,21 +88,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
sym::va_end => bx.va_end(args[0].immediate()),
sym::size_of_val => {
let tp_ty = fn_args.type_at(0);
- if let OperandValue::Pair(_, meta) = args[0].val {
- let (llsize, _) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
- llsize
- } else {
- bx.const_usize(bx.layout_of(tp_ty).size.bytes())
- }
+ let meta =
+ if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
+ let (llsize, _) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
+ llsize
}
sym::min_align_of_val => {
let tp_ty = fn_args.type_at(0);
- if let OperandValue::Pair(_, meta) = args[0].val {
- let (_, llalign) = glue::size_and_align_of_dst(bx, tp_ty, Some(meta));
- llalign
- } else {
- bx.const_usize(bx.layout_of(tp_ty).align.abi.bytes())
- }
+ let meta =
+ if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None };
+ let (_, llalign) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta);
+ llalign
}
sym::vtable_size | sym::vtable_align => {
let vtable = args[0].immediate();
diff --git a/compiler/rustc_codegen_ssa/src/mir/locals.rs b/compiler/rustc_codegen_ssa/src/mir/locals.rs
index 378c54013..7db260c9f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/locals.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/locals.rs
@@ -43,7 +43,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let local = mir::Local::from_usize(local);
let expected_ty = self.monomorphize(self.mir.local_decls[local].ty);
if expected_ty != op.layout.ty {
- warn!("Unexpected initial operand type. See the issues/114858");
+ warn!(
+ "Unexpected initial operand type: expected {expected_ty:?}, found {:?}.\
+ See <https://github.com/rust-lang/rust/issues/114858>.",
+ op.layout.ty
+ );
}
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index d0b799e08..a6fcf1fd3 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -168,7 +168,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty());
debug!("fn_abi: {:?}", fn_abi);
- let debug_context = cx.create_function_debug_context(instance, &fn_abi, llfn, &mir);
+ let debug_context = cx.create_function_debug_context(instance, fn_abi, llfn, mir);
let start_llbb = Bx::append_block(cx, llfn, "start");
let mut start_bx = Bx::build(cx, start_llbb);
@@ -180,7 +180,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
let cleanup_kinds =
- base::wants_new_eh_instructions(cx.tcx().sess).then(|| analyze::cleanup_kinds(&mir));
+ base::wants_new_eh_instructions(cx.tcx().sess).then(|| analyze::cleanup_kinds(mir));
let cached_llbbs: IndexVec<mir::BasicBlock, CachedLlbb<Bx::BasicBlock>> =
mir.basic_blocks
@@ -261,7 +261,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
drop(start_bx);
// Codegen the body of each block using reverse postorder
- for (bb, _) in traversal::reverse_postorder(&mir) {
+ for (bb, _) in traversal::reverse_postorder(mir) {
fx.codegen_block(bb);
}
}
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 0ab2b7ecd..794cbd315 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -2,7 +2,7 @@ use super::place::PlaceRef;
use super::{FunctionCx, LocalRef};
use crate::base;
-use crate::glue;
+use crate::size_of_val;
use crate::traits::*;
use crate::MemFlags;
@@ -105,7 +105,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
bug!("from_const: invalid ScalarPair layout: {:#?}", layout);
};
let a = Scalar::from_pointer(
- Pointer::new(bx.tcx().reserve_and_set_memory_alloc(data), Size::ZERO),
+ Pointer::new(bx.tcx().reserve_and_set_memory_alloc(data).into(), Size::ZERO),
&bx.tcx(),
);
let a_llval = bx.scalar_to_backend(
@@ -132,7 +132,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
offset: Size,
) -> Self {
let alloc_align = alloc.inner().align;
- assert_eq!(alloc_align, layout.align.abi);
+ assert!(alloc_align >= layout.align.abi);
let read_scalar = |start, size, s: abi::Scalar, ty| {
match alloc.0.read_scalar(
@@ -155,7 +155,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
Abi::Scalar(s @ abi::Scalar::Initialized { .. }) => {
let size = s.size(bx);
assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
- let val = read_scalar(offset, size, s, bx.backend_type(layout));
+ let val = read_scalar(offset, size, s, bx.immediate_backend_type(layout));
OperandRef { val: OperandValue::Immediate(val), layout }
}
Abi::ScalarPair(
@@ -414,6 +414,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
// value is through `undef`/`poison`, and the store itself is useless.
}
OperandValue::Ref(r, None, source_align) => {
+ assert!(dest.layout.is_sized(), "cannot directly store unsized values");
if flags.contains(MemFlags::NONTEMPORAL) {
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
let ty = bx.backend_type(dest.layout);
@@ -465,13 +466,13 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
.ty;
let OperandValue::Ref(llptr, Some(llextra), _) = self else {
- bug!("store_unsized called with a sized value")
+ bug!("store_unsized called with a sized value (or with an extern type)")
};
// Allocate an appropriate region on the stack, and copy the value into it. Since alloca
// doesn't support dynamic alignment, we allocate an extra align - 1 bytes, and align the
// pointer manually.
- let (size, align) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
+ let (size, align) = size_of_val::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
let one = bx.const_usize(1);
let align_minus_1 = bx.sub(align, one);
let size_extra = bx.add(size, align_minus_1);
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index eb590a45a..c0bb3ac56 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -2,7 +2,7 @@ use super::operand::OperandValue;
use super::{FunctionCx, LocalRef};
use crate::common::IntPredicate;
-use crate::glue;
+use crate::size_of_val;
use crate::traits::*;
use rustc_middle::mir;
@@ -99,6 +99,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
let offset = self.layout.fields.offset(ix);
let effective_field_align = self.align.restrict_for_offset(offset);
+ // `simple` is called when we don't need to adjust the offset to
+ // the dynamic alignment of the field.
let mut simple = || {
let llval = match self.layout.abi {
_ if offset.bytes() == 0 => {
@@ -141,35 +143,21 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
};
// Simple cases, which don't need DST adjustment:
- // * no metadata available - just log the case
- // * known alignment - sized types, `[T]`, `str` or a foreign type
- // * packed struct - there is no alignment padding
+ // * known alignment - sized types, `[T]`, `str`
+ // * offset 0 -- rounding up to alignment cannot change the offset
+ // Note that looking at `field.align` is incorrect since that is not necessarily equal
+ // to the dynamic alignment of the type.
match field.ty.kind() {
- _ if self.llextra.is_none() => {
- debug!(
- "unsized field `{}`, of `{:?}` has no metadata for adjustment",
- ix, self.llval
- );
- return simple();
- }
_ if field.is_sized() => return simple(),
- ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(),
- ty::Adt(def, _) => {
- if def.repr().packed() {
- // FIXME(eddyb) generalize the adjustment when we
- // start supporting packing to larger alignments.
- assert_eq!(self.layout.align.abi.bytes(), 1);
- return simple();
- }
- }
+ ty::Slice(..) | ty::Str => return simple(),
+ _ if offset.bytes() == 0 => return simple(),
_ => {}
}
// We need to get the pointer manually now.
// We do this by casting to a `*i8`, then offsetting it by the appropriate amount.
// We do this instead of, say, simply adjusting the pointer from the result of a GEP
- // because the field may have an arbitrary alignment in the LLVM representation
- // anyway.
+ // because the field may have an arbitrary alignment in the LLVM representation.
//
// To demonstrate:
//
@@ -186,7 +174,16 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
let unaligned_offset = bx.cx().const_usize(offset.bytes());
// Get the alignment of the field
- let (_, unsized_align) = glue::size_and_align_of_dst(bx, field.ty, meta);
+ let (_, mut unsized_align) = size_of_val::size_and_align_of_dst(bx, field.ty, meta);
+
+ // For packed types, we need to cap alignment.
+ if let ty::Adt(def, _) = self.layout.ty.kind()
+ && let Some(packed) = def.repr().pack
+ {
+ let packed = bx.const_usize(packed.bytes());
+ let cmp = bx.icmp(IntPredicate::IntULT, unsized_align, packed);
+ unsized_align = bx.select(cmp, unsized_align, packed)
+ }
// Bump the unaligned offset up to the appropriate alignment
let offset = round_up_const_value_to_alignment(bx, unaligned_offset, unsized_align);
@@ -474,27 +471,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
cg_base.project_index(bx, llindex)
}
mir::ProjectionElem::ConstantIndex { offset, from_end: false, min_length: _ } => {
- let lloffset = bx.cx().const_usize(offset as u64);
+ let lloffset = bx.cx().const_usize(offset);
cg_base.project_index(bx, lloffset)
}
mir::ProjectionElem::ConstantIndex { offset, from_end: true, min_length: _ } => {
- let lloffset = bx.cx().const_usize(offset as u64);
+ let lloffset = bx.cx().const_usize(offset);
let lllen = cg_base.len(bx.cx());
let llindex = bx.sub(lllen, lloffset);
cg_base.project_index(bx, llindex)
}
mir::ProjectionElem::Subslice { from, to, from_end } => {
- let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from as u64));
+ let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from));
let projected_ty =
PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, *elem).ty;
subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
if subslice.layout.is_unsized() {
assert!(from_end, "slice subslices should be `from_end`");
- subslice.llextra = Some(bx.sub(
- cg_base.llextra.unwrap(),
- bx.cx().const_usize((from as u64) + (to as u64)),
- ));
+ subslice.llextra =
+ Some(bx.sub(cg_base.llextra.unwrap(), bx.cx().const_usize(from + to)));
}
subslice
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 8e5019967..02b51dfe5 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -702,7 +702,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
};
let fn_ptr = bx.get_fn_addr(instance);
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
- let fn_ty = bx.fn_decl_backend_type(&fn_abi);
+ let fn_ty = bx.fn_decl_backend_type(fn_abi);
let fn_attrs = if bx.tcx().def_kind(instance.def_id()).has_codegen_attrs() {
Some(bx.tcx().codegen_fn_attrs(instance.def_id()))
} else {
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index 899e41265..a158fc6e2 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -3,7 +3,6 @@ use rustc_middle::mir::NonDivergingIntrinsic;
use super::FunctionCx;
use super::LocalRef;
-use crate::traits::BuilderMethods;
use crate::traits::*;
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index 6fbf992ed..295e27691 100644
--- a/compiler/rustc_codegen_ssa/src/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -34,7 +34,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
}
MonoItem::GlobalAsm(item_id) => {
let item = cx.tcx().hir().item(item_id);
- if let hir::ItemKind::GlobalAsm(ref asm) = item.kind {
+ if let hir::ItemKind::GlobalAsm(asm) = item.kind {
let operands: Vec<_> = asm
.operands
.iter()
@@ -88,7 +88,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
}
}
MonoItem::Fn(instance) => {
- base::codegen_instance::<Bx>(&cx, instance);
+ base::codegen_instance::<Bx>(cx, instance);
}
}
@@ -119,10 +119,10 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
match *self {
MonoItem::Static(def_id) => {
- cx.predefine_static(def_id, linkage, visibility, &symbol_name);
+ cx.predefine_static(def_id, linkage, visibility, symbol_name);
}
MonoItem::Fn(instance) => {
- cx.predefine_fn(instance, linkage, visibility, &symbol_name);
+ cx.predefine_fn(instance, linkage, visibility, symbol_name);
}
MonoItem::GlobalAsm(..) => {}
}
diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index c34f1dbf8..087836ca3 100644
--- a/compiler/rustc_codegen_ssa/src/glue.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -1,10 +1,11 @@
-//!
-//
-// Code relating to drop glue.
+//! Computing the size and alignment of a value.
+use crate::common;
use crate::common::IntPredicate;
use crate::meth;
use crate::traits::*;
+use rustc_hir::LangItem;
+use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Ty};
use rustc_target::abi::WrappingRange;
@@ -14,7 +15,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
info: Option<Bx::Value>,
) -> (Bx::Value, Bx::Value) {
let layout = bx.layout_of(t);
- debug!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout);
+ trace!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout);
if layout.is_sized() {
let size = bx.const_usize(layout.size.bytes());
let align = bx.const_usize(layout.align.abi.bytes());
@@ -51,7 +52,31 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx.const_usize(unit.align.abi.bytes()),
)
}
- _ => {
+ ty::Foreign(_) => {
+ // `extern` type. We cannot compute the size, so panic.
+ let msg_str = with_no_visible_paths!({
+ with_no_trimmed_paths!({
+ format!("attempted to compute the size or alignment of extern type `{t}`")
+ })
+ });
+ let msg = bx.const_str(&msg_str);
+
+ // Obtain the panic entry point.
+ let (fn_abi, llfn) = common::build_langcall(bx, None, LangItem::PanicNounwind);
+
+ // Generate the call.
+ // Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`.
+ // (But we are in good company, this code is duplicated plenty of times.)
+ let fn_ty = bx.fn_decl_backend_type(fn_abi);
+
+ bx.call(fn_ty, /* fn_attrs */ None, Some(fn_abi), llfn, &[msg.0, msg.1], None);
+
+ // This function does not return so we can now return whatever we want.
+ let size = bx.const_usize(layout.size.bytes());
+ let align = bx.const_usize(layout.align.abi.bytes());
+ (size, align)
+ }
+ ty::Adt(..) | ty::Tuple(..) => {
// First get the size of all statically known fields.
// Don't use size_of because it also rounds up to alignment, which we
// want to avoid, as the unsized field's alignment could be smaller.
@@ -59,10 +84,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
debug!("DST {} layout: {:?}", t, layout);
let i = layout.fields.count() - 1;
- let sized_size = layout.fields.offset(i).bytes();
+ let unsized_offset_unadjusted = layout.fields.offset(i).bytes();
let sized_align = layout.align.abi.bytes();
- debug!("DST {} statically sized prefix size: {} align: {}", t, sized_size, sized_align);
- let sized_size = bx.const_usize(sized_size);
+ debug!(
+ "DST {} offset of dyn field: {}, statically sized align: {}",
+ t, unsized_offset_unadjusted, sized_align
+ );
+ let unsized_offset_unadjusted = bx.const_usize(unsized_offset_unadjusted);
let sized_align = bx.const_usize(sized_align);
// Recurse to get the size of the dynamically sized field (must be
@@ -70,26 +98,26 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let field_ty = layout.field(bx, i).ty;
let (unsized_size, mut unsized_align) = size_and_align_of_dst(bx, field_ty, info);
- // FIXME (#26403, #27023): We should be adding padding
- // to `sized_size` (to accommodate the `unsized_align`
- // required of the unsized field that follows) before
- // summing it with `sized_size`. (Note that since #26403
- // is unfixed, we do not yet add the necessary padding
- // here. But this is where the add would go.)
+ // # First compute the dynamic alignment
- // Return the sum of sizes and max of aligns.
- let size = bx.add(sized_size, unsized_size);
-
- // Packed types ignore the alignment of their fields.
- if let ty::Adt(def, _) = t.kind() {
- if def.repr().packed() {
- unsized_align = sized_align;
+ // For packed types, we need to cap the alignment.
+ if let ty::Adt(def, _) = t.kind()
+ && let Some(packed) = def.repr().pack
+ {
+ if packed.bytes() == 1 {
+ // We know this will be capped to 1.
+ unsized_align = bx.const_usize(1);
+ } else {
+ // We have to dynamically compute `min(unsized_align, packed)`.
+ let packed = bx.const_usize(packed.bytes());
+ let cmp = bx.icmp(IntPredicate::IntULT, unsized_align, packed);
+ unsized_align = bx.select(cmp, unsized_align, packed);
}
}
// Choose max of two known alignments (combined value must
// be aligned according to more restrictive of the two).
- let align = match (
+ let full_align = match (
bx.const_to_opt_u128(sized_align, false),
bx.const_to_opt_u128(unsized_align, false),
) {
@@ -104,6 +132,19 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
};
+ // # Then compute the dynamic size
+
+ // The full formula for the size would be:
+ // let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align);
+ // let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align);
+ // However, `unsized_size` is a multiple of `unsized_align`.
+ // Therefore, we can equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`:
+ // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(unsized_align).align_to(full_align);
+ // Furthermore, `align >= unsized_align`, and therefore we only need to do:
+ // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(full_align);
+
+ let full_size = bx.add(unsized_offset_unadjusted, unsized_size);
+
// Issue #27023: must add any necessary padding to `size`
// (to make it a multiple of `align`) before returning it.
//
@@ -115,12 +156,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
//
// `(size + (align-1)) & -align`
let one = bx.const_usize(1);
- let addend = bx.sub(align, one);
- let add = bx.add(size, addend);
- let neg = bx.neg(align);
- let size = bx.and(add, neg);
+ let addend = bx.sub(full_align, one);
+ let add = bx.add(full_size, addend);
+ let neg = bx.neg(full_align);
+ let full_size = bx.and(add, neg);
- (size, align)
+ (full_size, full_align)
}
+ _ => bug!("size_and_align_of_dst: {t} not supported"),
}
}
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 2936f1de3..0b9b08c6a 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -11,403 +11,10 @@ use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::parse::feature_err;
-use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::symbol::Symbol;
use rustc_span::Span;
-/// Features that control behaviour of rustc, rather than the codegen.
-pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
-
-// When adding features to the below lists
-// check whether they're named already elsewhere in rust
-// e.g. in stdarch and whether the given name matches LLVM's
-// if it doesn't, to_llvm_feature in llvm_util in rustc_codegen_llvm needs to be adapted
-//
-// When adding a new feature, be particularly mindful of features that affect function ABIs. Those
-// need to be treated very carefully to avoid introducing unsoundness! This often affects features
-// that enable/disable hardfloat support (see https://github.com/rust-lang/rust/issues/116344 for an
-// example of this going wrong), but features enabling new SIMD registers are also a concern (see
-// https://github.com/rust-lang/rust/issues/116558 for an example of this going wrong).
-//
-// Stabilizing a target feature (setting the 2nd component of the pair to `None`) requires t-lang
-// approval.
-
-const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- // tidy-alphabetical-start
- ("aclass", Some(sym::arm_target_feature)),
- ("aes", Some(sym::arm_target_feature)),
- ("crc", 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)),
- ("trustzone", Some(sym::arm_target_feature)),
- ("v5te", Some(sym::arm_target_feature)),
- ("v6", Some(sym::arm_target_feature)),
- ("v6k", Some(sym::arm_target_feature)),
- ("v6t2", Some(sym::arm_target_feature)),
- ("v7", Some(sym::arm_target_feature)),
- ("v8", Some(sym::arm_target_feature)),
- ("vfp2", Some(sym::arm_target_feature)),
- ("vfp3", Some(sym::arm_target_feature)),
- ("vfp4", Some(sym::arm_target_feature)),
- ("virtualization", Some(sym::arm_target_feature)),
- // tidy-alphabetical-end
-];
-
-const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- // tidy-alphabetical-start
- // FEAT_AES
- ("aes", None),
- // FEAT_BF16
- ("bf16", None),
- // FEAT_BTI
- ("bti", None),
- // FEAT_CRC
- ("crc", None),
- // FEAT_DIT
- ("dit", None),
- // FEAT_DotProd
- ("dotprod", None),
- // FEAT_DPB
- ("dpb", None),
- // FEAT_DPB2
- ("dpb2", None),
- // FEAT_F32MM
- ("f32mm", None),
- // FEAT_F64MM
- ("f64mm", None),
- // FEAT_FCMA
- ("fcma", 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_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)),
- ("v8.4a", Some(sym::aarch64_ver_target_feature)),
- ("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]] = &[
- &["paca", "pacg"], // Together these represent `pauth` in LLVM
-];
-
-const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- // tidy-alphabetical-start
- ("adx", None),
- ("aes", None),
- ("avx", None),
- ("avx2", None),
- ("avx512bf16", Some(sym::avx512_target_feature)),
- ("avx512bitalg", Some(sym::avx512_target_feature)),
- ("avx512bw", Some(sym::avx512_target_feature)),
- ("avx512cd", Some(sym::avx512_target_feature)),
- ("avx512dq", Some(sym::avx512_target_feature)),
- ("avx512er", Some(sym::avx512_target_feature)),
- ("avx512f", Some(sym::avx512_target_feature)),
- ("avx512ifma", Some(sym::avx512_target_feature)),
- ("avx512pf", Some(sym::avx512_target_feature)),
- ("avx512vbmi", Some(sym::avx512_target_feature)),
- ("avx512vbmi2", Some(sym::avx512_target_feature)),
- ("avx512vl", Some(sym::avx512_target_feature)),
- ("avx512vnni", Some(sym::avx512_target_feature)),
- ("avx512vp2intersect", Some(sym::avx512_target_feature)),
- ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
- ("bmi1", None),
- ("bmi2", None),
- ("cmpxchg16b", None),
- ("ermsb", Some(sym::ermsb_target_feature)),
- ("f16c", None),
- ("fma", None),
- ("fxsr", None),
- ("gfni", Some(sym::avx512_target_feature)),
- ("lzcnt", None),
- ("movbe", None),
- ("pclmulqdq", None),
- ("popcnt", None),
- ("rdrand", None),
- ("rdseed", None),
- ("rtm", Some(sym::rtm_target_feature)),
- ("sha", None),
- ("sse", None),
- ("sse2", None),
- ("sse3", None),
- ("sse4.1", None),
- ("sse4.2", None),
- ("sse4a", Some(sym::sse4a_target_feature)),
- ("ssse3", None),
- ("tbm", Some(sym::tbm_target_feature)),
- ("vaes", Some(sym::avx512_target_feature)),
- ("vpclmulqdq", Some(sym::avx512_target_feature)),
- ("xsave", None),
- ("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)),
- ("power10-vector", Some(sym::powerpc_target_feature)),
- ("power8-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>)] = &[
- // tidy-alphabetical-start
- ("a", None),
- ("c", None),
- ("d", Some(sym::riscv_target_feature)),
- ("e", Some(sym::riscv_target_feature)),
- ("f", Some(sym::riscv_target_feature)),
- ("m", None),
- ("relax", Some(sym::riscv_target_feature)),
- ("unaligned-scalar-mem", Some(sym::riscv_target_feature)),
- ("v", Some(sym::riscv_target_feature)),
- ("zba", None),
- ("zbb", None),
- ("zbc", None),
- ("zbkb", None),
- ("zbkc", None),
- ("zbkx", None),
- ("zbs", None),
- ("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", None),
- ("zkn", None),
- ("zknd", None),
- ("zkne", None),
- ("zknh", None),
- ("zkr", None),
- ("zks", None),
- ("zksed", None),
- ("zksh", None),
- ("zkt", None),
- // tidy-alphabetical-end
-];
-
-const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- // tidy-alphabetical-start
- ("atomics", Some(sym::wasm_target_feature)),
- ("bulk-memory", Some(sym::wasm_target_feature)),
- ("exception-handling", Some(sym::wasm_target_feature)),
- ("multivalue", 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)),
- ("relaxed-simd", 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))];
-
-const CSKY_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- // tidy-alphabetical-start
- ("10e60", Some(sym::csky_target_feature)),
- ("2e3", Some(sym::csky_target_feature)),
- ("3e3r1", Some(sym::csky_target_feature)),
- ("3e3r2", Some(sym::csky_target_feature)),
- ("3e3r3", Some(sym::csky_target_feature)),
- ("3e7", Some(sym::csky_target_feature)),
- ("7e10", Some(sym::csky_target_feature)),
- ("cache", Some(sym::csky_target_feature)),
- ("doloop", Some(sym::csky_target_feature)),
- ("dsp1e2", Some(sym::csky_target_feature)),
- ("dspe60", Some(sym::csky_target_feature)),
- ("e1", Some(sym::csky_target_feature)),
- ("e2", Some(sym::csky_target_feature)),
- ("edsp", Some(sym::csky_target_feature)),
- ("elrw", Some(sym::csky_target_feature)),
- ("float1e2", Some(sym::csky_target_feature)),
- ("float1e3", Some(sym::csky_target_feature)),
- ("float3e4", Some(sym::csky_target_feature)),
- ("float7e60", Some(sym::csky_target_feature)),
- ("floate1", Some(sym::csky_target_feature)),
- ("hard-tp", Some(sym::csky_target_feature)),
- ("high-registers", Some(sym::csky_target_feature)),
- ("hwdiv", Some(sym::csky_target_feature)),
- ("mp", Some(sym::csky_target_feature)),
- ("mp1e2", Some(sym::csky_target_feature)),
- ("nvic", Some(sym::csky_target_feature)),
- ("trust", Some(sym::csky_target_feature)),
- ("vdsp2e60f", Some(sym::csky_target_feature)),
- ("vdspv1", Some(sym::csky_target_feature)),
- ("vdspv2", Some(sym::csky_target_feature)),
- // tidy-alphabetical-end
- //fpu
- // tidy-alphabetical-start
- ("fdivdu", Some(sym::csky_target_feature)),
- ("fpuv2_df", Some(sym::csky_target_feature)),
- ("fpuv2_sf", Some(sym::csky_target_feature)),
- ("fpuv3_df", Some(sym::csky_target_feature)),
- ("fpuv3_hf", Some(sym::csky_target_feature)),
- ("fpuv3_hi", Some(sym::csky_target_feature)),
- ("fpuv3_sf", Some(sym::csky_target_feature)),
- ("hard-float", Some(sym::csky_target_feature)),
- ("hard-float-abi", Some(sym::csky_target_feature)),
- // tidy-alphabetical-end
-];
-
-const LOONGARCH_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
- // tidy-alphabetical-start
- ("d", Some(sym::loongarch_target_feature)),
- ("f", Some(sym::loongarch_target_feature)),
- ("lasx", Some(sym::loongarch_target_feature)),
- ("lbt", Some(sym::loongarch_target_feature)),
- ("lsx", Some(sym::loongarch_target_feature)),
- ("lvz", Some(sym::loongarch_target_feature)),
- ("ual", Some(sym::loongarch_target_feature)),
- // tidy-alphabetical-end
-];
-
-/// When rustdoc is running, provide a list of all known features so that all their respective
-/// primitives may be documented.
-///
-/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
-pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol>)> {
- std::iter::empty()
- .chain(ARM_ALLOWED_FEATURES.iter())
- .chain(AARCH64_ALLOWED_FEATURES.iter())
- .chain(X86_ALLOWED_FEATURES.iter())
- .chain(HEXAGON_ALLOWED_FEATURES.iter())
- .chain(POWERPC_ALLOWED_FEATURES.iter())
- .chain(MIPS_ALLOWED_FEATURES.iter())
- .chain(RISCV_ALLOWED_FEATURES.iter())
- .chain(WASM_ALLOWED_FEATURES.iter())
- .chain(BPF_ALLOWED_FEATURES.iter())
- .chain(CSKY_ALLOWED_FEATURES)
- .chain(LOONGARCH_ALLOWED_FEATURES)
- .cloned()
-}
-
-pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Option<Symbol>)] {
- match &*sess.target.arch {
- "arm" => ARM_ALLOWED_FEATURES,
- "aarch64" => AARCH64_ALLOWED_FEATURES,
- "x86" | "x86_64" => X86_ALLOWED_FEATURES,
- "hexagon" => HEXAGON_ALLOWED_FEATURES,
- "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES,
- "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
- "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
- "wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
- "bpf" => BPF_ALLOWED_FEATURES,
- "csky" => CSKY_ALLOWED_FEATURES,
- "loongarch64" => LOONGARCH_ALLOWED_FEATURES,
- _ => &[],
- }
-}
-
-pub fn tied_target_features(sess: &Session) -> &'static [&'static [&'static str]] {
- match &*sess.target.arch {
- "aarch64" => AARCH64_TIED_FEATURES,
- _ => &[],
- }
-}
-
pub fn from_target_feature(
tcx: TyCtxt<'_>,
attr: &ast::Attribute,
@@ -529,11 +136,15 @@ pub(crate) fn provide(providers: &mut Providers) {
if tcx.sess.opts.actually_rustdoc {
// rustdoc needs to be able to document functions that use all the features, so
// whitelist them all
- all_known_features().map(|(a, b)| (a.to_string(), b)).collect()
+ rustc_target::target_features::all_known_features()
+ .map(|(a, b)| (a.to_string(), b.as_feature_name()))
+ .collect()
} else {
- supported_target_features(tcx.sess)
+ tcx.sess
+ .target
+ .supported_target_features()
.iter()
- .map(|&(a, b)| (a.to_string(), b))
+ .map(|&(a, b)| (a.to_string(), b.as_feature_name()))
.collect()
}
},
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index 35744d9a1..8e9907ed8 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -9,6 +9,7 @@ use rustc_ast::expand::allocator::AllocatorKind;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::{DynSend, DynSync};
use rustc_errors::ErrorGuaranteed;
+use rustc_metadata::creader::MetadataLoaderDyn;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
@@ -16,7 +17,6 @@ use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::util::Providers;
use rustc_session::{
config::{self, OutputFilenames, PrintRequest},
- cstore::MetadataLoaderDyn,
Session,
};
use rustc_span::symbol::Symbol;
diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs
index ecf5095d8..048540894 100644
--- a/compiler/rustc_codegen_ssa/src/traits/write.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/write.rs
@@ -2,7 +2,7 @@ use crate::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
use crate::back::write::{CodegenContext, FatLtoInput, ModuleConfig};
use crate::{CompiledModule, ModuleCodegen};
-use rustc_errors::{FatalError, Handler};
+use rustc_errors::{DiagCtxt, FatalError};
use rustc_middle::dep_graph::WorkProduct;
pub trait WriteBackendMethods: 'static + Sized + Clone {
@@ -16,7 +16,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
/// Merge all modules into main_module and returning it
fn run_link(
cgcx: &CodegenContext<Self>,
- diag_handler: &Handler,
+ dcx: &DiagCtxt,
modules: Vec<ModuleCodegen<Self::Module>>,
) -> Result<ModuleCodegen<Self::Module>, FatalError>;
/// Performs fat LTO by merging all modules into a single one and returning it
@@ -38,7 +38,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
fn print_statistics(&self);
unsafe fn optimize(
cgcx: &CodegenContext<Self>,
- diag_handler: &Handler,
+ dcx: &DiagCtxt,
module: &ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<(), FatalError>;
@@ -52,7 +52,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
) -> Result<ModuleCodegen<Self::Module>, FatalError>;
unsafe fn codegen(
cgcx: &CodegenContext<Self>,
- diag_handler: &Handler,
+ dcx: &DiagCtxt,
module: ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<CompiledModule, FatalError>;