@@ -25,8 +25,8 @@ use crate::dist;
2525use crate :: dist:: pkg;
2626use crate :: mock_command:: CommandCreatorSync ;
2727use crate :: util:: {
28- decode_path, encode_path, hash_all, Digest , HashToDigest , MetadataCtimeExt , TimeMacroFinder ,
29- Timestamp ,
28+ decode_path, encode_path, hash_all, Digest , HashToDigest , MetadataCtimeExt , OsStrExt ,
29+ TimeMacroFinder , Timestamp ,
3030} ;
3131use async_trait:: async_trait;
3232use fs_err as fs;
@@ -1435,6 +1435,13 @@ static CACHED_ENV_VARS: Lazy<HashSet<&'static OsStr>> = Lazy::new(|| {
14351435 . collect ( )
14361436} ) ;
14371437
1438+ const NON_HASHABLE_ARGS : & [ & str ] = & [
1439+ "-fdebug-prefix-map" ,
1440+ "-fmacro-prefix-map" ,
1441+ "-ffile-prefix-map" ,
1442+ "-fdebug-compilation-dir" ,
1443+ ] ;
1444+
14381445/// Compute the hash key of `compiler` compiling `preprocessor_output` with `args`.
14391446pub fn hash_key (
14401447 compiler_digest : & str ,
@@ -1453,7 +1460,13 @@ pub fn hash_key(
14531460 m. update ( & [ plusplus as u8 ] ) ;
14541461 m. update ( CACHE_VERSION ) ;
14551462 m. update ( language. as_str ( ) . as_bytes ( ) ) ;
1456- for arg in arguments {
1463+ ' arg_loop: for arg in arguments {
1464+ for non_hashable in NON_HASHABLE_ARGS {
1465+ if arg. to_string_lossy ( ) . starts_with ( non_hashable) {
1466+ // Skip non-hashable arguments.
1467+ continue ' arg_loop;
1468+ }
1469+ }
14571470 arg. hash ( & mut HashToDigest { digest : & mut m } ) ;
14581471 }
14591472 for hash in extra_hashes {
@@ -1567,6 +1580,32 @@ mod test {
15671580 ) ;
15681581 }
15691582
1583+ #[ test]
1584+ fn test_hash_key_non_hashable_args ( ) {
1585+ let digest = "abcd" ;
1586+ const PREPROCESSED : & [ u8 ] = b"hello world" ;
1587+
1588+ let args = ovec ! [ "arg1" , "arg2" , "arg3" ] ;
1589+ let mut args_with_non_hashable: Vec < OsString > = NON_HASHABLE_ARGS
1590+ . iter ( )
1591+ . map ( |s| OsString :: from ( s) )
1592+ . collect ( ) ;
1593+
1594+ args_with_non_hashable. extend ( args. clone ( ) ) ;
1595+ assert_neq ! (
1596+ hash_key( digest, Language :: C , & args, & [ ] , & [ ] , PREPROCESSED , false ) ,
1597+ hash_key(
1598+ digest,
1599+ Language :: C ,
1600+ & args_with_non_hashable,
1601+ & [ ] ,
1602+ & [ ] ,
1603+ PREPROCESSED ,
1604+ false
1605+ )
1606+ ) ;
1607+ }
1608+
15701609 #[ test]
15711610 fn test_hash_key_preprocessed_content_differs ( ) {
15721611 let args = ovec ! [ "a" , "b" , "c" ] ;
0 commit comments