1
+ //! There are 2 sources of facts for the resolver:
2
+ //!
3
+ //! - The Registry tells us for a Dependency what versions are available to fulfil it.
4
+ //! - The Summary tells us for a version (and features) what dependencies need to be fulfilled for it to be activated.
5
+ //!
6
+ //! These constitute immutable facts, the soled ground truth that all other inference depends on.
7
+ //! Theoretically this could all be enumerated ahead of time, but we want to be lazy and only
8
+ //! look up things we need to. The compromise is to cache the results as they are computed.
9
+ //!
10
+ //! The structs in this module impl that cache in all the gory details
11
+
1
12
use std:: cmp:: Ordering ;
2
13
use std:: collections:: { BTreeSet , HashMap , HashSet } ;
3
14
use std:: rc:: Rc ;
@@ -8,7 +19,7 @@ use crate::core::interning::InternedString;
8
19
use crate :: core:: { Dependency , FeatureValue , PackageId , PackageIdSpec , Registry , Summary } ;
9
20
use crate :: util:: errors:: CargoResult ;
10
21
11
- use crate :: core:: resolver:: types:: { Candidate , ConflictReason , DepInfo } ;
22
+ use crate :: core:: resolver:: types:: { Candidate , ConflictReason , DepInfo , FeaturesSet } ;
12
23
use crate :: core:: resolver:: { ActivateResult , Method } ;
13
24
14
25
pub struct RegistryQueryer < ' a > {
@@ -193,12 +204,18 @@ impl<'a> DepsCache<'a> {
193
204
}
194
205
}
195
206
207
+ /// Find out what dependencies will be added by activating `candidate`,
208
+ /// with features described in `method`. Then look up in the `registry`
209
+ /// the candidates that will fulfil each of these dependencies, as it is the
210
+ /// next obvious question.
196
211
pub fn build_deps (
197
212
& mut self ,
198
213
parent : Option < PackageId > ,
199
214
candidate : & Summary ,
200
215
method : & Method ,
201
216
) -> ActivateResult < Rc < ( HashSet < InternedString > , Rc < Vec < DepInfo > > ) > > {
217
+ // if we have calculated a result before, then we can just return it,
218
+ // as it is a "pure" query of its arguments.
202
219
if let Some ( out) = self
203
220
. cache
204
221
. get ( & ( parent, candidate. clone ( ) , method. clone ( ) ) )
@@ -217,7 +234,7 @@ impl<'a> DepsCache<'a> {
217
234
. into_iter ( )
218
235
. map ( |( dep, features) | {
219
236
let candidates = self . registry . query ( & dep) ?;
220
- Ok ( ( dep, candidates, Rc :: new ( features) ) )
237
+ Ok ( ( dep, candidates, features) )
221
238
} )
222
239
. collect :: < CargoResult < Vec < DepInfo > > > ( ) ?;
223
240
@@ -229,22 +246,22 @@ impl<'a> DepsCache<'a> {
229
246
230
247
let out = Rc :: new ( ( used_features, Rc :: new ( deps) ) ) ;
231
248
249
+ // If we succeed we add the result to the cache so we can use it again next time.
250
+ // We dont cache the failure cases as they dont impl Clone.
232
251
self . cache
233
252
. insert ( ( parent, candidate. clone ( ) , method. clone ( ) ) , out. clone ( ) ) ;
234
253
235
254
Ok ( out)
236
255
}
237
256
}
238
257
239
- /// Returns all dependencies and the features we want from them.
258
+ /// Returns the features we ended up using and
259
+ /// all dependencies and the features we want from each of them.
240
260
pub fn resolve_features < ' b > (
241
261
parent : Option < PackageId > ,
242
262
s : & ' b Summary ,
243
263
method : & ' b Method ,
244
- ) -> ActivateResult < (
245
- HashSet < InternedString > ,
246
- Vec < ( Dependency , BTreeSet < InternedString > ) > ,
247
- ) > {
264
+ ) -> ActivateResult < ( HashSet < InternedString > , Vec < ( Dependency , FeaturesSet ) > ) > {
248
265
let dev_deps = match * method {
249
266
Method :: Everything => true ,
250
267
Method :: Required { dev_deps, .. } => dev_deps,
@@ -303,7 +320,7 @@ pub fn resolve_features<'b>(
303
320
. into ( ) ) ;
304
321
}
305
322
}
306
- ret. push ( ( dep. clone ( ) , base) ) ;
323
+ ret. push ( ( dep. clone ( ) , Rc :: new ( base) ) ) ;
307
324
}
308
325
309
326
// Any entries in `reqs.dep` which weren't used are bugs in that the
0 commit comments