@@ -5,7 +5,7 @@ use crate::core::compiler::UnitInterner;
5
5
use crate :: core:: compiler:: { CompileKind , CompileMode , RustcTargetData , Unit } ;
6
6
use crate :: core:: profiles:: { Profiles , UnitFor } ;
7
7
use crate :: core:: resolver:: features:: { CliFeatures , FeaturesFor , ResolvedFeatures } ;
8
- use crate :: core:: resolver:: HasDevUnits ;
8
+ use crate :: core:: resolver:: { EncodableResolve , HasDevUnits } ;
9
9
use crate :: core:: { Dependency , PackageId , PackageSet , Resolve , SourceId , Workspace } ;
10
10
use crate :: ops:: { self , Packages } ;
11
11
use crate :: util:: errors:: CargoResult ;
@@ -125,9 +125,12 @@ pub fn resolve_std<'gctx>(
125
125
// now. Perhaps in the future features will be decoupled from the resolver
126
126
// and it will be easier to control feature selection.
127
127
let current_manifest = src_path. join ( "library/sysroot/Cargo.toml" ) ;
128
- // TODO: Consider doing something to enforce --locked? Or to prevent the
129
- // lock file from being written, such as setting ephemeral.
130
- let mut std_ws = Workspace :: new_virtual ( src_path, current_manifest, virtual_manifest, gctx) ?;
128
+ let mut std_ws =
129
+ Workspace :: new_virtual ( src_path. clone ( ) , current_manifest, virtual_manifest, gctx) ?;
130
+
131
+ // The source checkout isn't managed by us, so setting ephemeral here
132
+ // ensures the lockfile isn't updated.
133
+ std_ws. set_ephemeral ( true ) ;
131
134
// Don't require optional dependencies in this workspace, aka std's own
132
135
// `[dev-dependencies]`. No need for us to generate a `Resolve` which has
133
136
// those included because we'll never use them anyway.
@@ -158,6 +161,47 @@ pub fn resolve_std<'gctx>(
158
161
HasDevUnits :: No ,
159
162
crate :: core:: resolver:: features:: ForceAllTargets :: No ,
160
163
) ?;
164
+
165
+ // Verify that we have resolved to a subset of the lockfile
166
+ let lockfile = std:: fs:: read_to_string ( & src_path. join ( "Cargo.lock" ) )
167
+ . expect ( "Couldn't read the Rust source's lockfile" ) ;
168
+
169
+ let encoded_lockfile: EncodableResolve = toml:: from_str ( & lockfile) . unwrap ( ) ;
170
+ let lockfile_packages = encoded_lockfile. package ( ) . expect ( "libstd has no packages!" ) ;
171
+
172
+ for resolved_pkg in resolve. targeted_resolve . iter ( ) {
173
+ let pkg_name = resolved_pkg. name ( ) . to_string ( ) ;
174
+ let pkg_ver = resolved_pkg. version ( ) . to_string ( ) ;
175
+ let lockfile_pkg = lockfile_packages. binary_search_by_key (
176
+ & ( pkg_name. as_str ( ) , pkg_ver. as_str ( ) ) ,
177
+ |p| ( p. name ( ) , p. version ( ) )
178
+ )
179
+ . and_then ( |idx| Ok ( & lockfile_packages[ idx] ) )
180
+ . unwrap_or_else ( |_|
181
+ panic ! ( "Standard library's package graph changed during resolution:
182
+ Package '{}' ({}) was present in the resolve but not in the original lockfile" ,
183
+ resolved_pkg. name( ) , resolved_pkg. version( ) )
184
+ ) ;
185
+ // If the lockfile wasn't sorted then the binary search result can be nonsensical
186
+ assert ! ( lockfile_pkg. name( ) == pkg_name) ;
187
+
188
+ for ( dep, _) in resolve. targeted_resolve . deps ( resolved_pkg) {
189
+ lockfile_pkg. dependencies ( )
190
+ . and_then ( |deps| {
191
+ deps. iter ( ) . find ( |pkg| {
192
+ pkg. name ( ) == dep. name ( ) . as_str ( )
193
+ && ( pkg. version ( ) == None
194
+ || pkg. version ( ) == Some ( dep. version ( ) . to_string ( ) . as_str ( ) ) )
195
+ } )
196
+ } )
197
+ . unwrap_or_else ( ||
198
+ panic ! ( "Standard library's package graph changed during resolution:
199
+ Package '{}' ({}) was present as a dependency of '{} ({}) in the resolve but not in the lockfile" ,
200
+ dep. name( ) , dep. version( ) , resolved_pkg. name( ) , resolved_pkg. version( ) )
201
+ ) ;
202
+ }
203
+ }
204
+
161
205
Ok ( (
162
206
resolve. pkg_set ,
163
207
resolve. targeted_resolve ,
0 commit comments