Bug
In compiler/rustc_const_eval/src/check_consts/resolver.rs:321-322, the JoinSemiLattice::join implementation for State uses short-circuit ||:
fn join(&mut self, other: &Self) -> bool {
self.qualif.join(&other.qualif) || self.borrow.join(&other.borrow)
}
When self.qualif.join() returns true (qualif state changed), the || operator short-circuits and self.borrow.join() is never called. This means borrow state from other is silently dropped at dataflow merge points.
The JoinSemiLattice::join contract says: "Computes the least upper bound of two elements, storing the result in self and returning true if self has changed." The borrow join has a side effect (mutating self.borrow) that must always execute.
Fix
Replace || with | (non-short-circuit or), or use separate let bindings:
let a = self.qualif.join(&other.qualif);
let b = self.borrow.join(&other.borrow);
a | b
Impact
Const fn with branching control flow may miss borrow constraints at merge points, potentially allowing const evaluation to proceed with incomplete borrow tracking.
Bug
In
compiler/rustc_const_eval/src/check_consts/resolver.rs:321-322, theJoinSemiLattice::joinimplementation forStateuses short-circuit||:When
self.qualif.join()returnstrue(qualif state changed), the||operator short-circuits andself.borrow.join()is never called. This means borrow state fromotheris silently dropped at dataflow merge points.The
JoinSemiLattice::joincontract says: "Computes the least upper bound of two elements, storing the result in self and returning true if self has changed." The borrow join has a side effect (mutatingself.borrow) that must always execute.Fix
Replace
||with|(non-short-circuit or), or use separate let bindings:Impact
Const fn with branching control flow may miss borrow constraints at merge points, potentially allowing const evaluation to proceed with incomplete borrow tracking.