java-topology/defects/rustc/patch/rustc-diamond-recursion-CLEAN.md

2.3 KiB

rustc diamond-recursion scan — CLEAN

Scan date: 2026-03-29 Pattern: Recursive DAG traversal without visited set (CWE-407 diamond recursion, O(2^D)) Files scanned:

  • compiler/rustc_type_ir/src/elaborate.rsElaborator, supertrait_def_ids
  • compiler/rustc_type_ir/src/walk.rsTypeWalker
  • compiler/rustc_trait_selection/src/traits/util.rsexpand_trait_aliases
  • compiler/rustc_trait_selection/src/traits/select/mod.rsevaluate_predicate_recursively
  • compiler/rustc_hir_analysis/src/collect/predicates_of.rsimplied_predicates_with_filter
  • compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rscollect_bounds

Findings

elaborate.rs — CLEAN

Elaborator uses visited: HashSet<ty::Binder<I, ty::PredicateKind<I>>> (line 25). supertrait_def_ids uses set: HashSet with set.insert(data.def_id()) guard (line 328). Both correctly prevent diamond re-traversal.

walk.rs — CLEAN

TypeWalker uses visited: SsoHashSet<I::GenericArg> with self.visited.insert(next) guard (line 59). Explicitly documented: "walker only visits each type once."

expand_trait_aliases — CLEAN

Uses BFS VecDeque without a visited set on trait aliases, but the re-queuing is gated by tcx.is_trait_alias() only. Normal (non-alias) traits are pushed directly to trait_preds output without re-queuing. Diamond blowup not possible because tcx.explicit_super_predicates_of is a memoized query.

select/mod.rs — CLEAN

evaluate_predicate_recursively calls check_candidate_cache / insert_candidate_cache — a proper memoization cache keyed on trait predicates. No diamond re-traversal.

predicates_of.rs — CLEAN

All supertrait queries go through tcx.at(span).explicit_super_predicates_of(bound.def_id()) which is a memoized TyCtxt query. Results are cached per DefId. No diamond blowup.

hir_ty_lowering/bounds.rs — CLEAN

collect_bounds iterates directly over HIR bounds, no recursion into supertraits.

Conclusion

No diamond recursion CWE-407 defects in rustc. All supertrait and type traversal uses either a proper HashSet/SsoHashSet visited set, or memoized TyCtxt query results that cache per DefId. The O(2^D) diamond blowup pattern is not present in the scanned rustc crates.