@@ -1558,7 +1558,7 @@ impl Step for RustcLink {
15581558 run. never ( )
15591559 }
15601560
1561- /// Same as `std_link `, only for librustc
1561+ /// Same as `StdLink `, only for librustc
15621562 fn run ( self , builder : & Builder < ' _ > ) {
15631563 let build_compiler = self . build_compiler ;
15641564 let sysroot_compiler = self . sysroot_compiler ;
@@ -2418,13 +2418,28 @@ pub fn add_to_sysroot(
24182418 t ! ( fs:: create_dir_all( sysroot_dst) ) ;
24192419 t ! ( fs:: create_dir_all( sysroot_host_dst) ) ;
24202420 t ! ( fs:: create_dir_all( self_contained_dst) ) ;
2421+
2422+ let mut rustc_crates = HashSet :: new ( ) ;
24212423 for ( path, dependency_type) in builder. read_stamp_file ( stamp) {
2424+ let filename = path. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
24222425 let dst = match dependency_type {
24232426 DependencyType :: Host => sysroot_host_dst,
24242427 DependencyType :: Target => sysroot_dst,
24252428 DependencyType :: TargetSelfContained => self_contained_dst,
24262429 } ;
2427- builder. copy_link ( & path, & dst. join ( path. file_name ( ) . unwrap ( ) ) , FileType :: Regular ) ;
2430+ builder. copy_link ( & path, & dst. join ( & filename) , FileType :: Regular ) ;
2431+
2432+ // Check that none of the rustc_* crates have multiple versions. Otherwise using them from
2433+ // the sysroot would cause ambiguity errors. We do allow rustc_hash however as it is an
2434+ // external dependency that we build multiple copies of. It is re-exported by
2435+ // rustc_data_structures, so not being able to use extern crate rustc_hash; is not a big
2436+ // issue.
2437+ if !filename. contains ( "rustc_" ) || filename. contains ( "rustc_hash" ) {
2438+ continue ;
2439+ }
2440+ if !rustc_crates. insert ( filename. split_once ( '-' ) . unwrap ( ) . 0 . to_owned ( ) ) {
2441+ panic ! ( "duplicate rustc crate at {}" , path. display( ) ) ;
2442+ }
24282443 }
24292444}
24302445
@@ -2511,7 +2526,13 @@ pub fn run_cargo(
25112526 if filename. starts_with ( & host_root_dir) {
25122527 // Unless it's a proc macro used in the compiler
25132528 if crate_types. iter ( ) . any ( |t| t == "proc-macro" ) {
2514- deps. push ( ( filename. to_path_buf ( ) , DependencyType :: Host ) ) ;
2529+ // Cargo will compile proc-macros that are part of the rustc workspace twice.
2530+ // Once as libmacro-hash.so as build dependency and once as libmacro.so as
2531+ // output artifact. Only keep the former to avoid ambiguity when trying to use
2532+ // the proc macro from the sysroot.
2533+ if filename. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . contains ( "-" ) {
2534+ deps. push ( ( filename. to_path_buf ( ) , DependencyType :: Host ) ) ;
2535+ }
25152536 }
25162537 continue ;
25172538 }
0 commit comments