@@ -232,6 +232,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
232
232
this. alloc_os_str_as_c_str ( & os_str, memkind)
233
233
}
234
234
235
+ #[ allow( clippy:: get_first) ]
235
236
fn convert_path < ' a > (
236
237
& self ,
237
238
os_str : Cow < ' a , OsStr > ,
@@ -252,28 +253,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
252
253
} ;
253
254
let mut converted = os_str
254
255
. encode_wide ( )
255
- . map ( |wchar| if wchar == from as u16 { to as u16 } else { wchar } )
256
+ . map ( |wchar| if wchar == from. into ( ) { to. into ( ) } else { wchar } )
256
257
. collect :: < Vec < _ > > ( ) ;
257
258
// We also have to ensure that absolute paths remain absolute.
258
259
match direction {
259
260
PathConversion :: HostToTarget => {
260
261
// If this is an absolute Windows path that starts with a drive letter (`C:/...`
261
262
// after separator conversion), it would not be considered absolute by Unix
262
263
// target code.
263
- if converted. get ( 1 ) . copied ( ) == Some ( ':' as u16 )
264
- && converted. get ( 2 ) . copied ( ) == Some ( '/' as u16 )
264
+ if converted. get ( 1 ) . copied ( ) == Some ( b ':'. into ( ) )
265
+ && converted. get ( 2 ) . copied ( ) == Some ( b '/'. into ( ) )
265
266
{
266
267
// We add a `/` at the beginning, to store the absolute Windows
267
268
// path in something that looks like an absolute Unix path.
268
- converted. insert ( 0 , '/' as u16 ) ;
269
+ converted. insert ( 0 , b '/'. into ( ) ) ;
269
270
}
270
271
}
271
272
PathConversion :: TargetToHost => {
272
273
// If the path is `\C:\`, the leading backslash was probably added by the above code
273
274
// and we should get rid of it again.
274
- if converted. get ( 0 ) . copied ( ) == Some ( '\\' as u16 )
275
- && converted. get ( 2 ) . copied ( ) == Some ( ':' as u16 )
276
- && converted. get ( 3 ) . copied ( ) == Some ( '\\' as u16 )
275
+ if converted. get ( 0 ) . copied ( ) == Some ( b '\\'. into ( ) )
276
+ && converted. get ( 2 ) . copied ( ) == Some ( b ':'. into ( ) )
277
+ && converted. get ( 3 ) . copied ( ) == Some ( b '\\'. into ( ) )
277
278
{
278
279
converted. remove ( 0 ) ;
279
280
}
@@ -288,13 +289,33 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
288
289
PathConversion :: HostToTarget => ( '/' , '\\' ) ,
289
290
PathConversion :: TargetToHost => ( '\\' , '/' ) ,
290
291
} ;
291
- let converted = os_str
292
+ let mut converted = os_str
292
293
. as_bytes ( )
293
294
. iter ( )
294
295
. map ( |& wchar| if wchar == from as u8 { to as u8 } else { wchar } )
295
296
. collect :: < Vec < _ > > ( ) ;
296
- // TODO: Once we actually support file system things on Windows targets, we'll probably
297
- // have to also do something clever for absolute path preservation here, like above.
297
+ // We also have to ensure that absolute paths remain absolute.
298
+ match direction {
299
+ PathConversion :: HostToTarget => {
300
+ // If this start withs a `\`, we add `\\.` so it starts with `\\.\` which is
301
+ // some magic path on Windos that *is* considered absolute.
302
+ if converted. get ( 0 ) . copied ( ) == Some ( b'\\' ) {
303
+ converted. splice ( 0 ..0 , b"\\ \\ ." . iter ( ) . copied ( ) ) ;
304
+ }
305
+ }
306
+ PathConversion :: TargetToHost => {
307
+ // If this starts with `//./`, it was probably added by the above code and we
308
+ // remove the `//.` that got added to get the Unix path back out.
309
+ if converted. get ( 0 ) . copied ( ) == Some ( b'/' )
310
+ && converted. get ( 1 ) . copied ( ) == Some ( b'/' )
311
+ && converted. get ( 2 ) . copied ( ) == Some ( b'.' )
312
+ && converted. get ( 3 ) . copied ( ) == Some ( b'/' )
313
+ {
314
+ // Remove first 3 characters
315
+ converted. splice ( 0 ..3 , std:: iter:: empty ( ) ) ;
316
+ }
317
+ }
318
+ }
298
319
Cow :: Owned ( OsString :: from_vec ( converted) )
299
320
} else {
300
321
// Unix-on-Unix, all is fine.
0 commit comments