From 2627ae32f28a05e09394a7810ab0f152714f95c1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 28 May 2015 16:46:19 -0700 Subject: [PATCH] rustc: Fixup verbatim UNC paths as well on Windows The compiler already has special support for fixing up verbatim paths with disks on Windows to something that can be correctly passed down to gcc, and this commit adds support for verbatim UNC paths as well. Closes #25505 --- src/librustc/util/fs.rs | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/librustc/util/fs.rs b/src/librustc/util/fs.rs index 3ae78fa7c19..4936e049ef2 100644 --- a/src/librustc/util/fs.rs +++ b/src/librustc/util/fs.rs @@ -11,14 +11,22 @@ use std::path::{self, Path, PathBuf}; use std::ffi::OsString; -// Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...` -// (a verbatim path). This form of path is generally pretty rare, but the -// implementation of `fs::canonicalize` currently generates paths of this form, -// meaning that we're going to be passing quite a few of these down to gcc. +// Unfortunately, on windows, it looks like msvcrt.dll is silently translating +// verbatim paths under the hood to non-verbatim paths! This manifests itself as +// gcc looking like it cannot accept paths of the form `\\?\C:\...`, but the +// real bug seems to lie in msvcrt.dll. +// +// Verbatim paths are generally pretty rare, but the implementation of +// `fs::canonicalize` currently generates paths of this form, meaning that we're +// going to be passing quite a few of these down to gcc, so we need to deal with +// this case. // // For now we just strip the "verbatim prefix" of `\\?\` from the path. This // will probably lose information in some cases, but there's not a whole lot -// more we can do with a buggy gcc... +// more we can do with a buggy msvcrt... +// +// For some more information, see this comment: +// https://github.com/rust-lang/rust/issues/25505#issuecomment-102876737 pub fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf { if !cfg!(windows) { return p.to_path_buf() @@ -28,11 +36,20 @@ pub fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf { Some(path::Component::Prefix(p)) => p, _ => return p.to_path_buf(), }; - let disk = match prefix.kind() { - path::Prefix::VerbatimDisk(disk) => disk, - _ => return p.to_path_buf(), - }; - let mut base = OsString::from(format!("{}:", disk as char)); - base.push(components.as_path()); - PathBuf::from(base) + match prefix.kind() { + path::Prefix::VerbatimDisk(disk) => { + let mut base = OsString::from(format!("{}:", disk as char)); + base.push(components.as_path()); + PathBuf::from(base) + } + path::Prefix::VerbatimUNC(server, share) => { + let mut base = OsString::from(r"\\"); + base.push(server); + base.push(r"\"); + base.push(share); + base.push(components.as_path()); + PathBuf::from(base) + } + _ => p.to_path_buf(), + } }