@@ -483,20 +483,25 @@ impl PackageGraph {
483483 proc_macro_dylibs : HashMap < PackageId , FilePathBuf > ,
484484 build_scripts : HashMap < PackageId , BuildScript > ,
485485 ) -> Result < Vec < Crate > > {
486- let iter = self . graph . into_iter ( ) . flat_map ( |( id, package) | {
487- // TODO: clones
488- package
489- . clone ( )
490- . targets
491- . into_iter ( )
492- . map ( move |target| ( id. clone ( ) , package. clone ( ) , target) )
493- } ) ;
494-
495486 let mut crates = Vec :: new ( ) ;
496487 let mut deps = Vec :: new ( ) ;
497488 let mut indexes: HashMap < PackageId , usize > = HashMap :: new ( ) ;
498489
499- for ( id, package, target) in iter {
490+ for ( id, package) in self . graph . into_iter ( ) {
491+ // Represents the indices of the `crates` array corresponding to lib targets for this
492+ // package
493+ let lib_indices: Vec < _ > = package
494+ . targets
495+ . iter ( )
496+ . enumerate ( )
497+ . filter ( |( _, target) | matches ! ( TargetKind :: new( & target. kind) , TargetKind :: Lib ) )
498+ . map ( |( i, target) | {
499+ // I *think* this is the right way to handle target names in this
500+ // context...
501+ ( crates. len ( ) + i, target. name . clone ( ) . replace ( '-' , "_" ) )
502+ } )
503+ . collect ( ) ;
504+
500505 let mut env = HashMap :: new ( ) ;
501506 let mut include_dirs = vec ! [ package. manifest_path. parent( ) . unwrap( ) . to_string( ) ] ;
502507 if let Some ( script) = build_scripts. get ( & id) {
@@ -508,57 +513,66 @@ impl PackageGraph {
508513 }
509514 }
510515
511- let target_kind = TargetKind :: new ( & target. kind ) ;
512- if matches ! ( target_kind, TargetKind :: Lib ) {
513- indexes. insert ( id. clone ( ) , crates. len ( ) ) ;
514- }
516+ for target in package. targets {
517+ let target_kind = TargetKind :: new ( & target. kind ) ;
518+ if matches ! ( target_kind, TargetKind :: Lib ) {
519+ indexes. insert ( id. clone ( ) , crates. len ( ) ) ;
520+ }
515521
516- deps. push ( package. dependencies ) ;
517-
518- crates. push ( Crate {
519- display_name : Some ( package. name . to_string ( ) . replace ( '-' , "_" ) ) ,
520- root_module : target. root_module . clone ( ) ,
521- edition : target. edition ,
522- version : Some ( package. version . to_string ( ) ) ,
523- deps : vec ! [ ] ,
524- is_workspace_member : package. is_workspace_member ,
525- is_proc_macro : target. is_proc_macro ( ) ,
526- repository : package. repository . clone ( ) ,
527- build : Some ( BuildInfo {
528- label : target. name . clone ( ) ,
529- build_file : package. manifest_path . to_string ( ) ,
530- target_kind,
531- } ) ,
532- proc_macro_dylib_path : proc_macro_dylibs. get ( & id) . cloned ( ) ,
533- source : Some ( CrateSource {
534- include_dirs,
535- exclude_dirs : vec ! [ ".git" . into( ) , "target" . into( ) ] ,
536- } ) ,
537- // cfg_groups: None,
538- cfg : package
539- . features
540- . clone ( )
541- . into_iter ( )
542- . map ( |feature| format ! ( "feature=\" {feature}\" " ) )
543- . collect ( ) ,
544- target : None ,
545- env,
546- proc_macro_cwd : package
547- . manifest_path
548- . as_file_path ( )
549- . parent ( )
550- . map ( |a| a. into ( ) ) ,
551- } ) ;
522+ // If the target is a bin or a test, we want to include all the lib targets of the
523+ // package in the dependencies for this target. This is what gives bin/test targets
524+ // access to the public items defined in lib targets in the same crate
525+ let mut this_deps = vec ! [ ] ;
526+ if !matches ! ( target_kind, TargetKind :: Lib ) {
527+ for ( crate_index, name) in lib_indices. clone ( ) . into_iter ( ) {
528+ this_deps. push ( Dep { crate_index, name } ) ;
529+ }
530+ }
531+
532+ deps. push ( package. dependencies . clone ( ) ) ;
533+
534+ crates. push ( Crate {
535+ display_name : Some ( package. name . to_string ( ) . replace ( '-' , "_" ) ) ,
536+ root_module : target. root_module . clone ( ) ,
537+ edition : target. edition ,
538+ version : Some ( package. version . to_string ( ) ) ,
539+ deps : this_deps,
540+ is_workspace_member : package. is_workspace_member ,
541+ is_proc_macro : target. is_proc_macro ( ) ,
542+ repository : package. repository . clone ( ) ,
543+ build : Some ( BuildInfo {
544+ label : target. name . clone ( ) ,
545+ build_file : package. manifest_path . to_string ( ) ,
546+ target_kind,
547+ } ) ,
548+ proc_macro_dylib_path : proc_macro_dylibs. get ( & id) . cloned ( ) ,
549+ source : Some ( CrateSource {
550+ include_dirs : include_dirs. clone ( ) ,
551+ exclude_dirs : vec ! [ ".git" . into( ) , "target" . into( ) ] ,
552+ } ) ,
553+ // cfg_groups: None,
554+ cfg : package
555+ . features
556+ . clone ( )
557+ . into_iter ( )
558+ . map ( |feature| format ! ( "feature=\" {feature}\" " ) )
559+ . collect ( ) ,
560+ target : None ,
561+ env : env. clone ( ) ,
562+ proc_macro_cwd : package
563+ . manifest_path
564+ . as_file_path ( )
565+ . parent ( )
566+ . map ( |a| a. into ( ) ) ,
567+ } ) ;
568+ }
552569 }
553570
554571 for ( c, deps) in crates. iter_mut ( ) . zip ( deps. into_iter ( ) ) {
555- c. deps = deps
556- . into_iter ( )
557- . map ( |dep| Dep {
558- name : dep. name ,
559- crate_index : indexes. get ( & dep. id ) . copied ( ) . unwrap ( ) ,
560- } )
561- . collect ( ) ;
572+ c. deps . extend ( deps. into_iter ( ) . map ( |dep| Dep {
573+ name : dep. name ,
574+ crate_index : indexes. get ( & dep. id ) . copied ( ) . unwrap ( ) ,
575+ } ) ) ;
562576
563577 // *shrug* buck does this, not sure if it's necessary
564578 c. deps . sort_by_key ( |dep| dep. crate_index ) ;
0 commit comments