@@ -631,3 +631,179 @@ feat2 = ["bar?/feat"]
631631 ) ] ,
632632 ) ;
633633}
634+
635+ #[ cargo_test]
636+ fn disabled_weak_direct_dep ( ) {
637+ // Issue #10801
638+ // A weak direct dependency should be included in Cargo.lock,
639+ // even if disabled, and even if on lockfile version 4.
640+ Package :: new ( "bar" , "1.0.0" )
641+ . feature ( "feat" , & [ ] )
642+ . file ( "src/lib.rs" , & require ( & [ "feat" ] , & [ ] ) )
643+ . publish ( ) ;
644+ let p = project ( )
645+ . file (
646+ "Cargo.toml" ,
647+ r#"
648+ [package]
649+ name = "foo"
650+ version = "0.1.0"
651+
652+ [dependencies]
653+ bar = { version = "1.0", optional = true }
654+
655+ [features]
656+ f1 = ["bar?/feat"]
657+ "# ,
658+ )
659+ . file ( "src/lib.rs" , & require ( & [ "f1" ] , & [ ] ) )
660+ . build ( ) ;
661+
662+ p. cargo ( "generate-lockfile" ) . run ( ) ;
663+
664+ let lockfile = p. read_lockfile ( ) ;
665+ assert ! (
666+ lockfile. contains( r#"version = 3"# ) ,
667+ "lockfile version is not 3!\n {lockfile}" ,
668+ ) ;
669+ // Previous behavior: bar is inside lockfile.
670+ assert ! (
671+ lockfile. contains( r#"name = "bar""# ) ,
672+ "bar not found\n {lockfile}" ,
673+ ) ;
674+
675+ // Update to new lockfile version
676+ let new_lockfile = lockfile. replace ( "version = 3" , "version = 4" ) ;
677+ p. change_file ( "Cargo.lock" , & new_lockfile) ;
678+
679+ p. cargo ( "check --features f1" )
680+ . with_stderr (
681+ "\
682+ [CHECKING] foo v0.1.0 [..]
683+ [FINISHED] [..]
684+ " ,
685+ )
686+ . run ( ) ;
687+
688+ let lockfile = p. read_lockfile ( ) ;
689+ assert ! (
690+ lockfile. contains( r#"version = 4"# ) ,
691+ "lockfile version is not 4!\n {lockfile}" ,
692+ ) ;
693+ // New behavior: bar is still there because it is a direct (optional) dependency.
694+ assert ! (
695+ lockfile. contains( r#"name = "bar""# ) ,
696+ "bar not found\n {lockfile}" ,
697+ ) ;
698+
699+ p. cargo ( "check --features f1,bar" )
700+ . with_stderr (
701+ "\
702+ [DOWNLOADING] crates ...
703+ [DOWNLOADED] bar v1.0.0 [..]
704+ [CHECKING] bar v1.0.0
705+ [CHECKING] foo v0.1.0 [..]
706+ [FINISHED] [..]
707+ " ,
708+ )
709+ . run ( ) ;
710+ }
711+
712+ #[ cargo_test]
713+ fn disabled_weak_optional_deps ( ) {
714+ // Issue #10801
715+ // A weak dependency of a dependency should not be included in Cargo.lock,
716+ // at least on lockfile version 4.
717+ Package :: new ( "bar" , "1.0.0" )
718+ . feature ( "feat" , & [ ] )
719+ . file ( "src/lib.rs" , & require ( & [ "feat" ] , & [ ] ) )
720+ . publish ( ) ;
721+ Package :: new ( "dep" , "1.0.0" )
722+ . add_dep ( Dependency :: new ( "bar" , "1.0" ) . optional ( true ) )
723+ . feature ( "feat" , & [ "bar?/feat" ] )
724+ . file ( "src/lib.rs" , "" )
725+ . publish ( ) ;
726+ let p = project ( )
727+ . file (
728+ "Cargo.toml" ,
729+ r#"
730+ [package]
731+ name = "foo"
732+ version = "0.1.0"
733+
734+ [dependencies]
735+ dep = { version = "1.0", features = ["feat"] }
736+ "# ,
737+ )
738+ . file ( "src/lib.rs" , "" )
739+ . build ( ) ;
740+
741+ p. cargo ( "generate-lockfile" ) . run ( ) ;
742+
743+ let lockfile = p. read_lockfile ( ) ;
744+
745+ assert ! (
746+ lockfile. contains( r#"version = 3"# ) ,
747+ "lockfile version is not 3!\n {lockfile}" ,
748+ ) ;
749+ // Previous behavior: bar is inside lockfile.
750+ assert ! (
751+ lockfile. contains( r#"name = "bar""# ) ,
752+ "bar not found\n {lockfile}" ,
753+ ) ;
754+
755+ // Update to new lockfile version
756+ let new_lockfile = lockfile. replace ( "version = 3" , "version = 4" ) ;
757+ p. change_file ( "Cargo.lock" , & new_lockfile) ;
758+
759+ // Note how we are not downloading bar here
760+ p. cargo ( "check" )
761+ . with_stderr (
762+ "\
763+ [DOWNLOADING] crates ...
764+ [DOWNLOADED] dep v1.0.0 [..]
765+ [CHECKING] dep v1.0.0
766+ [CHECKING] foo v0.1.0 [..]
767+ [FINISHED] [..]
768+ " ,
769+ )
770+ . run ( ) ;
771+
772+ let lockfile = p. read_lockfile ( ) ;
773+ assert ! (
774+ lockfile. contains( r#"version = 4"# ) ,
775+ "lockfile version is not 4!\n {lockfile}" ,
776+ ) ;
777+ // New behavior: bar is gone.
778+ assert ! (
779+ !lockfile. contains( r#"name = "bar""# ) ,
780+ "bar inside lockfile!\n {lockfile}" ,
781+ ) ;
782+
783+ // Note how we are not downloading bar here
784+ p. cargo ( "check --features dep/bar" )
785+ . with_stderr (
786+ "\
787+ [DOWNLOADING] crates ...
788+ [DOWNLOADED] bar v1.0.0 [..]
789+ [CHECKING] bar v1.0.0
790+ [CHECKING] dep v1.0.0
791+ [CHECKING] foo v0.1.0 [..]
792+ [FINISHED] [..]
793+ " ,
794+ )
795+ . run ( ) ;
796+
797+ let lockfile = p. read_lockfile ( ) ;
798+ assert ! (
799+ lockfile. contains( r#"version = 4"# ) ,
800+ "lockfile version is not 4!\n {lockfile}" ,
801+ ) ;
802+ // bar is still not there, even if dep/bar is enabled on the command line.
803+ // This might be unintuitive, but it matches what happens on lock version 3
804+ // if there was no optional feat = bar?/feat feature in bar.
805+ assert ! (
806+ !lockfile. contains( r#"name = "bar""# ) ,
807+ "bar inside lockfile!\n {lockfile}" ,
808+ ) ;
809+ }
0 commit comments