11
11
use std:: path:: { self , Path , PathBuf } ;
12
12
use std:: ffi:: OsString ;
13
13
14
- // Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...`
15
- // (a verbatim path). This form of path is generally pretty rare, but the
16
- // implementation of `fs::canonicalize` currently generates paths of this form,
17
- // meaning that we're going to be passing quite a few of these down to gcc.
14
+ // Unfortunately, on windows, it looks like msvcrt.dll is silently translating
15
+ // verbatim paths under the hood to non-verbatim paths! This manifests itself as
16
+ // gcc looking like it cannot accept paths of the form `\\?\C:\...`, but the
17
+ // real bug seems to lie in msvcrt.dll.
18
+ //
19
+ // Verbatim paths are generally pretty rare, but the implementation of
20
+ // `fs::canonicalize` currently generates paths of this form, meaning that we're
21
+ // going to be passing quite a few of these down to gcc, so we need to deal with
22
+ // this case.
18
23
//
19
24
// For now we just strip the "verbatim prefix" of `\\?\` from the path. This
20
25
// will probably lose information in some cases, but there's not a whole lot
21
- // more we can do with a buggy gcc...
26
+ // more we can do with a buggy msvcrt...
27
+ //
28
+ // For some more information, see this comment:
29
+ // https://github.com/rust-lang/rust/issues/25505#issuecomment-102876737
22
30
pub fn fix_windows_verbatim_for_gcc ( p : & Path ) -> PathBuf {
23
31
if !cfg ! ( windows) {
24
32
return p. to_path_buf ( )
@@ -28,11 +36,20 @@ pub fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
28
36
Some ( path:: Component :: Prefix ( p) ) => p,
29
37
_ => return p. to_path_buf ( ) ,
30
38
} ;
31
- let disk = match prefix. kind ( ) {
32
- path:: Prefix :: VerbatimDisk ( disk) => disk,
33
- _ => return p. to_path_buf ( ) ,
34
- } ;
35
- let mut base = OsString :: from ( format ! ( "{}:" , disk as char ) ) ;
36
- base. push ( components. as_path ( ) ) ;
37
- PathBuf :: from ( base)
39
+ match prefix. kind ( ) {
40
+ path:: Prefix :: VerbatimDisk ( disk) => {
41
+ let mut base = OsString :: from ( format ! ( "{}:" , disk as char ) ) ;
42
+ base. push ( components. as_path ( ) ) ;
43
+ PathBuf :: from ( base)
44
+ }
45
+ path:: Prefix :: VerbatimUNC ( server, share) => {
46
+ let mut base = OsString :: from ( r"\\" ) ;
47
+ base. push ( server) ;
48
+ base. push ( r"\" ) ;
49
+ base. push ( share) ;
50
+ base. push ( components. as_path ( ) ) ;
51
+ PathBuf :: from ( base)
52
+ }
53
+ _ => p. to_path_buf ( ) ,
54
+ }
38
55
}
0 commit comments