diff options
| author | Laurențiu Nicola <lnicola@dend.ro> | 2024-10-08 14:25:39 +0300 |
|---|---|---|
| committer | Laurențiu Nicola <lnicola@dend.ro> | 2024-10-08 14:25:39 +0300 |
| commit | 4316afffd9390bdac1d3bd5e5398c65d6e9bb150 (patch) | |
| tree | 9d5b39941405bec4b7c4571606df8b88850325e9 /compiler/rustc_codegen_ssa/src | |
| parent | 537fb8d1bb2405b118898c663bc076815a1762c7 (diff) | |
| parent | cf24c73141a77db730f4b7fda69dcd7e8b113b51 (diff) | |
| download | rust-4316afffd9390bdac1d3bd5e5398c65d6e9bb150.tar.gz rust-4316afffd9390bdac1d3bd5e5398c65d6e9bb150.zip | |
Merge from rust-lang/rust
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 176 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/linker.rs | 98 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/metadata.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/write.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/base.rs | 80 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/errors.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/lib.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/meth.rs | 67 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 54 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/intrinsic.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/mod.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/operand.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/size_of_val.rs | 4 |
16 files changed, 441 insertions, 113 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 892dfb91201..e7b1c63a822 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -40,7 +40,7 @@ use rustc_target::spec::crt_objects::CrtObjects; use rustc_target::spec::{ Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, SanitizerSet, - SplitDebuginfo, + SplitDebuginfo, current_apple_deployment_target, }; use tempfile::Builder as TempFileBuilder; use tracing::{debug, info, warn}; @@ -1087,16 +1087,17 @@ fn link_natively( let strip = sess.opts.cg.strip; if sess.target.is_like_osx { + let stripcmd = "/usr/bin/strip"; match (strip, crate_type) { (Strip::Debuginfo, _) => { - strip_symbols_with_external_utility(sess, "strip", out_filename, Some("-S")) + strip_symbols_with_external_utility(sess, stripcmd, 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, stripcmd, out_filename, Some("-x")) } (Strip::Symbols, _) => { - strip_symbols_with_external_utility(sess, "strip", out_filename, None) + strip_symbols_with_external_utility(sess, stripcmd, out_filename, None) } (Strip::None, _) => {} } @@ -2404,6 +2405,8 @@ fn add_order_independent_options( // Take care of the flavors and CLI options requesting the `lld` linker. add_lld_args(cmd, sess, flavor, self_contained_components); + add_apple_link_args(cmd, sess, flavor); + let apple_sdk_root = add_apple_sdk(cmd, sess, flavor); add_link_script(cmd, sess, tmpdir, crate_type); @@ -2487,7 +2490,7 @@ fn add_order_independent_options( } } - cmd.set_output_kind(link_output_kind, out_filename); + cmd.set_output_kind(link_output_kind, crate_type, out_filename); add_relro_args(cmd, sess); @@ -2956,6 +2959,169 @@ pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool } } +/// We need to communicate five things to the linker on Apple/Darwin targets: +/// - The architecture. +/// - The operating system (and that it's an Apple platform). +/// - The environment / ABI. +/// - The deployment target. +/// - The SDK version. +fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { + if !sess.target.is_like_osx { + return; + } + let LinkerFlavor::Darwin(cc, _) = flavor else { + return; + }; + + // `sess.target.arch` (`target_arch`) is not detailed enough. + let llvm_arch = sess.target.llvm_target.split_once('-').expect("LLVM target must have arch").0; + let target_os = &*sess.target.os; + let target_abi = &*sess.target.abi; + + // The architecture name to forward to the linker. + // + // Supported architecture names can be found in the source: + // https://github.com/apple-oss-distributions/ld64/blob/ld64-951.9/src/abstraction/MachOFileAbstraction.hpp#L578-L648 + // + // Intentially verbose to ensure that the list always matches correctly + // with the list in the source above. + let ld64_arch = match llvm_arch { + "armv7k" => "armv7k", + "armv7s" => "armv7s", + "arm64" => "arm64", + "arm64e" => "arm64e", + "arm64_32" => "arm64_32", + // ld64 doesn't understand i686, so fall back to i386 instead. + // + // Same story when linking with cc, since that ends up invoking ld64. + "i386" | "i686" => "i386", + "x86_64" => "x86_64", + "x86_64h" => "x86_64h", + _ => bug!("unsupported architecture in Apple target: {}", sess.target.llvm_target), + }; + + if cc == Cc::No { + // From the man page for ld64 (`man ld`): + // > The linker accepts universal (multiple-architecture) input files, + // > but always creates a "thin" (single-architecture), standard + // > Mach-O output file. The architecture for the output file is + // > specified using the -arch option. + // + // The linker has heuristics to determine the desired architecture, + // but to be safe, and to avoid a warning, we set the architecture + // explicitly. + cmd.link_args(&["-arch", ld64_arch]); + + // Man page says that ld64 supports the following platform names: + // > - macos + // > - ios + // > - tvos + // > - watchos + // > - bridgeos + // > - visionos + // > - xros + // > - mac-catalyst + // > - ios-simulator + // > - tvos-simulator + // > - watchos-simulator + // > - visionos-simulator + // > - xros-simulator + // > - driverkit + let platform_name = match (target_os, target_abi) { + (os, "") => os, + ("ios", "macabi") => "mac-catalyst", + ("ios", "sim") => "ios-simulator", + ("tvos", "sim") => "tvos-simulator", + ("watchos", "sim") => "watchos-simulator", + ("visionos", "sim") => "visionos-simulator", + _ => bug!("invalid OS/ABI combination for Apple target: {target_os}, {target_abi}"), + }; + + let (major, minor, patch) = current_apple_deployment_target(&sess.target); + let min_version = format!("{major}.{minor}.{patch}"); + + // The SDK version is used at runtime when compiling with a newer SDK / version of Xcode: + // - By dyld to give extra warnings and errors, see e.g.: + // <https://github.com/apple-oss-distributions/dyld/blob/dyld-1165.3/common/MachOFile.cpp#L3029> + // <https://github.com/apple-oss-distributions/dyld/blob/dyld-1165.3/common/MachOFile.cpp#L3738-L3857> + // - By system frameworks to change certain behaviour. For example, the default value of + // `-[NSView wantsBestResolutionOpenGLSurface]` is `YES` when the SDK version is >= 10.15. + // <https://developer.apple.com/documentation/appkit/nsview/1414938-wantsbestresolutionopenglsurface?language=objc> + // + // We do not currently know the actual SDK version though, so we have a few options: + // 1. Use the minimum version supported by rustc. + // 2. Use the same as the deployment target. + // 3. Use an arbitary recent version. + // 4. Omit the version. + // + // The first option is too low / too conservative, and means that users will not get the + // same behaviour from a binary compiled with rustc as with one compiled by clang. + // + // The second option is similarly conservative, and also wrong since if the user specified a + // higher deployment target than the SDK they're compiling/linking with, the runtime might + // make invalid assumptions about the capabilities of the binary. + // + // The third option requires that `rustc` is periodically kept up to date with Apple's SDK + // version, and is also wrong for similar reasons as above. + // + // The fourth option is bad because while `ld`, `otool`, `vtool` and such understand it to + // mean "absent" or `n/a`, dyld doesn't actually understand it, and will end up interpreting + // it as 0.0, which is again too low/conservative. + // + // Currently, we lie about the SDK version, and choose the second option. + // + // FIXME(madsmtm): Parse the SDK version from the SDK root instead. + // <https://github.com/rust-lang/rust/issues/129432> + let sdk_version = &*min_version; + + // From the man page for ld64 (`man ld`): + // > This is set to indicate the platform, oldest supported version of + // > that platform that output is to be used on, and the SDK that the + // > output was built against. + // + // Like with `-arch`, the linker can figure out the platform versions + // itself from the binaries being linked, but to be safe, we specify + // the desired versions here explicitly. + cmd.link_args(&["-platform_version", platform_name, &*min_version, sdk_version]); + } else { + // cc == Cc::Yes + // + // We'd _like_ to use `-target` everywhere, since that can uniquely + // communicate all the required details except for the SDK version + // (which is read by Clang itself from the SDKROOT), but that doesn't + // work on GCC, and since we don't know whether the `cc` compiler is + // Clang, GCC, or something else, we fall back to other options that + // also work on GCC when compiling for macOS. + // + // Targets other than macOS are ill-supported by GCC (it doesn't even + // support e.g. `-miphoneos-version-min`), so in those cases we can + // fairly safely use `-target`. See also the following, where it is + // made explicit that the recommendation by LLVM developers is to use + // `-target`: <https://github.com/llvm/llvm-project/issues/88271> + if target_os == "macos" { + // `-arch` communicates the architecture. + // + // CC forwards the `-arch` to the linker, so we use the same value + // here intentionally. + cmd.cc_args(&["-arch", ld64_arch]); + + // The presence of `-mmacosx-version-min` makes CC default to + // macOS, and it sets the deployment target. + let (major, minor, patch) = current_apple_deployment_target(&sess.target); + // Intentionally pass this as a single argument, Clang doesn't + // seem to like it otherwise. + cmd.cc_arg(&format!("-mmacosx-version-min={major}.{minor}.{patch}")); + + // macOS has no environment, so with these two, we've told CC the + // four desired parameters. + // + // We avoid `-m32`/`-m64`, as this is already encoded by `-arch`. + } else { + cmd.cc_args(&["-target", &sess.target.llvm_target]); + } + } +} + fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) -> Option<PathBuf> { let arch = &sess.target.arch; let os = &sess.target.os; diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 84817e19844..3f3d305da01 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1,9 +1,8 @@ use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; use std::io::prelude::*; -use std::io::{self, BufWriter}; use std::path::{Path, PathBuf}; -use std::{env, iter, mem, str}; +use std::{env, io, iter, mem, str}; use cc::windows_registry; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; @@ -276,7 +275,12 @@ pub(crate) trait Linker { fn is_cc(&self) -> bool { false } - fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path); + fn set_output_kind( + &mut self, + output_kind: LinkOutputKind, + crate_type: CrateType, + out_filename: &Path, + ); fn link_dylib_by_name(&mut self, _name: &str, _verbatim: bool, _as_needed: bool) { bug!("dylib linked with unsupported linker") } @@ -397,7 +401,7 @@ impl<'a> GccLinker<'a> { ]); } - fn build_dylib(&mut self, out_filename: &Path) { + fn build_dylib(&mut self, crate_type: CrateType, out_filename: &Path) { // On mac we need to tell the linker to let this library be rpathed if self.sess.target.is_like_osx { if !self.is_ld { @@ -428,7 +432,7 @@ impl<'a> GccLinker<'a> { let mut out_implib = OsString::from("--out-implib="); out_implib.push(out_filename.with_file_name(implib_name)); self.link_arg(out_implib); - } else { + } else if crate_type == CrateType::Dylib { // When dylibs are linked by a full path this value will get into `DT_NEEDED` // instead of the full path, so the library can be later found in some other // location than that specific path. @@ -475,7 +479,12 @@ impl<'a> Linker for GccLinker<'a> { !self.is_ld } - fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) { + fn set_output_kind( + &mut self, + output_kind: LinkOutputKind, + crate_type: CrateType, + out_filename: &Path, + ) { match output_kind { LinkOutputKind::DynamicNoPicExe => { if !self.is_ld && self.is_gnu { @@ -510,10 +519,10 @@ impl<'a> Linker for GccLinker<'a> { self.link_args(&["-static", "-pie", "--no-dynamic-linker", "-z", "text"]); } } - LinkOutputKind::DynamicDylib => self.build_dylib(out_filename), + LinkOutputKind::DynamicDylib => self.build_dylib(crate_type, out_filename), LinkOutputKind::StaticDylib => { self.link_or_cc_arg("-static"); - self.build_dylib(out_filename); + self.build_dylib(crate_type, out_filename); } LinkOutputKind::WasiReactorExe => { self.link_args(&["--entry", "_initialize"]); @@ -754,7 +763,7 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.target.is_like_osx { // Write a plain, newline-separated list of symbols let res: io::Result<()> = try { - let mut f = BufWriter::new(File::create(&path)?); + let mut f = File::create_buffered(&path)?; for sym in symbols { debug!(" _{sym}"); writeln!(f, "_{sym}")?; @@ -765,7 +774,7 @@ impl<'a> Linker for GccLinker<'a> { } } else if is_windows { let res: io::Result<()> = try { - let mut f = BufWriter::new(File::create(&path)?); + let mut f = File::create_buffered(&path)?; // .def file similar to MSVC one but without LIBRARY section // because LD doesn't like when it's empty @@ -781,7 +790,7 @@ impl<'a> Linker for GccLinker<'a> { } else { // Write an LD version script let res: io::Result<()> = try { - let mut f = BufWriter::new(File::create(&path)?); + let mut f = File::create_buffered(&path)?; writeln!(f, "{{")?; if !symbols.is_empty() { writeln!(f, " global:")?; @@ -867,7 +876,12 @@ impl<'a> Linker for MsvcLinker<'a> { &mut self.cmd } - fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) { + fn set_output_kind( + &mut self, + output_kind: LinkOutputKind, + _crate_type: CrateType, + out_filename: &Path, + ) { match output_kind { LinkOutputKind::DynamicNoPicExe | LinkOutputKind::DynamicPicExe @@ -1059,7 +1073,7 @@ impl<'a> Linker for MsvcLinker<'a> { let path = tmpdir.join("lib.def"); let res: io::Result<()> = try { - let mut f = BufWriter::new(File::create(&path)?); + let mut f = File::create_buffered(&path)?; // Start off with the standard module name header and then go // straight to exports. @@ -1125,7 +1139,13 @@ impl<'a> Linker for EmLinker<'a> { true } - fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} + fn set_output_kind( + &mut self, + _output_kind: LinkOutputKind, + _crate_type: CrateType, + _out_filename: &Path, + ) { + } fn link_dylib_by_name(&mut self, name: &str, _verbatim: bool, _as_needed: bool) { // Emscripten always links statically @@ -1274,7 +1294,12 @@ impl<'a> Linker for WasmLd<'a> { &mut self.cmd } - fn set_output_kind(&mut self, output_kind: LinkOutputKind, _out_filename: &Path) { + fn set_output_kind( + &mut self, + output_kind: LinkOutputKind, + _crate_type: CrateType, + _out_filename: &Path, + ) { match output_kind { LinkOutputKind::DynamicNoPicExe | LinkOutputKind::DynamicPicExe @@ -1423,7 +1448,13 @@ impl<'a> Linker for L4Bender<'a> { &mut self.cmd } - fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} + fn set_output_kind( + &mut self, + _output_kind: LinkOutputKind, + _crate_type: CrateType, + _out_filename: &Path, + ) { + } fn link_staticlib_by_name(&mut self, name: &str, _verbatim: bool, whole_archive: bool) { self.hint_static(); @@ -1569,7 +1600,12 @@ impl<'a> Linker for AixLinker<'a> { &mut self.cmd } - fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) { + fn set_output_kind( + &mut self, + output_kind: LinkOutputKind, + _crate_type: CrateType, + out_filename: &Path, + ) { match output_kind { LinkOutputKind::DynamicDylib => { self.hint_dynamic(); @@ -1648,7 +1684,7 @@ impl<'a> Linker for AixLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { let path = tmpdir.join("list.exp"); let res: io::Result<()> = try { - let mut f = BufWriter::new(File::create(&path)?); + let mut f = File::create_buffered(&path)?; // FIXME: use llvm-nm to generate export list. for symbol in symbols { debug!(" _{symbol}"); @@ -1776,7 +1812,13 @@ impl<'a> Linker for PtxLinker<'a> { &mut self.cmd } - fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} + fn set_output_kind( + &mut self, + _output_kind: LinkOutputKind, + _crate_type: CrateType, + _out_filename: &Path, + ) { + } fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { panic!("staticlibs not supported") @@ -1842,7 +1884,13 @@ impl<'a> Linker for LlbcLinker<'a> { &mut self.cmd } - fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} + fn set_output_kind( + &mut self, + _output_kind: LinkOutputKind, + _crate_type: CrateType, + _out_filename: &Path, + ) { + } fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { panic!("staticlibs not supported") @@ -1913,7 +1961,13 @@ impl<'a> Linker for BpfLinker<'a> { &mut self.cmd } - fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {} + fn set_output_kind( + &mut self, + _output_kind: LinkOutputKind, + _crate_type: CrateType, + _out_filename: &Path, + ) { + } fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) { panic!("staticlibs not supported") @@ -1961,7 +2015,7 @@ impl<'a> Linker for BpfLinker<'a> { fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { let path = tmpdir.join("symbols"); let res: io::Result<()> = try { - let mut f = BufWriter::new(File::create(&path)?); + let mut f = File::create_buffered(&path)?; for sym in symbols { writeln!(f, "{sym}")?; } diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 06433484ea3..8857fda1e97 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -402,13 +402,17 @@ fn macho_object_build_version_for_target(target: &Target) -> object::write::Mach let platform = rustc_target::spec::current_apple_platform(target).expect("unknown Apple target OS"); let min_os = rustc_target::spec::current_apple_deployment_target(target); - let (sdk_major, sdk_minor) = - rustc_target::spec::current_apple_sdk_version(platform).expect("unknown Apple target OS"); let mut build_version = object::write::MachOBuildVersion::default(); build_version.platform = platform; build_version.minos = pack_version(min_os); - build_version.sdk = pack_version((sdk_major, sdk_minor, 0)); + // The version here does not _really_ matter, since it is only used at runtime, and we specify + // it when linking the final binary, so we will omit the version. This is also what LLVM does, + // and the tooling also allows this (and shows the SDK version as `n/a`). Finally, it is the + // semantically correct choice, as the SDK has not influenced the binary generated by rustc at + // this point in time. + build_version.sdk = 0; + build_version } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 4d81ff933dd..e22dd8373bd 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -11,7 +11,6 @@ use rustc_ast::attr; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; 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; use rustc_errors::{ @@ -1889,7 +1888,7 @@ impl SharedEmitter { } impl Translate for SharedEmitter { - fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> { + fn fluent_bundle(&self) -> Option<&FluentBundle> { None } @@ -1924,7 +1923,7 @@ impl Emitter for SharedEmitter { ); } - fn source_map(&self) -> Option<&Lrc<SourceMap>> { + fn source_map(&self) -> Option<&SourceMap> { None } } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 8e4385bee1a..d91c0f0790d 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -27,6 +27,9 @@ use rustc_session::config::{self, CrateType, EntryFnType, OptLevel, OutputType}; use rustc_span::symbol::sym; use rustc_span::{DUMMY_SP, Symbol}; use rustc_target::abi::FIRST_VARIANT; +use rustc_trait_selection::infer::at::ToTrace; +use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt}; +use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::{debug, info}; use crate::assert_module_sources::CguReuse; @@ -37,6 +40,7 @@ use crate::back::write::{ submit_codegened_module_to_llvm, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, }; use crate::common::{self, IntPredicate, RealPredicate, TypeKind}; +use crate::meth::load_vtable; use crate::mir::operand::OperandValue; use crate::mir::place::PlaceRef; use crate::traits::*; @@ -100,6 +104,54 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx.sext(cmp, ret_ty) } +/// Codegen takes advantage of the additional assumption, where if the +/// principal trait def id of what's being casted doesn't change, +/// then we don't need to adjust the vtable at all. This +/// corresponds to the fact that `dyn Tr<A>: Unsize<dyn Tr<B>>` +/// requires that `A = B`; we don't allow *upcasting* objects +/// between the same trait with different args. If we, for +/// some reason, were to relax the `Unsize` trait, it could become +/// unsound, so let's validate here that the trait refs are subtypes. +pub fn validate_trivial_unsize<'tcx>( + tcx: TyCtxt<'tcx>, + source_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, + target_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, +) -> bool { + match (source_data.principal(), target_data.principal()) { + (Some(hr_source_principal), Some(hr_target_principal)) => { + let infcx = tcx.infer_ctxt().build(); + let universe = infcx.universe(); + let ocx = ObligationCtxt::new(&infcx); + infcx.enter_forall(hr_target_principal, |target_principal| { + let source_principal = infcx.instantiate_binder_with_fresh_vars( + DUMMY_SP, + BoundRegionConversionTime::HigherRankedType, + hr_source_principal, + ); + let Ok(()) = ocx.eq_trace( + &ObligationCause::dummy(), + ty::ParamEnv::reveal_all(), + ToTrace::to_trace( + &ObligationCause::dummy(), + hr_target_principal, + hr_source_principal, + ), + target_principal, + source_principal, + ) else { + return false; + }; + if !ocx.select_all_or_error().is_empty() { + return false; + } + infcx.leak_check(universe, None).is_ok() + }) + } + (None, None) => true, + _ => false, + } +} + /// Retrieves the information we are losing (making dynamic) in an unsizing /// adjustment. /// @@ -124,8 +176,24 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( 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() { - // A NOP cast that doesn't actually change anything, should be allowed even with - // invalid vtables. + // Codegen takes advantage of the additional assumption, where if the + // principal trait def id of what's being casted doesn't change, + // then we don't need to adjust the vtable at all. This + // corresponds to the fact that `dyn Tr<A>: Unsize<dyn Tr<B>>` + // requires that `A = B`; we don't allow *upcasting* objects + // between the same trait with different args. If we, for + // some reason, were to relax the `Unsize` trait, it could become + // unsound, so let's assert here that the trait refs are *equal*. + debug_assert!( + validate_trivial_unsize(cx.tcx(), data_a, data_b), + "NOP unsize vtable changed principal trait ref: {data_a} -> {data_b}" + ); + + // A NOP cast that doesn't actually change anything, let's avoid any + // unnecessary work. This relies on the assumption that if the principal + // traits are equal, then the associated type bounds (`dyn Trait<Assoc=T>`) + // are also equal, which is ensured by the fact that normalization is + // a function and we do not allow overlapping impls. return old_info; } @@ -135,14 +203,8 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( if let Some(entry_idx) = vptr_entry_idx { let ptr_size = bx.data_layout().pointer_size; - let ptr_align = bx.data_layout().pointer_align.abi; let vtable_byte_offset = u64::try_from(entry_idx).unwrap() * ptr_size.bytes(); - let gep = bx.inbounds_ptradd(old_info, bx.const_usize(vtable_byte_offset)); - let new_vptr = bx.load(bx.type_ptr(), gep, ptr_align); - bx.nonnull_metadata(new_vptr); - // VTable loads are invariant. - bx.set_invariant_load(new_vptr); - new_vptr + load_vtable(bx, old_info, bx.type_ptr(), vtable_byte_offset, source, true) } else { old_info } diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index e99c3a46271..8d634ca4655 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,4 +1,4 @@ -use rustc_ast::{MetaItemKind, NestedMetaItem, ast, attr}; +use rustc_ast::{MetaItemInner, MetaItemKind, ast, attr}; use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_name}; use rustc_errors::codes::*; use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; @@ -357,7 +357,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { sym::instruction_set => { codegen_fn_attrs.instruction_set = attr.meta_item_list().and_then(|l| match &l[..] { - [NestedMetaItem::MetaItem(set)] => { + [MetaItemInner::MetaItem(set)] => { let segments = set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>(); match segments.as_slice() { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 08b326e3ac3..ab909abcead 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -916,8 +916,8 @@ pub enum InvalidMonomorphization<'tcx> { ret_ty: Ty<'tcx>, }, - #[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = E0511)] - CastFatPointer { + #[diag(codegen_ssa_invalid_monomorphization_cast_wide_pointer, code = E0511)] + CastWidePointer { #[primary_span] span: Span, name: Symbol, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index ec0520fbb09..cbd95146294 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -6,6 +6,7 @@ #![doc(rust_logo)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(file_buffered)] #![feature(if_let_guard)] #![feature(let_chains)] #![feature(negative_impls)] @@ -155,7 +156,7 @@ pub struct NativeLib { pub kind: NativeLibKind, pub name: Symbol, pub filename: Option<Symbol>, - pub cfg: Option<ast::MetaItem>, + pub cfg: Option<ast::MetaItemInner>, pub verbatim: bool, pub dll_imports: Vec<cstore::DllImport>, } diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index ecc3b2b24f1..7eb0ecd12ff 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -28,27 +28,9 @@ impl<'a, 'tcx> VirtualIndex { let llty = bx.fn_ptr_backend_type(fn_abi); let ptr_size = bx.data_layout().pointer_size; - let ptr_align = bx.data_layout().pointer_align.abi; let vtable_byte_offset = self.0 * ptr_size.bytes(); - if bx.cx().sess().opts.unstable_opts.virtual_function_elimination - && bx.cx().sess().lto() == Lto::Fat - { - let typeid = bx - .typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty))) - .unwrap(); - let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); - func - } else { - let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset)); - let ptr = bx.load(llty, gep, ptr_align); - // VTable loads are invariant. - bx.set_invariant_load(ptr); - if nonnull { - bx.nonnull_metadata(ptr); - } - ptr - } + load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, nonnull) } pub(crate) fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>( @@ -75,31 +57,27 @@ impl<'a, 'tcx> VirtualIndex { self, bx: &mut Bx, llvtable: Bx::Value, + ty: Ty<'tcx>, ) -> Bx::Value { // Load the data pointer from the object. debug!("get_int({:?}, {:?})", llvtable, self); let llty = bx.type_isize(); let ptr_size = bx.data_layout().pointer_size; - let ptr_align = bx.data_layout().pointer_align.abi; let vtable_byte_offset = self.0 * ptr_size.bytes(); - let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset)); - let ptr = bx.load(llty, gep, ptr_align); - // VTable loads are invariant. - bx.set_invariant_load(ptr); - ptr + load_vtable(bx, llvtable, llty, vtable_byte_offset, ty, false) } } /// This takes a valid `self` receiver type and extracts the principal trait -/// ref of the type. -fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> { +/// ref of the type. Return `None` if there is no principal trait. +fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> { for arg in ty.peel_refs().walk() { if let GenericArgKind::Type(ty) = arg.unpack() && let ty::Dynamic(data, _, _) = ty.kind() { - return data.principal().expect("expected principal trait object"); + return data.principal(); } } @@ -138,3 +116,36 @@ pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( cx.vtables().borrow_mut().insert((ty, trait_ref), vtable); vtable } + +/// Call this function whenever you need to load a vtable. +pub(crate) fn load_vtable<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( + bx: &mut Bx, + llvtable: Bx::Value, + llty: Bx::Type, + vtable_byte_offset: u64, + ty: Ty<'tcx>, + nonnull: bool, +) -> Bx::Value { + let ptr_align = bx.data_layout().pointer_align.abi; + + if bx.cx().sess().opts.unstable_opts.virtual_function_elimination + && bx.cx().sess().lto() == Lto::Fat + { + if let Some(trait_ref) = dyn_trait_in_self(ty) { + let typeid = bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), trait_ref)).unwrap(); + let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid); + return func; + } else if nonnull { + bug!("load nonnull value from a vtable without a principal trait") + } + } + + let gep = bx.inbounds_ptradd(llvtable, bx.const_usize(vtable_byte_offset)); + let ptr = bx.load(llty, gep, ptr_align); + // VTable loads are invariant. + bx.set_invariant_load(ptr); + if nonnull { + bx.nonnull_metadata(ptr); + } + ptr +} diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 125d3b908c7..be9a6d9a90e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -3,7 +3,9 @@ use std::cmp; use rustc_ast as ast; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::lang_items::LangItem; -use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason}; +use rustc_middle::mir::{ + self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason, +}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Instance, Ty}; @@ -1133,6 +1135,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &mut self, helper: TerminatorCodegenHelper<'tcx>, bx: &mut Bx, + asm_macro: InlineAsmMacro, terminator: &mir::Terminator<'tcx>, template: &[ast::InlineAsmTemplatePiece], operands: &[mir::InlineAsmOperand<'tcx>], @@ -1203,11 +1206,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { &operands, options, line_spans, - if options.contains(InlineAsmOptions::NORETURN) { - None - } else { - targets.get(0).copied() - }, + if asm_macro.diverges(options) { None } else { targets.get(0).copied() }, unwind, instance, mergeable_succ, @@ -1381,6 +1380,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::TerminatorKind::InlineAsm { + asm_macro, template, ref operands, options, @@ -1390,6 +1390,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } => self.codegen_asm_terminator( helper, bx, + asm_macro, terminator, template, operands, diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 9874809ea2b..146f55f95c2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -1,4 +1,5 @@ use std::collections::hash_map::Entry; +use std::marker::PhantomData; use std::ops::Range; use rustc_data_structures::fx::FxHashMap; @@ -14,7 +15,7 @@ use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx}; use super::operand::{OperandRef, OperandValue}; use super::place::{PlaceRef, PlaceValue}; -use super::{FunctionCx, LocalRef}; +use super::{FunctionCx, LocalRef, PerLocalVarDebugInfoIndexVec}; use crate::traits::*; pub struct FunctionDebugContext<'tcx, S, L> { @@ -48,6 +49,17 @@ pub struct PerLocalVarDebugInfo<'tcx, D> { pub projection: &'tcx ty::List<mir::PlaceElem<'tcx>>, } +/// Information needed to emit a constant. +pub struct ConstDebugInfo<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { + pub name: String, + pub source_info: mir::SourceInfo, + pub operand: OperandRef<'tcx, Bx::Value>, + pub dbg_var: Bx::DIVariable, + pub dbg_loc: Bx::DILocation, + pub fragment: Option<Range<Size>>, + pub _phantom: PhantomData<&'a ()>, +} + #[derive(Clone, Copy, Debug)] pub struct DebugScope<S, L> { pub dbg_scope: S, @@ -427,11 +439,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - pub(crate) fn debug_introduce_locals(&self, bx: &mut Bx) { + pub(crate) fn debug_introduce_locals( + &self, + bx: &mut Bx, + consts: Vec<ConstDebugInfo<'a, 'tcx, Bx>>, + ) { if bx.sess().opts.debuginfo == DebugInfo::Full || !bx.sess().fewer_names() { for local in self.locals.indices() { self.debug_introduce_local(bx, local); } + + for ConstDebugInfo { name, source_info, operand, dbg_var, dbg_loc, fragment, .. } in + consts.into_iter() + { + self.set_debug_loc(bx, source_info); + let base = FunctionCx::spill_operand_to_stack(operand, Some(name), bx); + bx.clear_dbg_loc(); + + bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], fragment); + } } } @@ -439,7 +465,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub(crate) fn compute_per_local_var_debug_info( &self, bx: &mut Bx, - ) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> { + ) -> Option<( + PerLocalVarDebugInfoIndexVec<'tcx, Bx::DIVariable>, + Vec<ConstDebugInfo<'a, 'tcx, Bx>>, + )> { let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full; let target_is_msvc = self.cx.sess().target.is_like_msvc; @@ -449,6 +478,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } let mut per_local = IndexVec::from_elem(vec![], &self.mir.local_decls); + let mut constants = vec![]; let mut params_seen: FxHashMap<_, Bx::DIVariable> = Default::default(); for var in &self.mir.var_debug_info { let dbg_scope_and_span = if full_debug_info { @@ -545,23 +575,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; let operand = self.eval_mir_constant_to_operand(bx, &c); - self.set_debug_loc(bx, var.source_info); - let base = - Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx); - bx.clear_dbg_loc(); - - bx.dbg_var_addr( + constants.push(ConstDebugInfo { + name: var.name.to_string(), + source_info: var.source_info, + operand, dbg_var, dbg_loc, - base.val.llval, - Size::ZERO, - &[], fragment, - ); + _phantom: PhantomData, + }); } } } } - Some(per_local) + Some((per_local, constants)) } } diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 71541e6ab41..32cc78187b9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::vtable_align => ty::COMMON_VTABLE_ENTRIES_ALIGN, _ => bug!(), }; - let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable); + let value = meth::VirtualIndex::from_index(idx).get_usize(bx, vtable, callee_ty); match name { // Size is always <= isize::MAX. sym::vtable_size => { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 202baddec72..8bd172a9ce6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -41,6 +41,9 @@ enum CachedLlbb<T> { Skip, } +type PerLocalVarDebugInfoIndexVec<'tcx, V> = + IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, V>>>; + /// Master context for codegenning from MIR. pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { instance: Instance<'tcx>, @@ -107,8 +110,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { /// All `VarDebugInfo` from the MIR body, partitioned by `Local`. /// This is `None` if no variable debuginfo/names are needed. - per_local_var_debug_info: - Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>>, + per_local_var_debug_info: Option<PerLocalVarDebugInfoIndexVec<'tcx, Bx::DIVariable>>, /// Caller location propagated if this function has `#[track_caller]`. caller_location: Option<OperandRef<'tcx, Bx::Value>>, @@ -131,9 +133,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { enum LocalRef<'tcx, V> { Place(PlaceRef<'tcx, V>), /// `UnsizedPlace(p)`: `p` itself is a thin pointer (indirect place). - /// `*p` is the fat pointer that references the actual unsized place. + /// `*p` is the wide pointer that references the actual unsized place. /// Every time it is initialized, we have to reallocate the place - /// and update the fat pointer. That's the reason why it is indirect. + /// and update the wide pointer. That's the reason why it is indirect. UnsizedPlace(PlaceRef<'tcx, V>), /// The backend [`OperandValue`] has already been generated. Operand(OperandRef<'tcx, V>), @@ -216,7 +218,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // monomorphization, and if there is an error during collection then codegen never starts -- so // we don't have to do it again. - fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx); + let (per_local_var_debug_info, consts_debug_info) = + fx.compute_per_local_var_debug_info(&mut start_bx).unzip(); + fx.per_local_var_debug_info = per_local_var_debug_info; let traversal_order = traversal::mono_reachable_reverse_postorder(mir, cx.tcx(), instance); let memory_locals = analyze::non_ssa_locals(&fx, &traversal_order); @@ -268,7 +272,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx.initialize_locals(local_values); // Apply debuginfo to the newly allocated locals. - fx.debug_introduce_locals(&mut start_bx); + fx.debug_introduce_locals(&mut start_bx, consts_debug_info.unwrap_or_default()); // If the backend supports coverage, and coverage is enabled for this function, // do any necessary start-of-function codegen (e.g. locals for MC/DC bitmaps). @@ -425,7 +429,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Unsized indirect qrguments PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { // As the storage for the indirect argument lives during - // the whole function call, we just copy the fat pointer. + // the whole function call, we just copy the wide pointer. let llarg = bx.get_param(llarg_idx); llarg_idx += 1; let llextra = bx.get_param(llarg_idx); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 17f66c12a03..0bcd7d6d081 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -41,7 +41,7 @@ pub enum OperandValue<V> { /// The backend value in this variant must be the *immediate* backend type, /// as returned by [`LayoutTypeCodegenMethods::immediate_backend_type`]. Immediate(V), - /// A pair of immediate LLVM values. Used by fat pointers too. + /// A pair of immediate LLVM values. Used by wide pointers too. /// /// An `OperandValue` *must* be this variant for any type for which /// [`LayoutTypeCodegenMethods::is_backend_scalar_pair`] returns `true`. diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index f9c0f3ce941..a132ca69540 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -38,10 +38,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ref source, _, ) => { - // The destination necessarily contains a fat pointer, so if - // it's a scalar pair, it's a fat pointer or newtype thereof. + // The destination necessarily contains a wide pointer, so if + // it's a scalar pair, it's a wide pointer or newtype thereof. if bx.cx().is_backend_scalar_pair(dest.layout) { - // Into-coerce of a thin pointer to a fat pointer -- just + // Into-coerce of a thin pointer to a wide pointer -- just // use the operand path. let temp = self.codegen_rvalue_operand(bx, rvalue); temp.val.store(bx, dest); @@ -519,7 +519,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if bx.cx().is_backend_scalar_pair(cast) { OperandValue::Pair(data_ptr, meta) } else { - // Cast of fat-ptr to thin-ptr is an extraction of data-ptr. + // Cast of wide-ptr to thin-ptr is an extraction of data-ptr. OperandValue::Immediate(data_ptr) } } else { @@ -622,7 +622,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ( OperandValue::Pair(lhs_addr, lhs_extra), OperandValue::Pair(rhs_addr, rhs_extra), - ) => self.codegen_fat_ptr_binop( + ) => self.codegen_wide_ptr_binop( bx, op, lhs_addr, @@ -984,7 +984,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - fn codegen_fat_ptr_binop( + fn codegen_wide_ptr_binop( &mut self, bx: &mut Bx, op: mir::BinOp, @@ -1021,7 +1021,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.or(lhs, rhs) } _ => { - bug!("unexpected fat ptr binop"); + bug!("unexpected wide ptr binop"); } } } diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index 3f3ae21035d..827b939217e 100644 --- a/compiler/rustc_codegen_ssa/src/size_of_val.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -28,9 +28,9 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // Load size/align from vtable. let vtable = info.unwrap(); let size = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_SIZE) - .get_usize(bx, vtable); + .get_usize(bx, vtable, t); let align = meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_ALIGN) - .get_usize(bx, vtable); + .get_usize(bx, vtable, t); // Size is always <= isize::MAX. let size_bound = bx.data_layout().ptr_sized_integer().signed_max() as u128; |
