{"record":{"id":"da31c10c24c6f312","repo":"a-b-street/abstreet","slug":"pathconstraints-from-lt-doesn-t-make-sense","errorCode":null,"errorMessage":"PathConstraints::from_lt({:?}) doesn't make sense","messagePattern":"PathConstraints::from_lt\\((.+?)\\) doesn't make sense","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"map_model/src/pathfind/mod.rs","lineNumber":58,"sourceCode":"    pub fn all() -> Vec<PathConstraints> {\n        vec![\n            PathConstraints::Pedestrian,\n            PathConstraints::Car,\n            PathConstraints::Bike,\n            PathConstraints::Bus,\n            PathConstraints::Train,\n        ]\n    }\n\n    /// Not bijective, but this is the best guess of user intent\n    pub fn from_lt(lt: LaneType) -> PathConstraints {\n        match lt {\n            LaneType::Sidewalk | LaneType::Shoulder => PathConstraints::Pedestrian,\n            LaneType::Driving => PathConstraints::Car,\n            LaneType::Biking => PathConstraints::Bike,\n            LaneType::Bus => PathConstraints::Bus,\n            LaneType::LightRail => PathConstraints::Train,\n            _ => panic!(\"PathConstraints::from_lt({:?}) doesn't make sense\", lt),\n        }\n    }\n\n    /// Can an agent use a lane? There are some subtle exceptions with using bus-only lanes for\n    /// turns.\n    pub fn can_use(self, lane: &Lane, map: &Map) -> bool {\n        let result = match self {\n            PathConstraints::Pedestrian => {\n                return lane.is_walkable();\n            }\n            PathConstraints::Car => lane.is_driving(),\n            PathConstraints::Bike => {\n                if lane.is_biking() {\n                    true\n                } else if lane.is_driving() || (lane.is_bus() && map.config.bikes_can_use_bus_lanes)\n                {\n                    let road = map.get_r(lane.id.road);\n                    !road.osm_tags.is(\"bicycle\", \"no\")","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/map_model/src/pathfind/mod.rs#L40-L76","documentation":"PathConstraints::from_lt converts a LaneType into the PathConstraints an agent needs to traverse it. The panic fires for LaneType variants that have no meaningful agent constraint mapping (e.g. construction or footway-only variants not listed in the match). It is an internal exhaustiveness guard: the library assumes every LaneType passed here is one of the six mappable variants.","triggerScenarios":"Calling from_lt (directly or via pathfinding setup that classifies lanes) with a LaneType value outside {Sidewalk, Shoulder, Driving, Biking, Bus, LightRail}, such as LaneType::Construction or other map data lane types.","commonSituations":"Loading map data with unusual OSM lane types and then building pathfinding routes for them; a new LaneType variant added upstream without updating this match; calling from_lt in custom tooling over all lanes in a map.","solutions":["Match only LaneTypes that map to a PathConstraints; filter or skip unmappable lanes before calling from_lt","Check LaneType for the problematic lane in your map data and fix the input data or its tags","Update the match arm in PathConstraints::from_lt to map the new LaneType to a sensible constraint","Use PathConstraints::from_lt only on lane types you have validated, handling the catch-all case yourself"],"exampleFix":"// before\nlet constraints = PathConstraints::from_lt(lane.lt);\n// after\nlet constraints = match lane.lt {\n    LaneType::Sidewalk | LaneType::Shoulder | LaneType::Footway => PathConstraints::Pedestrian,\n    LaneType::Driving => PathConstraints::Car,\n    LaneType::Biking => PathConstraints::Bike,\n    LaneType::Bus => PathConstraints::Bus,\n    LaneType::LightRail => PathConstraints::Train,\n    other => { eprintln!(\"skipping unmappable lane type {:?}\", other); continue; }\n};","handlingStrategy":"validation","validationCode":"fn is_mappable(lt: LaneType) -> bool {\n    matches!(lt, LaneType::Sidewalk | LaneType::Shoulder | LaneType::Driving | LaneType::Biking | LaneType::Bus | LaneType::LightRail)\n}","typeGuard":"fn to_constraints(lt: LaneType) -> Option<PathConstraints> {\n    match lt {\n        LaneType::Sidewalk | LaneType::Shoulder => Some(PathConstraints::Pedestrian),\n        LaneType::Driving => Some(PathConstraints::Car),\n        LaneType::Biking => Some(PathConstraints::Bike),\n        LaneType::Bus => Some(PathConstraints::Bus),\n        LaneType::LightRail => Some(PathConstraints::Train),\n        _ => None,\n    }\n}","tryCatchPattern":null,"preventionTips":["Use an Option-returning wrapper instead of the panicking from_lt for untrusted lane types","Keep the LaneType match in sync whenever new LaneType variants are introduced","Validate map input data lane types before pathfinding","Add a test iterating all LaneType variants against from_lt"],"tags":["rust","panic","enum-mapping","pathfinding"],"backgroundTag":"invalid-enum-value","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"}