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