1
1
use std:: collections:: { BTreeMap , BTreeSet , HashMap , HashSet } ;
2
2
use std:: fmt:: Write ;
3
3
4
+ use cargo:: core:: dependency:: DepKind ;
4
5
use cargo:: core:: { Dependency , FeatureMap , FeatureValue , PackageId , Summary } ;
5
6
use cargo:: util:: interning:: { InternedString , INTERNED_DEFAULT } ;
6
7
use varisat:: ExtendFormula ;
@@ -59,29 +60,36 @@ fn sat_at_most_one_by_key<K: std::hash::Hash + Eq>(
59
60
by_keys
60
61
}
61
62
62
- fn find_compatible_dep_summaries_by_name_in_toml (
63
+ fn find_all_compatible_dep_summaries (
63
64
pkg_dependencies : & [ Dependency ] ,
64
65
by_name : & HashMap < InternedString , Vec < Summary > > ,
65
- ) -> HashMap < InternedString , Vec < Summary > > {
66
+ check_dev_dependencies : bool ,
67
+ ) -> HashMap < InternedString , HashMap < DepKind , Vec < Summary > > > {
66
68
let empty_vec = vec ! [ ] ;
67
69
68
- pkg_dependencies
69
- . iter ( )
70
- . map ( |dep| {
71
- let name_in_toml = dep. name_in_toml ( ) ;
70
+ let mut compatible_dep_summaries_map = HashMap :: < _ , HashMap < _ , _ > > :: new ( ) ;
72
71
73
- let compatible_summaries = by_name
74
- . get ( & dep. package_name ( ) )
75
- . unwrap_or ( & empty_vec)
76
- . iter ( )
77
- . filter ( |s| dep. matches_id ( s. package_id ( ) ) )
78
- . filter ( |s| dep. features ( ) . iter ( ) . all ( |f| s. features ( ) . contains_key ( f) ) )
79
- . cloned ( )
80
- . collect :: < Vec < _ > > ( ) ;
72
+ for dep in pkg_dependencies {
73
+ if dep. kind ( ) == DepKind :: Development && !check_dev_dependencies {
74
+ continue ;
75
+ }
81
76
82
- ( name_in_toml, compatible_summaries)
83
- } )
84
- . collect ( )
77
+ let compatible_summaries = by_name
78
+ . get ( & dep. package_name ( ) )
79
+ . unwrap_or ( & empty_vec)
80
+ . iter ( )
81
+ . filter ( |s| dep. matches_id ( s. package_id ( ) ) )
82
+ . filter ( |s| dep. features ( ) . iter ( ) . all ( |f| s. features ( ) . contains_key ( f) ) )
83
+ . cloned ( )
84
+ . collect :: < Vec < _ > > ( ) ;
85
+
86
+ compatible_dep_summaries_map
87
+ . entry ( dep. name_in_toml ( ) )
88
+ . or_default ( )
89
+ . insert ( dep. kind ( ) , compatible_summaries) ;
90
+ }
91
+
92
+ compatible_dep_summaries_map
85
93
}
86
94
87
95
fn process_pkg_features (
@@ -90,7 +98,7 @@ fn process_pkg_features(
90
98
var_for_is_packages_features_used : & HashMap < PackageId , HashMap < InternedString , varisat:: Var > > ,
91
99
pkg_feature_var_map : & HashMap < InternedString , varisat:: Var > ,
92
100
pkg_features : & FeatureMap ,
93
- compatible_dep_summaries_by_name_in_toml : & HashMap < InternedString , Vec < Summary > > ,
101
+ compatible_dep_summaries_map : & HashMap < InternedString , HashMap < DepKind , Vec < Summary > > > ,
94
102
) {
95
103
// add clauses for package features
96
104
for ( & feature_name, feature_values) in pkg_features {
@@ -105,47 +113,61 @@ fn process_pkg_features(
105
113
] ) ;
106
114
}
107
115
FeatureValue :: Dep { dep_name } => {
108
- let dep_clause = compatible_dep_summaries_by_name_in_toml[ & dep_name]
109
- . iter ( )
110
- . map ( |dep| var_for_is_packages_used[ & dep. package_id ( ) ] . positive ( ) )
111
- . chain ( [ pkg_feature_var. negative ( ) ] )
112
- . collect :: < Vec < _ > > ( ) ;
116
+ // add a clause for each dependency with the provided name (normal/build/dev)
117
+ for compatible_dep_summaries in compatible_dep_summaries_map
118
+ . get ( & dep_name)
119
+ . into_iter ( )
120
+ . flat_map ( |map| map. values ( ) )
121
+ {
122
+ let dep_clause = compatible_dep_summaries
123
+ . iter ( )
124
+ . map ( |dep| var_for_is_packages_used[ & dep. package_id ( ) ] . positive ( ) )
125
+ . chain ( [ pkg_feature_var. negative ( ) ] )
126
+ . collect :: < Vec < _ > > ( ) ;
113
127
114
- solver. add_clause ( & dep_clause) ;
128
+ solver. add_clause ( & dep_clause) ;
129
+ }
115
130
}
116
131
FeatureValue :: DepFeature {
117
132
dep_name,
118
133
dep_feature : dep_feature_name,
119
134
weak,
120
135
} => {
121
- let mut dep_clause = Vec :: new ( ) ;
122
-
123
- for dep in & compatible_dep_summaries_by_name_in_toml[ & dep_name] {
124
- let dep_feature_var_map =
125
- & var_for_is_packages_features_used[ & dep. package_id ( ) ] ;
126
-
127
- let Some ( dep_feature_var) = dep_feature_var_map. get ( & dep_feature_name)
128
- else {
129
- continue ;
130
- } ;
131
-
132
- let dep_var = var_for_is_packages_used[ & dep. package_id ( ) ] ;
133
-
134
- solver. add_clause ( & [
135
- pkg_feature_var. negative ( ) ,
136
- dep_var. negative ( ) ,
137
- dep_feature_var. positive ( ) ,
138
- ] ) ;
136
+ // add clauses for each dependency with the provided name (normal/build/dev)
137
+ for compatible_dep_summaries in compatible_dep_summaries_map
138
+ . get ( & dep_name)
139
+ . into_iter ( )
140
+ . flat_map ( |map| map. values ( ) )
141
+ {
142
+ let mut dep_clause = Vec :: new ( ) ;
143
+
144
+ for dep in compatible_dep_summaries {
145
+ let dep_feature_var_map =
146
+ & var_for_is_packages_features_used[ & dep. package_id ( ) ] ;
147
+
148
+ let Some ( dep_feature_var) = dep_feature_var_map. get ( & dep_feature_name)
149
+ else {
150
+ continue ;
151
+ } ;
152
+
153
+ let dep_var = var_for_is_packages_used[ & dep. package_id ( ) ] ;
154
+
155
+ solver. add_clause ( & [
156
+ pkg_feature_var. negative ( ) ,
157
+ dep_var. negative ( ) ,
158
+ dep_feature_var. positive ( ) ,
159
+ ] ) ;
160
+
161
+ if !weak {
162
+ dep_clause. push ( dep_var. positive ( ) ) ;
163
+ }
164
+ }
139
165
140
166
if !weak {
141
- dep_clause. push ( dep_var. positive ( ) ) ;
167
+ dep_clause. push ( pkg_feature_var. negative ( ) ) ;
168
+ solver. add_clause ( & dep_clause) ;
142
169
}
143
170
}
144
-
145
- if !weak {
146
- dep_clause. push ( pkg_feature_var. negative ( ) ) ;
147
- solver. add_clause ( & dep_clause) ;
148
- }
149
171
}
150
172
}
151
173
}
@@ -158,11 +180,15 @@ fn process_pkg_dependencies(
158
180
var_for_is_packages_features_used : & HashMap < PackageId , HashMap < InternedString , varisat:: Var > > ,
159
181
pkg_var : varisat:: Var ,
160
182
pkg_dependencies : & [ Dependency ] ,
161
- compatible_dep_summaries_by_name_in_toml : & HashMap < InternedString , Vec < Summary > > ,
183
+ compatible_dep_summaries_map : & HashMap < InternedString , HashMap < DepKind , Vec < Summary > > > ,
162
184
) {
163
185
for dep in pkg_dependencies {
164
- let compatible_dep_summaries =
165
- & compatible_dep_summaries_by_name_in_toml[ & dep. name_in_toml ( ) ] ;
186
+ let Some ( compatible_dep_summaries) = compatible_dep_summaries_map
187
+ . get ( & dep. name_in_toml ( ) )
188
+ . and_then ( |map| map. get ( & dep. kind ( ) ) )
189
+ else {
190
+ continue ;
191
+ } ;
166
192
167
193
// add clauses for package dependency features
168
194
for dep_summary in compatible_dep_summaries {
@@ -272,16 +298,16 @@ impl SatResolver {
272
298
let pkg_dependencies = pkg. dependencies ( ) ;
273
299
let pkg_features = pkg. features ( ) ;
274
300
275
- let compatible_dep_summaries_by_name_in_toml =
276
- find_compatible_dep_summaries_by_name_in_toml ( pkg_dependencies, & by_name) ;
301
+ let compatible_dep_summaries_map =
302
+ find_all_compatible_dep_summaries ( pkg_dependencies, & by_name, false ) ;
277
303
278
304
process_pkg_features (
279
305
& mut solver,
280
306
& var_for_is_packages_used,
281
307
& var_for_is_packages_features_used,
282
308
& var_for_is_packages_features_used[ & pkg_id] ,
283
309
pkg_features,
284
- & compatible_dep_summaries_by_name_in_toml ,
310
+ & compatible_dep_summaries_map ,
285
311
) ;
286
312
287
313
process_pkg_dependencies (
@@ -290,7 +316,7 @@ impl SatResolver {
290
316
& var_for_is_packages_features_used,
291
317
var_for_is_packages_used[ & pkg_id] ,
292
318
pkg_dependencies,
293
- & compatible_dep_summaries_by_name_in_toml ,
319
+ & compatible_dep_summaries_map ,
294
320
) ;
295
321
}
296
322
@@ -330,16 +356,16 @@ impl SatResolver {
330
356
331
357
old_root_vars. push ( root_var) ;
332
358
333
- let compatible_dep_summaries_by_name_in_toml =
334
- find_compatible_dep_summaries_by_name_in_toml ( root_dependencies, & by_name) ;
359
+ let compatible_dep_summaries_map =
360
+ find_all_compatible_dep_summaries ( root_dependencies, & by_name, true ) ;
335
361
336
362
process_pkg_dependencies (
337
363
solver,
338
364
var_for_is_packages_used,
339
365
var_for_is_packages_features_used,
340
366
root_var,
341
367
root_dependencies,
342
- & compatible_dep_summaries_by_name_in_toml ,
368
+ & compatible_dep_summaries_map ,
343
369
) ;
344
370
345
371
solver. assume ( & assumption) ;
0 commit comments