mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Auto merge of #139037 - jhpratt:rollup-4c74y8a, r=jhpratt
Rollup of 6 pull requests Successful merges: - #138720 (Specify a concrete stack size in channel tests) - #139010 (Improve `xcrun` error handling) - #139021 (std: get rid of pre-Vista fallback code) - #139025 (Do not trim paths in MIR validator) - #139026 (Use `abs_diff` where applicable) - #139030 (saethlin goes on vacation) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e77a8f439c
@ -10,8 +10,6 @@ codegen_ssa_apple_deployment_target_invalid =
|
|||||||
codegen_ssa_apple_deployment_target_too_low =
|
codegen_ssa_apple_deployment_target_too_low =
|
||||||
deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
|
deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
|
||||||
|
|
||||||
codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
|
|
||||||
|
|
||||||
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
|
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
|
||||||
|
|
||||||
codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
|
codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing failure memory ordering
|
||||||
@ -391,8 +389,6 @@ codegen_ssa_unknown_atomic_ordering = unknown ordering in atomic intrinsic
|
|||||||
|
|
||||||
codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified
|
codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified
|
||||||
|
|
||||||
codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
|
|
||||||
|
|
||||||
codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]`
|
codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]`
|
||||||
|
|
||||||
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
|
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
|
||||||
@ -402,3 +398,20 @@ codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to sp
|
|||||||
codegen_ssa_version_script_write_failure = failed to write version script: {$error}
|
codegen_ssa_version_script_write_failure = failed to write version script: {$error}
|
||||||
|
|
||||||
codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload
|
codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload
|
||||||
|
|
||||||
|
codegen_ssa_xcrun_command_line_tools_insufficient =
|
||||||
|
when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode
|
||||||
|
|
||||||
|
codegen_ssa_xcrun_failed_invoking = invoking `{$command_formatted}` to find {$sdk_name}.sdk failed: {$error}
|
||||||
|
|
||||||
|
codegen_ssa_xcrun_found_developer_dir = found active developer directory at "{$developer_dir}"
|
||||||
|
|
||||||
|
# `xcrun` already outputs a message about missing Xcode installation, so we only augment it with details about env vars.
|
||||||
|
codegen_ssa_xcrun_no_developer_dir =
|
||||||
|
pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable
|
||||||
|
|
||||||
|
codegen_ssa_xcrun_sdk_path_warning = output of `xcrun` while finding {$sdk_name}.sdk
|
||||||
|
.note = {$stderr}
|
||||||
|
|
||||||
|
codegen_ssa_xcrun_unsuccessful = failed running `{$command_formatted}` to find {$sdk_name}.sdk
|
||||||
|
.note = {$stdout}{$stderr}
|
||||||
|
@ -1,16 +1,40 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
use std::ffi::OsString;
|
||||||
use std::fmt::{Display, from_fn};
|
use std::fmt::{Display, from_fn};
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
use rustc_middle::middle::exported_symbols::SymbolExportKind;
|
use rustc_middle::middle::exported_symbols::SymbolExportKind;
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_target::spec::Target;
|
use rustc_target::spec::Target;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::errors::AppleDeploymentTarget;
|
use crate::errors::{AppleDeploymentTarget, XcrunError, XcrunSdkPathWarning};
|
||||||
|
use crate::fluent_generated as fluent;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
|
/// The canonical name of the desired SDK for a given target.
|
||||||
|
pub(super) fn sdk_name(target: &Target) -> &'static str {
|
||||||
|
match (&*target.os, &*target.abi) {
|
||||||
|
("macos", "") => "MacOSX",
|
||||||
|
("ios", "") => "iPhoneOS",
|
||||||
|
("ios", "sim") => "iPhoneSimulator",
|
||||||
|
// Mac Catalyst uses the macOS SDK
|
||||||
|
("ios", "macabi") => "MacOSX",
|
||||||
|
("tvos", "") => "AppleTVOS",
|
||||||
|
("tvos", "sim") => "AppleTVSimulator",
|
||||||
|
("visionos", "") => "XROS",
|
||||||
|
("visionos", "sim") => "XRSimulator",
|
||||||
|
("watchos", "") => "WatchOS",
|
||||||
|
("watchos", "sim") => "WatchSimulator",
|
||||||
|
(os, abi) => unreachable!("invalid os '{os}' / abi '{abi}' combination for Apple target"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn macho_platform(target: &Target) -> u32 {
|
pub(super) fn macho_platform(target: &Target) -> u32 {
|
||||||
match (&*target.os, &*target.abi) {
|
match (&*target.os, &*target.abi) {
|
||||||
("macos", _) => object::macho::PLATFORM_MACOS,
|
("macos", _) => object::macho::PLATFORM_MACOS,
|
||||||
@ -253,3 +277,131 @@ pub(super) fn add_version_to_llvm_target(
|
|||||||
format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}")
|
format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn get_sdk_root(sess: &Session) -> Option<PathBuf> {
|
||||||
|
let sdk_name = sdk_name(&sess.target);
|
||||||
|
|
||||||
|
match xcrun_show_sdk_path(sdk_name, sess.verbose_internals()) {
|
||||||
|
Ok((path, stderr)) => {
|
||||||
|
// Emit extra stderr, such as if `-verbose` was passed, or if `xcrun` emitted a warning.
|
||||||
|
if !stderr.is_empty() {
|
||||||
|
sess.dcx().emit_warn(XcrunSdkPathWarning { sdk_name, stderr });
|
||||||
|
}
|
||||||
|
Some(path)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
let mut diag = sess.dcx().create_err(err);
|
||||||
|
|
||||||
|
// Recognize common error cases, and give more Rust-specific error messages for those.
|
||||||
|
if let Some(developer_dir) = xcode_select_developer_dir() {
|
||||||
|
diag.arg("developer_dir", &developer_dir);
|
||||||
|
diag.note(fluent::codegen_ssa_xcrun_found_developer_dir);
|
||||||
|
if developer_dir.as_os_str().to_string_lossy().contains("CommandLineTools") {
|
||||||
|
if sdk_name != "MacOSX" {
|
||||||
|
diag.help(fluent::codegen_ssa_xcrun_command_line_tools_insufficient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
diag.help(fluent::codegen_ssa_xcrun_no_developer_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
diag.emit();
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoke `xcrun --sdk $sdk_name --show-sdk-path` to get the SDK path.
|
||||||
|
///
|
||||||
|
/// The exact logic that `xcrun` uses is unspecified (see `man xcrun` for a few details), and may
|
||||||
|
/// change between macOS and Xcode versions, but it roughly boils down to finding the active
|
||||||
|
/// developer directory, and then invoking `xcodebuild -sdk $sdk_name -version` to get the SDK
|
||||||
|
/// details.
|
||||||
|
///
|
||||||
|
/// Finding the developer directory is roughly done by looking at, in order:
|
||||||
|
/// - The `DEVELOPER_DIR` environment variable.
|
||||||
|
/// - The `/var/db/xcode_select_link` symlink (set by `xcode-select --switch`).
|
||||||
|
/// - `/Applications/Xcode.app` (hardcoded fallback path).
|
||||||
|
/// - `/Library/Developer/CommandLineTools` (hardcoded fallback path).
|
||||||
|
///
|
||||||
|
/// Note that `xcrun` caches its result, but with a cold cache this whole operation can be quite
|
||||||
|
/// slow, especially so the first time it's run after a reboot.
|
||||||
|
fn xcrun_show_sdk_path(
|
||||||
|
sdk_name: &'static str,
|
||||||
|
verbose: bool,
|
||||||
|
) -> Result<(PathBuf, String), XcrunError> {
|
||||||
|
let mut cmd = Command::new("xcrun");
|
||||||
|
if verbose {
|
||||||
|
cmd.arg("--verbose");
|
||||||
|
}
|
||||||
|
// The `--sdk` parameter is the same as in xcodebuild, namely either an absolute path to an SDK,
|
||||||
|
// or the (lowercase) canonical name of an SDK.
|
||||||
|
cmd.arg("--sdk");
|
||||||
|
cmd.arg(&sdk_name.to_lowercase());
|
||||||
|
cmd.arg("--show-sdk-path");
|
||||||
|
|
||||||
|
// We do not stream stdout/stderr lines directly to the user, since whether they are warnings or
|
||||||
|
// errors depends on the status code at the end.
|
||||||
|
let output = cmd.output().map_err(|error| XcrunError::FailedInvoking {
|
||||||
|
sdk_name,
|
||||||
|
command_formatted: format!("{cmd:?}"),
|
||||||
|
error,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// It is fine to do lossy conversion here, non-UTF-8 paths are quite rare on macOS nowadays
|
||||||
|
// (only possible with the HFS+ file system), and we only use it for error messages.
|
||||||
|
let stderr = String::from_utf8_lossy_owned(output.stderr);
|
||||||
|
if !stderr.is_empty() {
|
||||||
|
debug!(stderr, "original xcrun stderr");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some versions of `xcodebuild` output beefy errors when invoked via `xcrun`,
|
||||||
|
// but these are usually red herrings.
|
||||||
|
let stderr = stderr
|
||||||
|
.lines()
|
||||||
|
.filter(|line| {
|
||||||
|
!line.contains("Writing error result bundle")
|
||||||
|
&& !line.contains("Requested but did not find extension point with identifier")
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
|
|
||||||
|
if output.status.success() {
|
||||||
|
Ok((stdout_to_path(output.stdout), stderr))
|
||||||
|
} else {
|
||||||
|
// Output both stdout and stderr, since shims of `xcrun` (such as the one provided by
|
||||||
|
// nixpkgs), do not always use stderr for errors.
|
||||||
|
let stdout = String::from_utf8_lossy_owned(output.stdout).trim().to_string();
|
||||||
|
Err(XcrunError::Unsuccessful {
|
||||||
|
sdk_name,
|
||||||
|
command_formatted: format!("{cmd:?}"),
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Invoke `xcode-select --print-path`, and return the current developer directory.
|
||||||
|
///
|
||||||
|
/// NOTE: We don't do any error handling here, this is only used as a canary in diagnostics (`xcrun`
|
||||||
|
/// will have already emitted the relevant error information).
|
||||||
|
fn xcode_select_developer_dir() -> Option<PathBuf> {
|
||||||
|
let mut cmd = Command::new("xcode-select");
|
||||||
|
cmd.arg("--print-path");
|
||||||
|
let output = cmd.output().ok()?;
|
||||||
|
if !output.status.success() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(stdout_to_path(output.stdout))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stdout_to_path(mut stdout: Vec<u8>) -> PathBuf {
|
||||||
|
// Remove trailing newline.
|
||||||
|
if let Some(b'\n') = stdout.last() {
|
||||||
|
let _ = stdout.pop().unwrap();
|
||||||
|
}
|
||||||
|
#[cfg(unix)]
|
||||||
|
let path = <OsString as std::os::unix::ffi::OsStringExt>::from_vec(stdout);
|
||||||
|
#[cfg(not(unix))] // Unimportant, this is only used on macOS
|
||||||
|
let path = OsString::from(String::from_utf8(stdout).unwrap());
|
||||||
|
PathBuf::from(path)
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::{add_version_to_llvm_target, parse_version};
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_version_to_llvm_target() {
|
fn test_add_version_to_llvm_target() {
|
||||||
@ -19,3 +19,69 @@ fn test_parse_version() {
|
|||||||
assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6)));
|
assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6)));
|
||||||
assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99)));
|
assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(not(target_os = "macos"), ignore = "xcode-select is only available on macOS")]
|
||||||
|
fn lookup_developer_dir() {
|
||||||
|
let _developer_dir = xcode_select_developer_dir().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(not(target_os = "macos"), ignore = "xcrun is only available on macOS")]
|
||||||
|
fn lookup_sdk() {
|
||||||
|
let (sdk_path, stderr) = xcrun_show_sdk_path("MacOSX", false).unwrap();
|
||||||
|
// Check that the found SDK is valid.
|
||||||
|
assert!(sdk_path.join("SDKSettings.plist").exists());
|
||||||
|
assert_eq!(stderr, "");
|
||||||
|
|
||||||
|
// Test that the SDK root is a subdir of the developer directory.
|
||||||
|
if let Some(developer_dir) = xcode_select_developer_dir() {
|
||||||
|
// Only run this test if SDKROOT is not set (otherwise xcrun may look up via. that).
|
||||||
|
if std::env::var_os("SDKROOT").is_some() {
|
||||||
|
assert!(sdk_path.starts_with(&developer_dir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(not(target_os = "macos"), ignore = "xcrun is only available on macOS")]
|
||||||
|
fn lookup_sdk_verbose() {
|
||||||
|
let (_, stderr) = xcrun_show_sdk_path("MacOSX", true).unwrap();
|
||||||
|
// Newer xcrun versions should emit something like this:
|
||||||
|
//
|
||||||
|
// xcrun: note: looking up SDK with 'xcodebuild -sdk macosx -version Path'
|
||||||
|
// xcrun: note: xcrun_db = '/var/.../xcrun_db'
|
||||||
|
// xcrun: note: lookup resolved to: '...'
|
||||||
|
// xcrun: note: database key is: ...
|
||||||
|
//
|
||||||
|
// Or if the value is already cached, something like this:
|
||||||
|
//
|
||||||
|
// xcrun: note: database key is: ...
|
||||||
|
// xcrun: note: lookup resolved in '/var/.../xcrun_db' : '...'
|
||||||
|
assert!(
|
||||||
|
stderr.contains("xcrun: note: lookup resolved"),
|
||||||
|
"stderr should contain lookup note: {stderr}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(not(target_os = "macos"), ignore = "xcrun is only available on macOS")]
|
||||||
|
fn try_lookup_invalid_sdk() {
|
||||||
|
// As a proxy for testing all the different ways that `xcrun` can fail,
|
||||||
|
// test the case where an SDK was not found.
|
||||||
|
let err = xcrun_show_sdk_path("invalid", false).unwrap_err();
|
||||||
|
let XcrunError::Unsuccessful { stderr, .. } = err else {
|
||||||
|
panic!("unexpected error kind: {err:?}");
|
||||||
|
};
|
||||||
|
// Either one of (depending on if using Command Line Tools or full Xcode):
|
||||||
|
// xcrun: error: SDK "invalid" cannot be located
|
||||||
|
// xcodebuild: error: SDK "invalid" cannot be located.
|
||||||
|
assert!(
|
||||||
|
stderr.contains(r#"error: SDK "invalid" cannot be located"#),
|
||||||
|
"stderr should contain xcodebuild note: {stderr}",
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
stderr.contains("xcrun: error: unable to lookup item 'Path' in SDK 'invalid'"),
|
||||||
|
"stderr should contain xcrun note: {stderr}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -3201,9 +3201,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) -> Option<PathBuf> {
|
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) -> Option<PathBuf> {
|
||||||
let arch = &sess.target.arch;
|
|
||||||
let os = &sess.target.os;
|
let os = &sess.target.os;
|
||||||
let llvm_target = &sess.target.llvm_target;
|
|
||||||
if sess.target.vendor != "apple"
|
if sess.target.vendor != "apple"
|
||||||
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "visionos" | "macos")
|
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "visionos" | "macos")
|
||||||
|| !matches!(flavor, LinkerFlavor::Darwin(..))
|
|| !matches!(flavor, LinkerFlavor::Darwin(..))
|
||||||
@ -3215,37 +3213,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) ->
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sdk_name = match (arch.as_ref(), os.as_ref()) {
|
let sdk_root = sess.time("get_apple_sdk_root", || get_apple_sdk_root(sess))?;
|
||||||
("aarch64", "tvos") if llvm_target.ends_with("-simulator") => "appletvsimulator",
|
|
||||||
("aarch64", "tvos") => "appletvos",
|
|
||||||
("x86_64", "tvos") => "appletvsimulator",
|
|
||||||
("arm", "ios") => "iphoneos",
|
|
||||||
("aarch64", "ios") if llvm_target.contains("macabi") => "macosx",
|
|
||||||
("aarch64", "ios") if llvm_target.ends_with("-simulator") => "iphonesimulator",
|
|
||||||
("aarch64", "ios") => "iphoneos",
|
|
||||||
("x86", "ios") => "iphonesimulator",
|
|
||||||
("x86_64", "ios") if llvm_target.contains("macabi") => "macosx",
|
|
||||||
("x86_64", "ios") => "iphonesimulator",
|
|
||||||
("x86_64", "watchos") => "watchsimulator",
|
|
||||||
("arm64_32", "watchos") => "watchos",
|
|
||||||
("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
|
|
||||||
("aarch64", "watchos") => "watchos",
|
|
||||||
("aarch64", "visionos") if llvm_target.ends_with("-simulator") => "xrsimulator",
|
|
||||||
("aarch64", "visionos") => "xros",
|
|
||||||
("arm", "watchos") => "watchos",
|
|
||||||
(_, "macos") => "macosx",
|
|
||||||
_ => {
|
|
||||||
sess.dcx().emit_err(errors::UnsupportedArch { arch, os });
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let sdk_root = match get_apple_sdk_root(sdk_name) {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(e) => {
|
|
||||||
sess.dcx().emit_err(e);
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match flavor {
|
match flavor {
|
||||||
LinkerFlavor::Darwin(Cc::Yes, _) => {
|
LinkerFlavor::Darwin(Cc::Yes, _) => {
|
||||||
@ -3255,28 +3223,32 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) ->
|
|||||||
// This is admittedly a bit strange, as on most targets
|
// This is admittedly a bit strange, as on most targets
|
||||||
// `-isysroot` only applies to include header files, but on Apple
|
// `-isysroot` only applies to include header files, but on Apple
|
||||||
// targets this also applies to libraries and frameworks.
|
// targets this also applies to libraries and frameworks.
|
||||||
cmd.cc_args(&["-isysroot", &sdk_root]);
|
cmd.cc_arg("-isysroot");
|
||||||
|
cmd.cc_arg(&sdk_root);
|
||||||
}
|
}
|
||||||
LinkerFlavor::Darwin(Cc::No, _) => {
|
LinkerFlavor::Darwin(Cc::No, _) => {
|
||||||
cmd.link_args(&["-syslibroot", &sdk_root]);
|
cmd.link_arg("-syslibroot");
|
||||||
|
cmd.link_arg(&sdk_root);
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(sdk_root.into())
|
Some(sdk_root)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootError<'_>> {
|
fn get_apple_sdk_root(sess: &Session) -> Option<PathBuf> {
|
||||||
// Following what clang does
|
|
||||||
// (https://github.com/llvm/llvm-project/blob/
|
|
||||||
// 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
|
|
||||||
// to allow the SDK path to be set. (For clang, xcrun sets
|
|
||||||
// SDKROOT; for rustc, the user or build system can set it, or we
|
|
||||||
// can fall back to checking for xcrun on PATH.)
|
|
||||||
if let Ok(sdkroot) = env::var("SDKROOT") {
|
if let Ok(sdkroot) = env::var("SDKROOT") {
|
||||||
let p = Path::new(&sdkroot);
|
let p = PathBuf::from(&sdkroot);
|
||||||
match sdk_name {
|
|
||||||
// Ignore `SDKROOT` if it's clearly set for the wrong platform.
|
// Ignore invalid SDKs, similar to what clang does:
|
||||||
|
// https://github.com/llvm/llvm-project/blob/llvmorg-19.1.6/clang/lib/Driver/ToolChains/Darwin.cpp#L2212-L2229
|
||||||
|
//
|
||||||
|
// NOTE: Things are complicated here by the fact that `rustc` can be run by Cargo to compile
|
||||||
|
// build scripts and proc-macros for the host, and thus we need to ignore SDKROOT if it's
|
||||||
|
// clearly set for the wrong platform.
|
||||||
|
//
|
||||||
|
// FIXME(madsmtm): Make this more robust (maybe read `SDKSettings.json` like Clang does?).
|
||||||
|
match &*apple::sdk_name(&sess.target).to_lowercase() {
|
||||||
"appletvos"
|
"appletvos"
|
||||||
if sdkroot.contains("TVSimulator.platform")
|
if sdkroot.contains("TVSimulator.platform")
|
||||||
|| sdkroot.contains("MacOSX.platform") => {}
|
|| sdkroot.contains("MacOSX.platform") => {}
|
||||||
@ -3303,26 +3275,11 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
|
|||||||
if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {}
|
if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {}
|
||||||
// Ignore `SDKROOT` if it's not a valid path.
|
// Ignore `SDKROOT` if it's not a valid path.
|
||||||
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
|
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
|
||||||
_ => return Ok(sdkroot),
|
_ => return Some(p),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let res =
|
|
||||||
Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then(
|
|
||||||
|output| {
|
|
||||||
if output.status.success() {
|
|
||||||
Ok(String::from_utf8(output.stdout).unwrap())
|
|
||||||
} else {
|
|
||||||
let error = String::from_utf8(output.stderr);
|
|
||||||
let error = format!("process exit with error: {}", error.unwrap());
|
|
||||||
Err(io::Error::new(io::ErrorKind::Other, &error[..]))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
match res {
|
apple::get_sdk_root(sess)
|
||||||
Ok(output) => Ok(output.trim().to_string()),
|
|
||||||
Err(error) => Err(errors::AppleSdkRootError::SdkPath { sdk_name, error }),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When using the linker flavors opting in to `lld`, add the necessary paths and arguments to
|
/// When using the linker flavors opting in to `lld`, add the necessary paths and arguments to
|
||||||
|
@ -738,13 +738,6 @@ pub enum ExtractBundledLibsError<'a> {
|
|||||||
ExtractSection { rlib: &'a Path, error: Box<dyn std::error::Error> },
|
ExtractSection { rlib: &'a Path, error: Box<dyn std::error::Error> },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_ssa_unsupported_arch)]
|
|
||||||
pub(crate) struct UnsupportedArch<'a> {
|
|
||||||
pub arch: &'a str,
|
|
||||||
pub os: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
pub(crate) enum AppleDeploymentTarget {
|
pub(crate) enum AppleDeploymentTarget {
|
||||||
#[diag(codegen_ssa_apple_deployment_target_invalid)]
|
#[diag(codegen_ssa_apple_deployment_target_invalid)]
|
||||||
@ -753,12 +746,6 @@ pub(crate) enum AppleDeploymentTarget {
|
|||||||
TooLow { env_var: &'static str, version: String, os_min: String },
|
TooLow { env_var: &'static str, version: String, os_min: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
pub(crate) enum AppleSdkRootError<'a> {
|
|
||||||
#[diag(codegen_ssa_apple_sdk_error_sdk_path)]
|
|
||||||
SdkPath { sdk_name: &'a str, error: Error },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(codegen_ssa_read_file)]
|
#[diag(codegen_ssa_read_file)]
|
||||||
pub(crate) struct ReadFileError {
|
pub(crate) struct ReadFileError {
|
||||||
@ -1334,3 +1321,26 @@ pub(crate) struct MixedExportNameAndNoMangle {
|
|||||||
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
|
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
|
||||||
pub removal_span: Span,
|
pub removal_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic, Debug)]
|
||||||
|
pub(crate) enum XcrunError {
|
||||||
|
#[diag(codegen_ssa_xcrun_failed_invoking)]
|
||||||
|
FailedInvoking { sdk_name: &'static str, command_formatted: String, error: std::io::Error },
|
||||||
|
|
||||||
|
#[diag(codegen_ssa_xcrun_unsuccessful)]
|
||||||
|
#[note]
|
||||||
|
Unsuccessful {
|
||||||
|
sdk_name: &'static str,
|
||||||
|
command_formatted: String,
|
||||||
|
stdout: String,
|
||||||
|
stderr: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic, Debug)]
|
||||||
|
#[diag(codegen_ssa_xcrun_sdk_path_warning)]
|
||||||
|
#[note]
|
||||||
|
pub(crate) struct XcrunSdkPathWarning {
|
||||||
|
pub sdk_name: &'static str,
|
||||||
|
pub stderr: String,
|
||||||
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(negative_impls)]
|
#![feature(negative_impls)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
|
#![feature(string_from_utf8_lossy_owned)]
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
|
@ -159,11 +159,7 @@ impl Annotation {
|
|||||||
/// Length of this annotation as displayed in the stderr output
|
/// Length of this annotation as displayed in the stderr output
|
||||||
pub(crate) fn len(&self) -> usize {
|
pub(crate) fn len(&self) -> usize {
|
||||||
// Account for usize underflows
|
// Account for usize underflows
|
||||||
if self.end_col.display > self.start_col.display {
|
self.end_col.display.abs_diff(self.start_col.display)
|
||||||
self.end_col.display - self.start_col.display
|
|
||||||
} else {
|
|
||||||
self.start_col.display - self.end_col.display
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn has_label(&self) -> bool {
|
pub(crate) fn has_label(&self) -> bool {
|
||||||
|
@ -12,6 +12,7 @@ use rustc_middle::mir::coverage::CoverageKind;
|
|||||||
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
|
||||||
use rustc_middle::mir::*;
|
use rustc_middle::mir::*;
|
||||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
|
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance,
|
self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance,
|
||||||
};
|
};
|
||||||
@ -56,7 +57,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator {
|
|||||||
ty::Coroutine(..) => ExternAbi::Rust,
|
ty::Coroutine(..) => ExternAbi::Rust,
|
||||||
// No need to do MIR validation on error bodies
|
// No need to do MIR validation on error bodies
|
||||||
ty::Error(_) => return,
|
ty::Error(_) => return,
|
||||||
_ => span_bug!(body.span, "unexpected body ty: {body_ty:?}"),
|
_ => span_bug!(body.span, "unexpected body ty: {body_ty}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
ty::layout::fn_can_unwind(tcx, Some(def_id), body_abi)
|
ty::layout::fn_can_unwind(tcx, Some(def_id), body_abi)
|
||||||
@ -543,7 +544,13 @@ pub(super) fn validate_types<'tcx>(
|
|||||||
caller_body: &Body<'tcx>,
|
caller_body: &Body<'tcx>,
|
||||||
) -> Vec<(Location, String)> {
|
) -> Vec<(Location, String)> {
|
||||||
let mut type_checker = TypeChecker { body, caller_body, tcx, typing_env, failures: Vec::new() };
|
let mut type_checker = TypeChecker { body, caller_body, tcx, typing_env, failures: Vec::new() };
|
||||||
type_checker.visit_body(body);
|
// The type checker formats a bunch of strings with type names in it, but these strings
|
||||||
|
// are not always going to be encountered on the error path since the inliner also uses
|
||||||
|
// the validator, and there are certain kinds of inlining (even for valid code) that
|
||||||
|
// can cause validation errors (mostly around where clauses and rigid projections).
|
||||||
|
with_no_trimmed_paths!({
|
||||||
|
type_checker.visit_body(body);
|
||||||
|
});
|
||||||
type_checker.failures
|
type_checker.failures
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +662,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
ProjectionElem::Index(index) => {
|
ProjectionElem::Index(index) => {
|
||||||
let index_ty = self.body.local_decls[index].ty;
|
let index_ty = self.body.local_decls[index].ty;
|
||||||
if index_ty != self.tcx.types.usize {
|
if index_ty != self.tcx.types.usize {
|
||||||
self.fail(location, format!("bad index ({index_ty:?} != usize)"))
|
self.fail(location, format!("bad index ({index_ty} != usize)"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProjectionElem::Deref
|
ProjectionElem::Deref
|
||||||
@ -664,10 +671,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
let base_ty = place_ref.ty(&self.body.local_decls, self.tcx).ty;
|
let base_ty = place_ref.ty(&self.body.local_decls, self.tcx).ty;
|
||||||
|
|
||||||
if base_ty.is_box() {
|
if base_ty.is_box() {
|
||||||
self.fail(
|
self.fail(location, format!("{base_ty} dereferenced after ElaborateBoxDerefs"))
|
||||||
location,
|
|
||||||
format!("{base_ty:?} dereferenced after ElaborateBoxDerefs"),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProjectionElem::Field(f, ty) => {
|
ProjectionElem::Field(f, ty) => {
|
||||||
@ -680,7 +684,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
this.fail(
|
this.fail(
|
||||||
location,
|
location,
|
||||||
format!(
|
format!(
|
||||||
"Field projection `{place_ref:?}.{f:?}` specified type `{ty:?}`, but actual type is `{f_ty:?}`"
|
"Field projection `{place_ref:?}.{f:?}` specified type `{ty}`, but actual type is `{f_ty}`"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -806,7 +810,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!(
|
format!(
|
||||||
"Failed subtyping {ty:#?} and {:#?}",
|
"Failed subtyping {ty} and {}",
|
||||||
place_ref.ty(&self.body.local_decls, self.tcx).ty
|
place_ref.ty(&self.body.local_decls, self.tcx).ty
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -826,7 +830,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!(
|
format!(
|
||||||
"Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty:?}"
|
"Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty}"
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -841,7 +845,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
if ty.is_union() || ty.is_enum() {
|
if ty.is_union() || ty.is_enum() {
|
||||||
self.fail(
|
self.fail(
|
||||||
START_BLOCK.start_location(),
|
START_BLOCK.start_location(),
|
||||||
format!("invalid type {ty:?} in debuginfo for {:?}", debuginfo.name),
|
format!("invalid type {ty} in debuginfo for {:?}", debuginfo.name),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if projection.is_empty() {
|
if projection.is_empty() {
|
||||||
@ -1064,15 +1068,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
if !self.mir_assign_valid_types(a, b) {
|
if !self.mir_assign_valid_types(a, b) {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!("Cannot {op:?} compare incompatible types {a:?} and {b:?}"),
|
format!("Cannot {op:?} compare incompatible types {a} and {b}"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if a != b {
|
} else if a != b {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!(
|
format!("Cannot perform binary op {op:?} on unequal types {a} and {b}"),
|
||||||
"Cannot perform binary op {op:?} on unequal types {a:?} and {b:?}"
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1081,7 +1083,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
Offset => {
|
Offset => {
|
||||||
check_kinds!(a, "Cannot offset non-pointer type {:?}", ty::RawPtr(..));
|
check_kinds!(a, "Cannot offset non-pointer type {:?}", ty::RawPtr(..));
|
||||||
if b != self.tcx.types.isize && b != self.tcx.types.usize {
|
if b != self.tcx.types.isize && b != self.tcx.types.usize {
|
||||||
self.fail(location, format!("Cannot offset by non-isize type {b:?}"));
|
self.fail(location, format!("Cannot offset by non-isize type {b}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Eq | Lt | Le | Ne | Ge | Gt => {
|
Eq | Lt | Le | Ne | Ge | Gt => {
|
||||||
@ -1313,7 +1315,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
{
|
{
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!("Cannot transmute from non-`Sized` type {op_ty:?}"),
|
format!("Cannot transmute from non-`Sized` type {op_ty}"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if !self
|
if !self
|
||||||
@ -1340,7 +1342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
Rvalue::NullaryOp(NullOp::OffsetOf(indices), container) => {
|
Rvalue::NullaryOp(NullOp::OffsetOf(indices), container) => {
|
||||||
let fail_out_of_bounds = |this: &mut Self, location, field, ty| {
|
let fail_out_of_bounds = |this: &mut Self, location, field, ty| {
|
||||||
this.fail(location, format!("Out of bounds field {field:?} for {ty:?}"));
|
this.fail(location, format!("Out of bounds field {field:?} for {ty}"));
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut current_ty = *container;
|
let mut current_ty = *container;
|
||||||
@ -1374,7 +1376,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
_ => {
|
_ => {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!("Cannot get offset ({variant:?}, {field:?}) from type {current_ty:?}"),
|
format!("Cannot get offset ({variant:?}, {field:?}) from type {current_ty}"),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1403,7 +1405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) {
|
if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!("Cannot wrap {unwrapped_ty:?} into unsafe binder {binder_ty:?}"),
|
format!("Cannot wrap {unwrapped_ty} into unsafe binder {binder_ty:?}"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1489,24 +1491,27 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
// since CopyNonOverlapping is parametrized by 1 type,
|
// since CopyNonOverlapping is parametrized by 1 type,
|
||||||
// we only need to check that they are equal and not keep an extra parameter.
|
// we only need to check that they are equal and not keep an extra parameter.
|
||||||
if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) {
|
if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) {
|
||||||
self.fail(location, format!("bad arg ({op_src_ty:?} != {op_dst_ty:?})"));
|
self.fail(location, format!("bad arg ({op_src_ty} != {op_dst_ty})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let op_cnt_ty = count.ty(&self.body.local_decls, self.tcx);
|
let op_cnt_ty = count.ty(&self.body.local_decls, self.tcx);
|
||||||
if op_cnt_ty != self.tcx.types.usize {
|
if op_cnt_ty != self.tcx.types.usize {
|
||||||
self.fail(location, format!("bad arg ({op_cnt_ty:?} != usize)"))
|
self.fail(location, format!("bad arg ({op_cnt_ty} != usize)"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementKind::SetDiscriminant { place, .. } => {
|
StatementKind::SetDiscriminant { place, .. } => {
|
||||||
if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) {
|
if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) {
|
||||||
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
|
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
|
||||||
}
|
}
|
||||||
let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
|
let pty = place.ty(&self.body.local_decls, self.tcx).ty;
|
||||||
if !matches!(pty, ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..)) {
|
if !matches!(
|
||||||
|
pty.kind(),
|
||||||
|
ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..)
|
||||||
|
) {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!(
|
format!(
|
||||||
"`SetDiscriminant` is only allowed on ADTs and coroutines, not {pty:?}"
|
"`SetDiscriminant` is only allowed on ADTs and coroutines, not {pty}"
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1555,7 +1560,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
if ScalarInt::try_from_uint(value, size).is_none() {
|
if ScalarInt::try_from_uint(value, size).is_none() {
|
||||||
self.fail(
|
self.fail(
|
||||||
location,
|
location,
|
||||||
format!("the value {value:#x} is not a proper {switch_ty:?}"),
|
format!("the value {value:#x} is not a proper {switch_ty}"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ pub fn edit_distance_with_substrings(a: &str, b: &str, limit: usize) -> Option<u
|
|||||||
// Check one isn't less than half the length of the other. If this is true then there is a
|
// Check one isn't less than half the length of the other. If this is true then there is a
|
||||||
// big difference in length.
|
// big difference in length.
|
||||||
let big_len_diff = (n * 2) < m || (m * 2) < n;
|
let big_len_diff = (n * 2) < m || (m * 2) < n;
|
||||||
let len_diff = if n < m { m - n } else { n - m };
|
let len_diff = m.abs_diff(n);
|
||||||
let distance = edit_distance(a, b, limit + len_diff)?;
|
let distance = edit_distance(a, b, limit + len_diff)?;
|
||||||
|
|
||||||
// This is the crux, subtracting length difference means exact substring matches will now be 0
|
// This is the crux, subtracting length difference means exact substring matches will now be 0
|
||||||
|
@ -74,7 +74,6 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
|
|||||||
let ours;
|
let ours;
|
||||||
let mut name;
|
let mut name;
|
||||||
let mut tries = 0;
|
let mut tries = 0;
|
||||||
let mut reject_remote_clients_flag = c::PIPE_REJECT_REMOTE_CLIENTS;
|
|
||||||
loop {
|
loop {
|
||||||
tries += 1;
|
tries += 1;
|
||||||
name = format!(
|
name = format!(
|
||||||
@ -96,7 +95,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
|
|||||||
c::PIPE_TYPE_BYTE
|
c::PIPE_TYPE_BYTE
|
||||||
| c::PIPE_READMODE_BYTE
|
| c::PIPE_READMODE_BYTE
|
||||||
| c::PIPE_WAIT
|
| c::PIPE_WAIT
|
||||||
| reject_remote_clients_flag,
|
| c::PIPE_REJECT_REMOTE_CLIENTS,
|
||||||
1,
|
1,
|
||||||
PIPE_BUFFER_CAPACITY,
|
PIPE_BUFFER_CAPACITY,
|
||||||
PIPE_BUFFER_CAPACITY,
|
PIPE_BUFFER_CAPACITY,
|
||||||
@ -112,30 +111,15 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
|
|||||||
//
|
//
|
||||||
// Don't try again too much though as this could also perhaps be a
|
// Don't try again too much though as this could also perhaps be a
|
||||||
// legit error.
|
// legit error.
|
||||||
// If `ERROR_INVALID_PARAMETER` is returned, this probably means we're
|
|
||||||
// running on pre-Vista version where `PIPE_REJECT_REMOTE_CLIENTS` is
|
|
||||||
// not supported, so we continue retrying without it. This implies
|
|
||||||
// reduced security on Windows versions older than Vista by allowing
|
|
||||||
// connections to this pipe from remote machines.
|
|
||||||
// Proper fix would increase the number of FFI imports and introduce
|
|
||||||
// significant amount of Windows XP specific code with no clean
|
|
||||||
// testing strategy
|
|
||||||
// For more info, see https://github.com/rust-lang/rust/pull/37677.
|
|
||||||
if handle == c::INVALID_HANDLE_VALUE {
|
if handle == c::INVALID_HANDLE_VALUE {
|
||||||
let error = api::get_last_error();
|
let error = api::get_last_error();
|
||||||
if tries < 10 {
|
if tries < 10 && error == WinError::ACCESS_DENIED {
|
||||||
if error == WinError::ACCESS_DENIED {
|
continue;
|
||||||
continue;
|
} else {
|
||||||
} else if reject_remote_clients_flag != 0
|
return Err(io::Error::from_raw_os_error(error.code as i32));
|
||||||
&& error == WinError::INVALID_PARAMETER
|
|
||||||
{
|
|
||||||
reject_remote_clients_flag = 0;
|
|
||||||
tries -= 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Err(io::Error::from_raw_os_error(error.code as i32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ours = Handle::from_raw_handle(handle);
|
ours = Handle::from_raw_handle(handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -70,4 +70,5 @@ the `-mmacosx-version-min=...`, `-miphoneos-version-min=...` or similar flags
|
|||||||
to disambiguate.
|
to disambiguate.
|
||||||
|
|
||||||
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
||||||
environment variable.
|
environment variable, or will be inferred when compiling on host macOS using
|
||||||
|
roughly the same logic as `xcrun --sdk macosx --show-sdk-path`.
|
||||||
|
@ -20,7 +20,8 @@ These targets are cross-compiled, and require the corresponding macOS SDK
|
|||||||
iOS-specific headers, as provided by Xcode 11 or higher.
|
iOS-specific headers, as provided by Xcode 11 or higher.
|
||||||
|
|
||||||
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
||||||
environment variable.
|
environment variable, or will be inferred when compiling on host macOS using
|
||||||
|
roughly the same logic as `xcrun --sdk macosx --show-sdk-path`.
|
||||||
|
|
||||||
### OS version
|
### OS version
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ These targets are cross-compiled, and require the corresponding iOS SDK
|
|||||||
ARM64 targets, Xcode 12 or higher is required.
|
ARM64 targets, Xcode 12 or higher is required.
|
||||||
|
|
||||||
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
||||||
environment variable.
|
environment variable, or will be inferred when compiling on host macOS using
|
||||||
|
roughly the same logic as `xcrun --sdk iphoneos --show-sdk-path`.
|
||||||
|
|
||||||
### OS version
|
### OS version
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ These targets are cross-compiled, and require the corresponding tvOS SDK
|
|||||||
ARM64 targets, Xcode 12 or higher is required.
|
ARM64 targets, Xcode 12 or higher is required.
|
||||||
|
|
||||||
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
||||||
environment variable.
|
environment variable, or will be inferred when compiling on host macOS using
|
||||||
|
roughly the same logic as `xcrun --sdk appletvos --show-sdk-path`.
|
||||||
|
|
||||||
### OS version
|
### OS version
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ These targets are cross-compiled, and require the corresponding visionOS SDK
|
|||||||
(`XROS.sdk` or `XRSimulator.sdk`), as provided by Xcode 15 or newer.
|
(`XROS.sdk` or `XRSimulator.sdk`), as provided by Xcode 15 or newer.
|
||||||
|
|
||||||
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
||||||
environment variable.
|
environment variable, or will be inferred when compiling on host macOS using
|
||||||
|
roughly the same logic as `xcrun --sdk xros --show-sdk-path`.
|
||||||
|
|
||||||
### OS version
|
### OS version
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ These targets are cross-compiled, and require the corresponding watchOS SDK
|
|||||||
ARM64 targets, Xcode 12 or higher is required.
|
ARM64 targets, Xcode 12 or higher is required.
|
||||||
|
|
||||||
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
The path to the SDK can be passed to `rustc` using the common `SDKROOT`
|
||||||
environment variable.
|
environment variable, or will be inferred when compiling on host macOS using
|
||||||
|
roughly the same logic as `xcrun --sdk watchos --show-sdk-path`.
|
||||||
|
|
||||||
### OS version
|
### OS version
|
||||||
|
|
||||||
|
36
tests/ui/mir/inline-causes-trimmed-paths.rs
Normal file
36
tests/ui/mir/inline-causes-trimmed-paths.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//@ build-pass
|
||||||
|
//@ compile-flags: -Zinline-mir
|
||||||
|
|
||||||
|
trait Storage {
|
||||||
|
type Buffer: ?Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Array<const N: usize>;
|
||||||
|
impl<const N: usize> Storage for Array<N> {
|
||||||
|
type Buffer = [(); N];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Slice;
|
||||||
|
impl Storage for Slice {
|
||||||
|
type Buffer = [()];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Wrap<S: Storage> {
|
||||||
|
_b: S::Buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn coerce<const N: usize>(this: &Wrap<Array<N>>) -> &Wrap<Slice>
|
||||||
|
where
|
||||||
|
Array<N>: Storage,
|
||||||
|
{
|
||||||
|
coerce_again(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn coerce_again<const N: usize>(this: &Wrap<Array<N>>) -> &Wrap<Slice> {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let inner: Wrap<Array<1>> = Wrap { _b: [(); 1] };
|
||||||
|
let _: &Wrap<Slice> = coerce(&inner);
|
||||||
|
}
|
@ -10,9 +10,16 @@
|
|||||||
// Ref: https://github.com/rust-lang/rust/issues/102246
|
// Ref: https://github.com/rust-lang/rust/issues/102246
|
||||||
|
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::thread;
|
use std::thread::Builder;
|
||||||
|
|
||||||
const N: usize = 32_768;
|
const N: usize = 32_768;
|
||||||
|
const SLOTS: usize = 32;
|
||||||
|
// Use a stack size that's smaller than N * SLOTS, proving the allocation is on the heap.
|
||||||
|
//
|
||||||
|
// The test explicitly specifies the stack size, because not all platforms have the same default
|
||||||
|
// size.
|
||||||
|
const STACK_SIZE: usize = (N*SLOTS) - 1;
|
||||||
|
|
||||||
struct BigStruct {
|
struct BigStruct {
|
||||||
_data: [u8; N],
|
_data: [u8; N],
|
||||||
}
|
}
|
||||||
@ -20,10 +27,13 @@ struct BigStruct {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let (sender, receiver) = channel::<BigStruct>();
|
let (sender, receiver) = channel::<BigStruct>();
|
||||||
|
|
||||||
let thread1 = thread::spawn(move || {
|
let thread1 = Builder::new().stack_size(STACK_SIZE).spawn(move || {
|
||||||
sender.send(BigStruct { _data: [0u8; N] }).unwrap();
|
sender.send(BigStruct { _data: [0u8; N] }).unwrap();
|
||||||
});
|
}).expect("thread1 should spawn successfully");
|
||||||
|
|
||||||
thread1.join().unwrap();
|
thread1.join().unwrap();
|
||||||
for _data in receiver.try_iter() {}
|
|
||||||
|
let thread2 = Builder::new().stack_size(STACK_SIZE).spawn(move || {
|
||||||
|
for _data in receiver.try_iter() {}
|
||||||
|
}).expect("thread2 should spawn successfully");
|
||||||
|
thread2.join().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -1098,6 +1098,7 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
|
|||||||
users_on_vacation = [
|
users_on_vacation = [
|
||||||
"jyn514",
|
"jyn514",
|
||||||
"ChrisDenton",
|
"ChrisDenton",
|
||||||
|
"saethlin",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[assign.warn_non_default_branch.exceptions]]
|
[[assign.warn_non_default_branch.exceptions]]
|
||||||
|
Loading…
Reference in New Issue
Block a user