@@ -53,7 +53,7 @@ use std::cmp::{self, Ordering};
5353use std:: fmt;
5454use std:: hash:: Hash ;
5555use std:: ops:: { Add , Sub } ;
56- use std:: path:: PathBuf ;
56+ use std:: path:: { Path , PathBuf } ;
5757use std:: str:: FromStr ;
5858
5959use md5:: Md5 ;
@@ -81,11 +81,61 @@ impl Globals {
8181
8282scoped_tls:: scoped_thread_local!( pub static GLOBALS : Globals ) ;
8383
84+ // FIXME: Perhaps this should not implement Rustc{Decodable, Encodable}
85+ //
86+ // FIXME: We should use this enum or something like it to get rid of the
87+ // use of magic `/rust/1.x/...` paths across the board.
88+ #[ derive( Debug , Eq , PartialEq , Clone , Ord , PartialOrd , Hash , RustcDecodable , RustcEncodable ) ]
89+ #[ derive( HashStable_Generic ) ]
90+ pub enum RealFileName {
91+ Named ( PathBuf ) ,
92+ /// For de-virtualized paths (namely paths into libstd that have been mapped
93+ /// to the appropriate spot on the local host's file system),
94+ Devirtualized {
95+ /// `local_path` is the (host-dependent) local path to the file.
96+ local_path : PathBuf ,
97+ /// `virtual_name` is the stable path rustc will store internally within
98+ /// build artifacts.
99+ virtual_name : PathBuf ,
100+ } ,
101+ }
102+
103+ impl RealFileName {
104+ /// Returns the path suitable for reading from the file system on the local host.
105+ /// Avoid embedding this in build artifacts; see `stable_name` for that.
106+ pub fn local_path ( & self ) -> & Path {
107+ match self {
108+ RealFileName :: Named ( p)
109+ | RealFileName :: Devirtualized { local_path : p, virtual_name : _ } => & p,
110+ }
111+ }
112+
113+ /// Returns the path suitable for reading from the file system on the local host.
114+ /// Avoid embedding this in build artifacts; see `stable_name` for that.
115+ pub fn into_local_path ( self ) -> PathBuf {
116+ match self {
117+ RealFileName :: Named ( p)
118+ | RealFileName :: Devirtualized { local_path : p, virtual_name : _ } => p,
119+ }
120+ }
121+
122+ /// Returns the path suitable for embedding into build artifacts. Note that
123+ /// a virtualized path will not correspond to a valid file system path; see
124+ /// `local_path` for something that is more likely to return paths into the
125+ /// local host file system.
126+ pub fn stable_name ( & self ) -> & Path {
127+ match self {
128+ RealFileName :: Named ( p)
129+ | RealFileName :: Devirtualized { local_path : _, virtual_name : p } => & p,
130+ }
131+ }
132+ }
133+
84134/// Differentiates between real files and common virtual files.
85135#[ derive( Debug , Eq , PartialEq , Clone , Ord , PartialOrd , Hash , RustcDecodable , RustcEncodable ) ]
86136#[ derive( HashStable_Generic ) ]
87137pub enum FileName {
88- Real ( PathBuf ) ,
138+ Real ( RealFileName ) ,
89139 /// Call to `quote!`.
90140 QuoteExpansion ( u64 ) ,
91141 /// Command line.
@@ -109,7 +159,13 @@ impl std::fmt::Display for FileName {
109159 fn fmt ( & self , fmt : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
110160 use FileName :: * ;
111161 match * self {
112- Real ( ref path) => write ! ( fmt, "{}" , path. display( ) ) ,
162+ Real ( RealFileName :: Named ( ref path) ) => write ! ( fmt, "{}" , path. display( ) ) ,
163+ // FIXME: might be nice to display both compoments of Devirtualized.
164+ // But for now (to backport fix for issue #70924), best to not
165+ // perturb diagnostics so its obvious test suite still works.
166+ Real ( RealFileName :: Devirtualized { ref local_path, virtual_name : _ } ) => {
167+ write ! ( fmt, "{}" , local_path. display( ) )
168+ }
113169 QuoteExpansion ( _) => write ! ( fmt, "<quote expansion>" ) ,
114170 MacroExpansion ( _) => write ! ( fmt, "<macro expansion>" ) ,
115171 Anon ( _) => write ! ( fmt, "<anon>" ) ,
@@ -126,7 +182,7 @@ impl std::fmt::Display for FileName {
126182impl From < PathBuf > for FileName {
127183 fn from ( p : PathBuf ) -> Self {
128184 assert ! ( !p. to_string_lossy( ) . ends_with( '>' ) ) ;
129- FileName :: Real ( p )
185+ FileName :: Real ( RealFileName :: Named ( p ) )
130186 }
131187}
132188
0 commit comments