@@ -7,11 +7,46 @@ use std::fmt::{self, Debug, Display};
77use std:: sync:: Arc ;
88
99use crate :: {
10- internal:: { Arena , Id , SmallMap } ,
10+ internal:: { Arena , DecisionLevel , Id , SmallMap } ,
1111 term, DefaultStringReportFormatter , DependencyProvider , DerivationTree , Derived , External , Map ,
1212 Package , PackageArena , ReportFormatter , Set , Term , Version , VersionSet ,
1313} ;
1414
15+ #[ derive( Debug , Clone ) ]
16+ struct ContradicationInfo {
17+ /// Store the decision level when the incompatibility was found to be contradicted.
18+ /// These will stay contradicted until we have backtracked beyond its associated decision level.
19+ decision_level : DecisionLevel ,
20+ /// Store the backtrack generation for the decision level.
21+ backtrack_generation : u32 ,
22+ }
23+
24+ impl ContradicationInfo {
25+ /// Construct a new value.
26+ fn new ( decision_level : DecisionLevel , backtrack_generation : u32 ) -> Self {
27+ Self {
28+ decision_level,
29+ backtrack_generation,
30+ }
31+ }
32+
33+ /// Construct a value interpreted as not contradicted.
34+ fn not_contradicted ( ) -> Self {
35+ Self {
36+ decision_level : DecisionLevel ( u32:: MAX ) ,
37+ backtrack_generation : 0 ,
38+ }
39+ }
40+
41+ /// Check for contradiction.
42+ fn is_contradicted ( & self , last_valid_decision_levels : & [ DecisionLevel ] ) -> bool {
43+ last_valid_decision_levels
44+ . get ( self . backtrack_generation as usize )
45+ . map ( |& l| self . decision_level <= l)
46+ . unwrap_or ( true )
47+ }
48+ }
49+
1550/// An incompatibility is a set of terms for different packages
1651/// that should never be satisfied all together.
1752/// An incompatibility usually originates from a package dependency.
@@ -31,6 +66,7 @@ use crate::{
3166pub ( crate ) struct Incompatibility < M : Eq + Clone + Debug + Display > {
3267 package_terms : SmallMap < Package , Term > ,
3368 kind : Kind < M > ,
69+ contradiction_info : ContradicationInfo ,
3470}
3571
3672/// Type alias of unique identifiers for incompatibilities.
@@ -96,6 +132,7 @@ impl<M: Eq + Clone + Debug + Display> Incompatibility<M> {
96132 Term :: negative ( VersionSet :: singleton ( version) ) ,
97133 ) ] ) ,
98134 kind : Kind :: NotRoot ( package, version) ,
135+ contradiction_info : ContradicationInfo :: not_contradicted ( ) ,
99136 }
100137 }
101138
@@ -109,6 +146,7 @@ impl<M: Eq + Clone + Debug + Display> Incompatibility<M> {
109146 Self {
110147 package_terms : SmallMap :: One ( [ ( package, term) ] ) ,
111148 kind : Kind :: NoVersions ( package, set) ,
149+ contradiction_info : ContradicationInfo :: not_contradicted ( ) ,
112150 }
113151 }
114152
@@ -123,6 +161,7 @@ impl<M: Eq + Clone + Debug + Display> Incompatibility<M> {
123161 Self {
124162 package_terms : SmallMap :: One ( [ ( package, term) ] ) ,
125163 kind : Kind :: Custom ( package, set, metadata) ,
164+ contradiction_info : ContradicationInfo :: not_contradicted ( ) ,
126165 }
127166 }
128167
@@ -133,6 +172,7 @@ impl<M: Eq + Clone + Debug + Display> Incompatibility<M> {
133172 Self {
134173 package_terms : SmallMap :: One ( [ ( package, term) ] ) ,
135174 kind : Kind :: Custom ( package, set, metadata) ,
175+ contradiction_info : ContradicationInfo :: not_contradicted ( ) ,
136176 }
137177 }
138178
@@ -153,6 +193,7 @@ impl<M: Eq + Clone + Debug + Display> Incompatibility<M> {
153193 ] )
154194 } ,
155195 kind : Kind :: FromDependencyOf ( package, versions, p2, set2) ,
196+ contradiction_info : ContradicationInfo :: not_contradicted ( ) ,
156197 }
157198 }
158199
@@ -226,6 +267,7 @@ impl<M: Eq + Clone + Debug + Display> Incompatibility<M> {
226267 Self {
227268 package_terms,
228269 kind,
270+ contradiction_info : ContradicationInfo :: not_contradicted ( ) ,
229271 }
230272 }
231273
@@ -242,6 +284,21 @@ impl<M: Eq + Clone + Debug + Display> Incompatibility<M> {
242284 }
243285 }
244286
287+ /// Check if an incompatibility is contradicted.
288+ pub ( crate ) fn is_contradicted ( & self , last_valid_decision_levels : & [ DecisionLevel ] ) -> bool {
289+ self . contradiction_info
290+ . is_contradicted ( last_valid_decision_levels)
291+ }
292+
293+ /// Set incompatibility contradication info.
294+ pub ( crate ) fn set_contradication_info (
295+ & mut self ,
296+ decision_level : DecisionLevel ,
297+ backtrack_generation : u32 ,
298+ ) {
299+ self . contradiction_info = ContradicationInfo :: new ( decision_level, backtrack_generation) ;
300+ }
301+
245302 /// Get the term related to a given package (if it exists).
246303 pub ( crate ) fn get ( & self , package : Package ) -> Option < Term > {
247304 self . package_terms . get ( & package) . copied ( )
@@ -386,12 +443,14 @@ pub(crate) mod tests {
386443 let mut store = Arena :: new( ) ;
387444 let i1 = store. alloc( Incompatibility {
388445 package_terms: SmallMap :: Two ( [ ( Package ( 1 ) , t1) , ( Package ( 2 ) , t2. negate( ) ) ] ) ,
389- kind: Kind :: <String >:: FromDependencyOf ( Package ( 1 ) , VersionSet :: full( ) , Package ( 2 ) , VersionSet :: full( ) )
446+ kind: Kind :: <String >:: FromDependencyOf ( Package ( 1 ) , VersionSet :: full( ) , Package ( 2 ) , VersionSet :: full( ) ) ,
447+ contradiction_info: ContradicationInfo :: not_contradicted( ) ,
390448 } ) ;
391449
392450 let i2 = store. alloc( Incompatibility {
393451 package_terms: SmallMap :: Two ( [ ( Package ( 2 ) , t2) , ( Package ( 3 ) , t3) ] ) ,
394- kind: Kind :: <String >:: FromDependencyOf ( Package ( 2 ) , VersionSet :: full( ) , Package ( 3 ) , VersionSet :: full( ) )
452+ kind: Kind :: <String >:: FromDependencyOf ( Package ( 2 ) , VersionSet :: full( ) , Package ( 3 ) , VersionSet :: full( ) ) ,
453+ contradiction_info: ContradicationInfo :: not_contradicted( ) ,
395454 } ) ;
396455
397456 let mut i3 = Map :: default ( ) ;
0 commit comments