{"record":{"id":"6775801fdcef1a47","repo":"a-b-street/abstreet","slug":"rotating-against-common-infinite-looped","errorCode":null,"errorMessage":"Rotating {:?} against common {:?} infinite-looped","messagePattern":"Rotating (.+?) against common (.+?) infinite-looped","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"blockfinding/src/lib.rs","lineNumber":223,"sourceCode":"            if common.is_empty() {\n                if debug_failures {\n                    warn!(\"No common roads\");\n                }\n                bail!(\"No common roads\");\n            }\n\n            // \"Rotate\" the order of roads, so that all of the overlapping roads are at the end of the\n            // list. If the entire perimeter is surrounded by the other, then no rotation needed.\n            if self.roads.len() != common.len() {\n                let mut i = 0;\n                while common.contains(&self.roads[0].road)\n                    || !common.contains(&self.roads.last().unwrap().road)\n                {\n                    self.roads.rotate_left(1);\n\n                    i += 1;\n                    if i == self.roads.len() {\n                        bail!(\n                            \"Rotating {:?} against common {:?} infinite-looped\",\n                            self.roads,\n                            common\n                        );\n                    }\n                }\n            }\n            // Same thing with the other\n            if other.roads.len() != common.len() {\n                let mut i = 0;\n                while common.contains(&other.roads[0].road)\n                    || !common.contains(&other.roads.last().unwrap().road)\n                {\n                    other.roads.rotate_left(1);\n\n                    i += 1;\n                    if i == other.roads.len() {\n                        bail!(","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/blockfinding/src/lib.rs#L205-L241","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match a.try_to_merge(map, b, &mut small_roads, debug_failures) {\n    Ok(_) => {},\n    Err(e) if e.to_string().contains(\"Rotating\") => { /* defer pair to a later merge pass */ }\n    Err(e) => return Err(e),\n}","preventionTips":["Run merging in multiple passes so deferred pairs can succeed after other merges.","Avoid feeding exotic interleaved block shapes directly into merge."],"tags":["merge","rotation","perimeter-tracing"],"backgroundTag":"internal-invariant-violation","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}