65 lines
2.7 KiB
Diff
65 lines
2.7 KiB
Diff
# UNDF: UNDF-2026-000000267
|
|
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
|
|
index c935869..9218cd1 100644
|
|
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
|
|
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
|
|
@@ -1,9 +1,34 @@
|
|
+use rustc_data_structures::fx::FxHashSet;
|
|
use rustc_macros::HashStable;
|
|
use smallvec::SmallVec;
|
|
use tracing::instrument;
|
|
|
|
use crate::ty::{self, DefId, OpaqueTypeKey, Ty, TyCtxt, TypingEnv};
|
|
|
|
+/// Stack for cycle detection in `apply_inner`.
|
|
+/// Wraps SmallVec (for push/pop LIFO order) with FxHashSet (for O(1) contains).
|
|
+/// CWE-407 fix: SmallVec::contains is O(n); FxHashSet::contains is O(1).
|
|
+#[derive(Default)]
|
|
+struct EvalStack<'tcx> {
|
|
+ vec: SmallVec<[Ty<'tcx>; 1]>,
|
|
+ set: FxHashSet<Ty<'tcx>>,
|
|
+}
|
|
+
|
|
+impl<'tcx> EvalStack<'tcx> {
|
|
+ fn contains(&self, t: &Ty<'tcx>) -> bool {
|
|
+ self.set.contains(t)
|
|
+ }
|
|
+ fn push(&mut self, t: Ty<'tcx>) {
|
|
+ self.vec.push(t);
|
|
+ self.set.insert(t);
|
|
+ }
|
|
+ fn pop(&mut self) {
|
|
+ if let Some(t) = self.vec.pop() {
|
|
+ self.set.remove(&t);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
/// Represents whether some type is inhabited in a given context.
|
|
/// Examples of uninhabited types are `!`, `enum Void {}`, or a struct
|
|
/// containing either of those types.
|
|
@@ -82,7 +107,7 @@ fn apply_inner<E: std::fmt::Debug>(
|
|
self,
|
|
tcx: TyCtxt<'tcx>,
|
|
typing_env: TypingEnv<'tcx>,
|
|
- eval_stack: &mut SmallVec<[Ty<'tcx>; 1]>, // for cycle detection
|
|
+ eval_stack: &mut EvalStack<'tcx>, // for cycle detection; Set-backed for O(1) contains
|
|
in_module: &impl Fn(DefId) -> Result<bool, E>,
|
|
reveal_opaque: &impl Fn(OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>>,
|
|
) -> Result<bool, E> {
|
|
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
|
|
index 8462471..713fec3 100644
|
|
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
|
|
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
|
|
@@ -66,8 +66,10 @@ fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
|
|
vec = &mut self.blanket_impls;
|
|
}
|
|
|
|
+ // CWE-407 partial fix: swap_remove is O(1) vs remove's O(n) shift.
|
|
+ // position() scan is still O(n); full O(1) requires Children to use IndexSet<DefId>.
|
|
let index = vec.iter().position(|d| *d == impl_def_id).unwrap();
|
|
- vec.remove(index);
|
|
+ vec.swap_remove(index);
|
|
}
|
|
|
|
/// Attempt to insert an impl into this set of children, while comparing for
|