The dependencies of an inference node are currently stored in a 'HashSet' that doesn't preserve insertion order (see 'Infer.InferenceGraph.Node' or 'DeferredAttr.DeferredAttrContext.StuckNode'). In addition to that, 'hashCode()' is inherited from 'Object' giving no guarantee of consistency between two compilations of the same code sample (it might depend on the memory location).
Tarjan's algorithm iterates on these dependencies to compute the acyclic graph determining the solving order which is then non-deterministic (see 'GraphUtils.Tarjan.findSCC()' and 'Infer.LeafSolver.pickNode()').
Picking a node to be solved from a stuck expression also iterates on those dependencies leading to a non-deterministic solving order too (see 'Infer.BestLeafSolver.pickNode()').
While the current implementation seems to be stable enough, this non-deterministic behavior is dangerous and might be the cause of irreproducible errors.
There are two solutions for that:
* overriding 'hashCode()' with a stable value like a sequential identifier
* using a 'LinkedHashSet' instead of a 'HashSet' to preserve insertion order while accessing elements in constant time
Tarjan's algorithm iterates on these dependencies to compute the acyclic graph determining the solving order which is then non-deterministic (see 'GraphUtils.Tarjan.findSCC()' and 'Infer.LeafSolver.pickNode()').
Picking a node to be solved from a stuck expression also iterates on those dependencies leading to a non-deterministic solving order too (see 'Infer.BestLeafSolver.pickNode()').
While the current implementation seems to be stable enough, this non-deterministic behavior is dangerous and might be the cause of irreproducible errors.
There are two solutions for that:
* overriding 'hashCode()' with a stable value like a sequential identifier
* using a 'LinkedHashSet' instead of a 'HashSet' to preserve insertion order while accessing elements in constant time
- relates to
-
JDK-8178150 Regression in logic for handling inference stuck constraints
-
- Closed
-
- links to