a-b-street/abstreet · error
Rotating against common infinite-looped
Error message
Rotating {:?} against common {:?} infinite-looped What it means
While merging, try_to_merge rotates `self`'s road-side list left so that the roads common with `other` sit at the end of the list. If after rotating a full list length the last road is still not common (or the first still is), the rotation can never succeed — the common roads aren't contiguous in the list — so it bails instead of looping forever.
Solutions
- Skip merging this block pair and retry merging later/with other pairs (find_blocks typically retries merges).
- Inspect the two perimeters' road sequences to understand why common roads are scattered; fix upstream block formation geometry.
- Reduce reliance on merge for these shapes: keep them as separate blocks instead of forcing a merge.
Defensive patterns
Strategy: fallback
Try / catch
match a.try_to_merge(map, b, &mut small_roads, debug_failures) {
Ok(_) => {},
Err(e) if e.to_string().contains("Rotating") => { /* defer pair to a later merge pass */ }
Err(e) => return Err(e),
} Prevention
- Run merging in multiple passes so deferred pairs can succeed after other merges.
- Avoid feeding exotic interleaved block shapes directly into merge.
When it happens
Trigger: try_to_merge called where `self.roads` contains common roads in a non-contiguous arrangement and self.roads.len() != common.len(), so the rotate_left loop runs self.roads.len() times without satisfying the ordering condition.
Common situations: Two blocks interleave along each other (share roads in several separated runs) due to unusual geometry like finger-shaped blocks or blocks sharing multiple disjoint stretches; map data with oddly shaped blocks from complex intersections.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- No common roads
- The common roads on the first aren't consecutive, near
- Started on a road we shouldn't trace
- Starting on inner piece of a loop road
- hit the map boundary at
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/6775801fdcef1a47.
Report an issue: GitHub.
Appendix: source
Thrown at blockfinding/src/lib.rs:223
if common.is_empty() {
if debug_failures {
warn!("No common roads");
}
bail!("No common roads");
}
// "Rotate" the order of roads, so that all of the overlapping roads are at the end of the
// list. If the entire perimeter is surrounded by the other, then no rotation needed.
if self.roads.len() != common.len() {
let mut i = 0;
while common.contains(&self.roads[0].road)
|| !common.contains(&self.roads.last().unwrap().road)
{
self.roads.rotate_left(1);
i += 1;
if i == self.roads.len() {
bail!(
"Rotating {:?} against common {:?} infinite-looped",
self.roads,
common
);
}
}
}
// Same thing with the other
if other.roads.len() != common.len() {
let mut i = 0;
while common.contains(&other.roads[0].road)
|| !common.contains(&other.roads.last().unwrap().road)
{
other.roads.rotate_left(1);
i += 1;
if i == other.roads.len() {
bail!(View on GitHub (pinned to 0964f29315)