@@ -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;
@@ -1444,6 +1444,13 @@ static CACHED_ENV_VARS: Lazy<HashSet<&'static OsStr>> = Lazy::new(|| {
14441444 . collect ( )
14451445} ) ;
14461446
1447+ const NON_HASHABLE_ARGS : & [ & str ] = & [
1448+ "-fdebug-prefix-map" ,
1449+ "-fmacro-prefix-map" ,
1450+ "-ffile-prefix-map" ,
1451+ "-fdebug-compilation-dir" ,
1452+ ] ;
1453+
14471454/// Compute the hash key of `compiler` compiling `preprocessor_output` with `args`.
14481455pub fn hash_key (
14491456 compiler_digest : & str ,
@@ -1462,7 +1469,13 @@ pub fn hash_key(
14621469 m. update ( & [ plusplus as u8 ] ) ;
14631470 m. update ( CACHE_VERSION ) ;
14641471 m. update ( language. as_str ( ) . as_bytes ( ) ) ;
1465- for arg in arguments {
1472+ ' arg_loop: for arg in arguments {
1473+ for non_hashable in NON_HASHABLE_ARGS {
1474+ if arg. to_string_lossy ( ) . starts_with ( non_hashable) {
1475+ // Skip non-hashable arguments.
1476+ continue ' arg_loop;
1477+ }
1478+ }
14661479 arg. hash ( & mut HashToDigest { digest : & mut m } ) ;
14671480 }
14681481 for hash in extra_hashes {
@@ -1576,6 +1589,32 @@ mod test {
15761589 ) ;
15771590 }
15781591
1592+ #[ test]
1593+ fn test_hash_key_non_hashable_args ( ) {
1594+ let digest = "abcd" ;
1595+ const PREPROCESSED : & [ u8 ] = b"hello world" ;
1596+
1597+ let args = ovec ! [ "arg1" , "arg2" , "arg3" ] ;
1598+ let mut args_with_non_hashable: Vec < OsString > = NON_HASHABLE_ARGS
1599+ . iter ( )
1600+ . map ( |s| OsString :: from ( s) )
1601+ . collect ( ) ;
1602+
1603+ args_with_non_hashable. extend ( args. clone ( ) ) ;
1604+ assert_neq ! (
1605+ hash_key( digest, Language :: C , & args, & [ ] , & [ ] , PREPROCESSED , false ) ,
1606+ hash_key(
1607+ digest,
1608+ Language :: C ,
1609+ & args_with_non_hashable,
1610+ & [ ] ,
1611+ & [ ] ,
1612+ PREPROCESSED ,
1613+ false
1614+ )
1615+ ) ;
1616+ }
1617+
15791618 #[ test]
15801619 fn test_hash_key_preprocessed_content_differs ( ) {
15811620 let args = ovec ! [ "a" , "b" , "c" ] ;
0 commit comments