At commit dffc676, iced-rs/iced spans 3,904 functions with 59 rated critical — and the heaviest structural debt is concentrated in two files: winit/src/lib.rs and widget/src/text_input.rs. The top-ranked hotspot, run_instance in winit/src/lib.rs, sits in the “debt” quadrant: it hasn’t been the subject of recent churn, but with a cyclomatic complexity of 79 and fan-out of 57, it carries enormous blast radius the moment it is next touched. All five top hotspots share this debt profile — structurally complex code that is overdue for refactoring before active development resumes.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
run_instance | winit/src/lib.rs | 18.6 | 79 | 7 | 57 |
update | widget/src/text_input.rs | 18.3 | 128 | 6 | 45 |
run | test/src/lib.rs | 17.4 | 18 | 3 | 18 |
run_action | winit/src/lib.rs | 15.6 | 166 | 4 | 53 |
update | widget/src/mouse_area.rs | 14.2 | 40 | 3 | 6 |
Hotspot Analysis
run_instance — winit/src/lib.rs
Based on its name and location in the winit integration layer, run_instance likely manages the lifecycle of a single application window instance — handling the main event loop, windowing system callbacks, and state transitions via winit. A cyclomatic complexity of 79 means 79 independent execution paths, a nesting depth of 7 signals deeply nested control flow that is difficult to reason about in isolation, and a fan-out of 57 means it directly invokes 57 other functions — a god-function with wide coupling. Flagged as “debt” quadrant, this function is not actively churning right now, but its structural weight means any future change carries extreme blast radius across the winit integration.
Recommendation: Before the next feature push into winit/src/lib.rs, add characterization tests that pin the current behavior of run_instance across its major execution paths, then extract coherent sub-responsibilities — event dispatch, state management, error handling — into dedicated functions to bring the CC below 20 and reduce fan-out to a manageable level.
update — widget/src/text_input.rs
As the core event-handling function for the text input widget, update almost certainly processes keyboard input, cursor movement, selection, clipboard operations, and focus changes — every discrete input action branching the logic further. A cyclomatic complexity of 128 is extreme by any measure, representing 128 independent paths and an equivalent number of required test cases for full coverage; the exit-heavy pattern confirms that many of these paths terminate early through multiple return points, compounding the test-coverage burden. With a fan-out of 45 and classified as structural debt, this function has not seen recent commit churn, but it is a high-blast-radius target that warrants refactoring before any new input feature is layered on top.
Recommendation: Decompose update in widget/src/text_input.rs by input category — separate handlers for cursor/selection logic, clipboard operations, and character insertion — each testable in isolation; this alone should reduce the effective CC dramatically and make the exit-heavy paths traceable to their specific input contracts.
run — test/src/lib.rs
Despite a relatively modest cyclomatic complexity of 18, run in iced’s test harness ranks third due to higher recent commit activity — this function is touched regularly as the test infrastructure evolves alongside the framework. A fan-out of 18 means it dispatches broadly across test helpers, and as the top-level executor for iced’s test layer it is a likely breakage point whenever core event-dispatch or state APIs change. The combination of moderate complexity and active churn makes it a higher immediate priority than it would appear from structural metrics alone.
Recommendation: Keep run’s responsibilities narrow by extracting the three main concerns — harness setup, event dispatch, and result collection — into focused helpers; this caps future fan-out growth and makes regressions easier to isolate when the test API changes.
run_action — winit/src/lib.rs
Sitting alongside run_instance in the winit integration layer, run_action likely dispatches the full set of runtime actions — window commands, clipboard requests, drag-and-drop, and platform-specific operations — across the application. With a cyclomatic complexity of 166, the highest in the entire top-5 list, it represents an extraordinary number of branching paths; despite a relatively contained nesting depth of 4, the complex-branching pattern and god-function classification confirm it is doing far more than a single well-scoped function should. Its activity-weighted risk score of 15.6 places it in the debt quadrant — it has not been actively touched recently, but its CC of 166 and fan-out of 53 mean a single modification here can ripple across more than half a hundred call sites.
Recommendation: Map run_action’s 53 outbound calls by action category (rendering, windowing, I/O, etc.) and extract each category into a dedicated dispatcher function; this reduces the single-function CC and makes each action group independently testable and reviewable.
update — widget/src/mouse_area.rs
The mouse area widget’s update handles the full range of pointer events — enter, leave, press, release, move — each as a separate branch. A cyclomatic complexity of 40 is high for a widget event handler, indicating many distinct interaction paths are packed into one function rather than delegated to helpers. Fan-out of 6 is contained, but the complex-branching pattern means the logic is dense with conditionals. With a risk score of 14.2 this function sits in the debt quadrant — not actively churning right now, but the high branch count makes it fragile ground for future pointer-event additions.
Recommendation: Extract named handlers for each pointer event category (on_press, on_release, on_enter, on_exit) into separate focused methods; each becomes independently testable and the aggregate CC of update drops to a manageable level.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
long_function | 6 |
god_function | 5 |
complex_branching | 3 |
exit_heavy | 3 |
deeply_nested | 2 |
hub_function | 2 |
These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
Key Takeaways
run_actioninwinit/src/lib.rshas a cyclomatic complexity of 166 — the highest in the codebase’s top hotspots — meaning any modification requires navigating 166 potential execution paths; extract action-category dispatchers before adding new platform actions.- The
updatefunction inwidget/src/text_input.rs(CC 128, fan-out 45) is the single highest-complexity widget function; decomposing it by input responsibility is the most impactful refactoring available in the widget layer. - All five critical hotspots are in the ‘debt’ quadrant — none are actively churning right now — making this an ideal window to invest in characterization tests and extract-method refactoring before the next development cycle raises regression risk.
Reproduce This Analysis
git clone https://github.com/iced-rs/iced
cd iced
git checkout dffc6765238090db89e33b4b84400a12e7dacfa2
hotspots analyze . --mode snapshot --explain-patterns --force
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →