@@ -351,6 +351,7 @@ pub(crate) struct LinkingFailed<'a> {
351351 pub command : Command ,
352352 pub escaped_output : String ,
353353 pub verbose : bool ,
354+ pub sysroot_dir : PathBuf ,
354355}
355356
356357impl < G : EmissionGuarantee > Diagnostic < ' _ , G > for LinkingFailed < ' _ > {
@@ -364,6 +365,8 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
364365 if self . verbose {
365366 diag. note ( format ! ( "{:?}" , self . command) ) ;
366367 } else {
368+ self . command . env_clear ( ) ;
369+
367370 enum ArgGroup {
368371 Regular ( OsString ) ,
369372 Objects ( usize ) ,
@@ -398,26 +401,55 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
398401 args. push ( ArgGroup :: Regular ( arg) ) ;
399402 }
400403 }
401- self . command . args ( args. into_iter ( ) . map ( |arg_group| match arg_group {
402- ArgGroup :: Regular ( arg) => arg,
403- ArgGroup :: Objects ( n) => OsString :: from ( format ! ( "<{n} object files omitted>" ) ) ,
404- ArgGroup :: Rlibs ( dir, rlibs) => {
405- let mut arg = dir. into_os_string ( ) ;
406- arg. push ( "/{" ) ;
407- let mut first = true ;
408- for rlib in rlibs {
409- if !first {
410- arg. push ( "," ) ;
404+ let crate_hash = regex:: bytes:: Regex :: new ( r"-[0-9a-f]+\.rlib$" ) . unwrap ( ) ;
405+ self . command . args ( args. into_iter ( ) . map ( |arg_group| {
406+ match arg_group {
407+ // SAFETY: we are only matching on ASCII, not any surrogate pairs, so any replacements we do will still be valid.
408+ ArgGroup :: Regular ( arg) => unsafe {
409+ use bstr:: ByteSlice ;
410+ OsString :: from_encoded_bytes_unchecked (
411+ arg. as_encoded_bytes ( ) . replace (
412+ self . sysroot_dir . as_os_str ( ) . as_encoded_bytes ( ) ,
413+ b"<sysroot>" ,
414+ ) ,
415+ )
416+ } ,
417+ ArgGroup :: Objects ( n) => OsString :: from ( format ! ( "<{n} object files omitted>" ) ) ,
418+ ArgGroup :: Rlibs ( mut dir, rlibs) => {
419+ let is_sysroot_dir = match dir. strip_prefix ( & self . sysroot_dir ) {
420+ Ok ( short) => {
421+ dir = Path :: new ( "<sysroot>" ) . join ( short) ;
422+ true
423+ }
424+ Err ( _) => false ,
425+ } ;
426+ let mut arg = dir. into_os_string ( ) ;
427+ arg. push ( "/{" ) ;
428+ let mut first = true ;
429+ for mut rlib in rlibs {
430+ if !first {
431+ arg. push ( "," ) ;
432+ }
433+ first = false ;
434+ if is_sysroot_dir {
435+ // SAFETY: Regex works one byte at a type, and our regex will not match surrogate pairs (because it only matches ascii).
436+ rlib = unsafe {
437+ OsString :: from_encoded_bytes_unchecked (
438+ crate_hash
439+ . replace ( rlib. as_encoded_bytes ( ) , b"-*" )
440+ . into_owned ( ) ,
441+ )
442+ } ;
443+ }
444+ arg. push ( rlib) ;
411445 }
412- first = false ;
413- arg. push ( rlib ) ;
446+ arg . push ( "}.rlib" ) ;
447+ arg
414448 }
415- arg. push ( "}" ) ;
416- arg
417449 }
418450 } ) ) ;
419451
420- diag. note ( format ! ( "{:?}" , self . command) ) ;
452+ diag. note ( format ! ( "{:?}" , self . command) . trim_start_matches ( "env -i" ) . to_owned ( ) ) ;
421453 diag. note ( "some arguments are omitted. use `--verbose` to show all linker arguments" ) ;
422454 }
423455
0 commit comments