diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 36b44d0169c9c..6024896b065bc 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -10,7 +10,7 @@ use std::env; use std::fmt::{self, Display}; use std::fs; use std::io::IsTerminal; -use std::path::{Path, PathBuf}; +use std::path::{absolute, Path, PathBuf}; use std::process::Command; use std::str::FromStr; use std::sync::OnceLock; @@ -1437,7 +1437,7 @@ impl Config { // To avoid writing to random places on the file system, `config.out` needs to be an absolute path. if !config.out.is_absolute() { // `canonicalize` requires the path to already exist. Use our vendored copy of `absolute` instead. - config.out = crate::utils::helpers::absolute(&config.out); + config.out = absolute(&config.out).expect("can't make empty path absolute"); } config.initial_rustc = if let Some(rustc) = rustc { diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 278359cb08e39..1df3432353581 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -331,115 +331,6 @@ fn dir_up_to_date(src: &Path, threshold: SystemTime) -> bool { }) } -/// Copied from `std::path::absolute` until it stabilizes. -/// -/// FIXME: this shouldn't exist. -pub(crate) fn absolute(path: &Path) -> PathBuf { - if path.as_os_str().is_empty() { - panic!("can't make empty path absolute"); - } - #[cfg(unix)] - { - t!(absolute_unix(path), format!("could not make path absolute: {}", path.display())) - } - #[cfg(windows)] - { - t!(absolute_windows(path), format!("could not make path absolute: {}", path.display())) - } - #[cfg(not(any(unix, windows)))] - { - println!("WARNING: bootstrap is not supported on non-unix platforms"); - t!(std::fs::canonicalize(t!(std::env::current_dir()))).join(path) - } -} - -#[cfg(unix)] -/// Make a POSIX path absolute without changing its semantics. -fn absolute_unix(path: &Path) -> io::Result { - // This is mostly a wrapper around collecting `Path::components`, with - // exceptions made where this conflicts with the POSIX specification. - // See 4.13 Pathname Resolution, IEEE Std 1003.1-2017 - // https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 - - use std::os::unix::prelude::OsStrExt; - let mut components = path.components(); - let path_os = path.as_os_str().as_bytes(); - - let mut normalized = if path.is_absolute() { - // "If a pathname begins with two successive characters, the - // first component following the leading characters may be - // interpreted in an implementation-defined manner, although more than - // two leading characters shall be treated as a single - // character." - if path_os.starts_with(b"//") && !path_os.starts_with(b"///") { - components.next(); - PathBuf::from("//") - } else { - PathBuf::new() - } - } else { - env::current_dir()? - }; - normalized.extend(components); - - // "Interfaces using pathname resolution may specify additional constraints - // when a pathname that does not name an existing directory contains at - // least one non- character and contains one or more trailing - // characters". - // A trailing is also meaningful if "a symbolic link is - // encountered during pathname resolution". - - if path_os.ends_with(b"/") { - normalized.push(""); - } - - Ok(normalized) -} - -#[cfg(windows)] -fn absolute_windows(path: &std::path::Path) -> std::io::Result { - use std::ffi::OsString; - use std::io::Error; - use std::os::windows::ffi::{OsStrExt, OsStringExt}; - use std::ptr::null_mut; - #[link(name = "kernel32")] - extern "system" { - fn GetFullPathNameW( - lpFileName: *const u16, - nBufferLength: u32, - lpBuffer: *mut u16, - lpFilePart: *mut *const u16, - ) -> u32; - } - - unsafe { - // encode the path as UTF-16 - let path: Vec = path.as_os_str().encode_wide().chain([0]).collect(); - let mut buffer = Vec::new(); - // Loop until either success or failure. - loop { - // Try to get the absolute path - let len = GetFullPathNameW( - path.as_ptr(), - buffer.len().try_into().unwrap(), - buffer.as_mut_ptr(), - null_mut(), - ); - match len as usize { - // Failure - 0 => return Err(Error::last_os_error()), - // Buffer is too small, resize. - len if len > buffer.len() => buffer.resize(len, 0), - // Success! - len => { - buffer.truncate(len); - return Ok(OsString::from_wide(&buffer).into()); - } - } - } - } -} - /// Adapted from /// /// When `clang-cl` is used with instrumentation, we need to add clang's runtime library resource diff --git a/src/bootstrap/src/utils/helpers/tests.rs b/src/bootstrap/src/utils/helpers/tests.rs index 9cfaa3eb67b5c..2ab3952ae5a1d 100644 --- a/src/bootstrap/src/utils/helpers/tests.rs +++ b/src/bootstrap/src/utils/helpers/tests.rs @@ -25,27 +25,6 @@ fn test_make() { } } -#[cfg(unix)] -#[test] -fn test_absolute_unix() { - use crate::utils::helpers::absolute_unix; - - // Test an absolute path - let path = PathBuf::from("/home/user/file.txt"); - assert_eq!(absolute_unix(&path).unwrap(), PathBuf::from("/home/user/file.txt")); - - // Test an absolute path with double leading slashes - let path = PathBuf::from("//root//file.txt"); - assert_eq!(absolute_unix(&path).unwrap(), PathBuf::from("//root/file.txt")); - - // Test a relative path - let path = PathBuf::from("relative/path"); - assert_eq!( - absolute_unix(&path).unwrap(), - std::env::current_dir().unwrap().join("relative/path") - ); -} - #[test] fn test_beta_rev_parsing() { // single digit revision