@@ -15,10 +15,7 @@ use crate::{
15
15
internal:: {
16
16
arena:: ArenaId ,
17
17
id:: { ClauseId , SolvableId , SolvableOrRootId , StringId , VersionSetId } ,
18
- } ,
19
- runtime:: AsyncRuntime ,
20
- solver:: { clause:: Clause , variable_map:: VariableOrigin , Solver } ,
21
- DependencyProvider , Interner , Requirement ,
18
+ } , requirement:: Condition , runtime:: AsyncRuntime , solver:: { clause:: Clause , variable_map:: VariableOrigin , Solver } , DependencyProvider , Interner , Requirement
22
19
} ;
23
20
24
21
/// Represents the cause of the solver being unable to find a solution
@@ -159,10 +156,9 @@ impl Conflict {
159
156
ConflictEdge :: Conflict ( ConflictCause :: Constrains ( version_set_id) ) ,
160
157
) ;
161
158
}
162
- & Clause :: Conditional (
159
+ Clause :: Conditional (
163
160
package_id,
164
- condition_variable,
165
- condition_version_set_id,
161
+ condition_variables,
166
162
requirement,
167
163
) => {
168
164
let solvable = package_id
@@ -173,7 +169,7 @@ impl Conflict {
173
169
let requirement_candidates = solver
174
170
. async_runtime
175
171
. block_on ( solver. cache . get_or_cache_sorted_candidates (
176
- requirement,
172
+ * requirement,
177
173
) )
178
174
. unwrap_or_else ( |_| {
179
175
unreachable ! (
@@ -189,13 +185,13 @@ impl Conflict {
189
185
package_node,
190
186
unresolved_node,
191
187
ConflictEdge :: ConditionalRequires (
192
- condition_version_set_id ,
193
- requirement ,
188
+ * requirement ,
189
+ condition_variables . iter ( ) . map ( | ( _ , condition ) | * condition ) . collect ( ) ,
194
190
) ,
195
191
) ;
196
192
} else {
197
193
tracing:: trace!(
198
- "{package_id:?} conditionally requires {requirement:?} if {condition_variable :?}"
194
+ "{package_id:?} conditionally requires {requirement:?} if {condition_variables :?}"
199
195
) ;
200
196
201
197
for & candidate_id in requirement_candidates {
@@ -206,8 +202,8 @@ impl Conflict {
206
202
package_node,
207
203
candidate_node,
208
204
ConflictEdge :: ConditionalRequires (
209
- condition_version_set_id ,
210
- requirement ,
205
+ * requirement ,
206
+ condition_variables . iter ( ) . map ( | ( _ , condition ) | * condition ) . collect ( ) ,
211
207
) ,
212
208
) ;
213
209
}
@@ -292,33 +288,33 @@ impl ConflictNode {
292
288
}
293
289
294
290
/// An edge in the graph representation of a [`Conflict`]
295
- #[ derive( Clone , Copy , Hash , Eq , PartialEq , Ord , PartialOrd , Debug ) ]
291
+ #[ derive( Clone , Hash , Eq , PartialEq , Ord , PartialOrd , Debug ) ]
296
292
pub ( crate ) enum ConflictEdge {
297
293
/// The target node is a candidate for the dependency specified by the
298
294
/// [`Requirement`]
299
295
Requires ( Requirement ) ,
300
296
/// The target node is involved in a conflict, caused by `ConflictCause`
301
297
Conflict ( ConflictCause ) ,
302
298
/// The target node is a candidate for a conditional dependency
303
- ConditionalRequires ( VersionSetId , Requirement ) ,
299
+ ConditionalRequires ( Requirement , Vec < Condition > ) ,
304
300
}
305
301
306
302
impl ConflictEdge {
307
- fn try_requires_or_conditional ( self ) -> Option < ( Requirement , Option < VersionSetId > ) > {
303
+ fn try_requires_or_conditional ( self ) -> Option < ( Requirement , Vec < Condition > ) > {
308
304
match self {
309
- ConflictEdge :: Requires ( match_spec_id) => Some ( ( match_spec_id, None ) ) ,
310
- ConflictEdge :: ConditionalRequires ( version_set_id , match_spec_id ) => {
311
- Some ( ( match_spec_id, Some ( version_set_id ) ) )
305
+ ConflictEdge :: Requires ( match_spec_id) => Some ( ( match_spec_id, vec ! [ ] ) ) ,
306
+ ConflictEdge :: ConditionalRequires ( match_spec_id , conditions ) => {
307
+ Some ( ( match_spec_id, conditions ) )
312
308
}
313
309
ConflictEdge :: Conflict ( _) => None ,
314
310
}
315
311
}
316
312
317
- fn requires_or_conditional ( self ) -> ( Requirement , Option < VersionSetId > ) {
313
+ fn requires_or_conditional ( self ) -> ( Requirement , Vec < Condition > ) {
318
314
match self {
319
- ConflictEdge :: Requires ( match_spec_id) => ( match_spec_id, None ) ,
320
- ConflictEdge :: ConditionalRequires ( version_set_id , match_spec_id ) => {
321
- ( match_spec_id, Some ( version_set_id ) )
315
+ ConflictEdge :: Requires ( match_spec_id) => ( match_spec_id, vec ! [ ] ) ,
316
+ ConflictEdge :: ConditionalRequires ( match_spec_id , conditions ) => {
317
+ ( match_spec_id, conditions )
322
318
}
323
319
ConflictEdge :: Conflict ( _) => panic ! ( "expected requires edge, found conflict" ) ,
324
320
}
@@ -414,10 +410,13 @@ impl ConflictGraph {
414
410
ConflictEdge :: Requires ( requirement) => {
415
411
requirement. display ( interner) . to_string ( )
416
412
}
417
- ConflictEdge :: ConditionalRequires ( condition_version_set_id , requirement ) => {
413
+ ConflictEdge :: ConditionalRequires ( requirement , conditions ) => {
418
414
format ! (
419
415
"if {} then {}" ,
420
- Requirement :: from( * condition_version_set_id) . display( interner) ,
416
+ conditions. iter( )
417
+ . map( |c| interner. display_condition( * c) . to_string( ) )
418
+ . collect:: <Vec <_>>( )
419
+ . join( " and " ) ,
421
420
requirement. display( interner)
422
421
)
423
422
}
@@ -566,15 +565,15 @@ impl ConflictGraph {
566
565
. graph
567
566
. edges_directed ( nx, Direction :: Outgoing )
568
567
. map ( |e| match e. weight ( ) {
569
- ConflictEdge :: Requires ( req) => ( ( req, None ) , e. target ( ) ) ,
570
- ConflictEdge :: ConditionalRequires ( condition , req ) => {
571
- ( ( req, Some ( condition ) ) , e. target ( ) )
568
+ ConflictEdge :: Requires ( req) => ( ( req, vec ! [ ] ) , e. target ( ) ) ,
569
+ ConflictEdge :: ConditionalRequires ( req , conditions ) => {
570
+ ( ( req, conditions . clone ( ) ) , e. target ( ) )
572
571
}
573
572
ConflictEdge :: Conflict ( _) => unreachable ! ( ) ,
574
573
} )
575
574
. collect :: < Vec < _ > > ( )
576
575
. into_iter ( )
577
- . chunk_by ( |( ( & version_set_id, condition) , _) | ( version_set_id, * condition) ) ;
576
+ . chunk_by ( |( ( & version_set_id, condition) , _) | ( version_set_id, condition. clone ( ) ) ) ;
578
577
579
578
for ( _, mut deps) in & dependencies {
580
579
if deps. all ( |( _, target) | !installable. contains ( & target) ) {
@@ -617,15 +616,15 @@ impl ConflictGraph {
617
616
. graph
618
617
. edges_directed ( nx, Direction :: Outgoing )
619
618
. map ( |e| match e. weight ( ) {
620
- ConflictEdge :: Requires ( version_set_id) => ( ( version_set_id, None ) , e. target ( ) ) ,
621
- ConflictEdge :: ConditionalRequires ( condition , version_set_id ) => {
622
- ( ( version_set_id , Some ( condition ) ) , e. target ( ) )
619
+ ConflictEdge :: Requires ( version_set_id) => ( ( version_set_id, vec ! [ ] ) , e. target ( ) ) ,
620
+ ConflictEdge :: ConditionalRequires ( reqs , conditions ) => {
621
+ ( ( reqs , conditions . clone ( ) ) , e. target ( ) )
623
622
}
624
623
ConflictEdge :: Conflict ( _) => unreachable ! ( ) ,
625
624
} )
626
625
. collect :: < Vec < _ > > ( )
627
626
. into_iter ( )
628
- . chunk_by ( |( ( & version_set_id, condition) , _) | ( version_set_id, * condition) ) ;
627
+ . chunk_by ( |( ( & version_set_id, condition) , _) | ( version_set_id, condition. clone ( ) ) ) ;
629
628
630
629
// Missing if at least one dependency is missing
631
630
if dependencies
@@ -744,7 +743,7 @@ impl<'i, I: Interner> DisplayUnsat<'i, I> {
744
743
top_level_indent : bool ,
745
744
) -> fmt:: Result {
746
745
pub enum DisplayOp {
747
- ConditionalRequirement ( ( Requirement , VersionSetId ) , Vec < EdgeIndex > ) ,
746
+ ConditionalRequirement ( ( Requirement , Vec < Condition > ) , Vec < EdgeIndex > ) ,
748
747
Requirement ( Requirement , Vec < EdgeIndex > ) ,
749
748
Candidate ( NodeIndex ) ,
750
749
}
@@ -758,8 +757,8 @@ impl<'i, I: Interner> DisplayUnsat<'i, I> {
758
757
let indenter = Indenter :: new ( top_level_indent) ;
759
758
let mut stack = top_level_edges
760
759
. iter ( )
761
- . filter ( |e| e. weight ( ) . try_requires_or_conditional ( ) . is_some ( ) )
762
- . chunk_by ( |e| e. weight ( ) . requires_or_conditional ( ) )
760
+ . filter ( |e| e. weight ( ) . clone ( ) . try_requires_or_conditional ( ) . is_some ( ) )
761
+ . chunk_by ( |e| e. weight ( ) . clone ( ) . requires_or_conditional ( ) )
763
762
. into_iter ( )
764
763
. map ( |( version_set_id_with_condition, group) | {
765
764
let edges: Vec < _ > = group. map ( |e| e. id ( ) ) . collect ( ) ;
@@ -772,7 +771,7 @@ impl<'i, I: Interner> DisplayUnsat<'i, I> {
772
771
} )
773
772
. map ( |( ( version_set_id, condition) , edges) | {
774
773
(
775
- if let Some ( condition) = condition {
774
+ if ! condition. is_empty ( ) {
776
775
println ! ( "conditional requirement" ) ;
777
776
DisplayOp :: ConditionalRequirement ( ( version_set_id, condition) , edges)
778
777
} else {
@@ -1011,7 +1010,7 @@ impl<'i, I: Interner> DisplayUnsat<'i, I> {
1011
1010
writeln ! ( f, "{indent}{version} would require" , ) ?;
1012
1011
let mut requirements = graph
1013
1012
. edges ( candidate)
1014
- . chunk_by ( |e| e. weight ( ) . requires_or_conditional ( ) )
1013
+ . chunk_by ( |e| e. weight ( ) . clone ( ) . requires_or_conditional ( ) )
1015
1014
. into_iter ( )
1016
1015
. map ( |( version_set_id, group) | {
1017
1016
let edges: Vec < _ > = group. map ( |e| e. id ( ) ) . collect ( ) ;
@@ -1025,7 +1024,7 @@ impl<'i, I: Interner> DisplayUnsat<'i, I> {
1025
1024
} )
1026
1025
. map ( |( ( version_set_id, condition) , edges) | {
1027
1026
(
1028
- if let Some ( condition) = condition {
1027
+ if ! condition. is_empty ( ) {
1029
1028
DisplayOp :: ConditionalRequirement (
1030
1029
( version_set_id, condition) ,
1031
1030
edges,
@@ -1054,7 +1053,7 @@ impl<'i, I: Interner> DisplayUnsat<'i, I> {
1054
1053
} ) ;
1055
1054
1056
1055
let req = requirement. display ( self . interner ) . to_string ( ) ;
1057
- let condition = self . interner . display_version_set ( condition ) ;
1056
+ let condition = condition . iter ( ) . map ( |c| self . interner . display_condition ( * c ) . to_string ( ) ) . collect :: < Vec < _ > > ( ) . join ( " and " ) ;
1058
1057
1059
1058
let target_nx = graph. edge_endpoints ( edges[ 0 ] ) . unwrap ( ) . 1 ;
1060
1059
let missing =
0 commit comments