diff options
| author | Michael Howell <michael@notriddle.com> | 2022-04-29 08:49:14 -0700 |
|---|---|---|
| committer | Michael Howell <michael@notriddle.com> | 2022-04-29 09:06:50 -0700 |
| commit | 8743ce85231d1b889323286aa3c88e0cfbc1a76b (patch) | |
| tree | 9f97bc830d176c3c27006073ac6485021ed3ca8e | |
| parent | 346065f621c861179a4f51d701c9c7c7a907346b (diff) | |
| download | rust-8743ce85231d1b889323286aa3c88e0cfbc1a76b.tar.gz rust-8743ce85231d1b889323286aa3c88e0cfbc1a76b.zip | |
rustdoc: prevent B -> C -> B -> C loops from stack overflowing
| -rw-r--r-- | src/librustdoc/passes/collect_trait_impls.rs | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 7b6b1ba0d96..9644e3d15fd 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -100,6 +100,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate cx: &DocContext<'_>, map: &FxHashMap<DefId, &Type>, cleaner: &mut BadImplStripper<'_>, + targets: &mut FxHashSet<DefId>, type_did: DefId, ) { if let Some(target) = map.get(&type_did) { @@ -108,12 +109,12 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate cleaner.prims.insert(target_prim); } else if let Some(target_did) = target.def_id(&cx.cache) { // `impl Deref<Target = S> for S` - if target_did == type_did { + if !targets.insert(target_did) { // Avoid infinite cycles return; } cleaner.items.insert(target_did.into()); - add_deref_target(cx, map, cleaner, target_did); + add_deref_target(cx, map, cleaner, targets, target_did); } } } @@ -143,7 +144,15 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate // `Deref` target type and the impl for type positions, this map of types is keyed by // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. if cleaner.keep_impl_with_def_id(for_did.into()) { - add_deref_target(cx, &type_did_to_deref_target, &mut cleaner, for_did); + let mut targets = FxHashSet::default(); + targets.insert(for_did); + add_deref_target( + cx, + &type_did_to_deref_target, + &mut cleaner, + &mut targets, + for_did, + ); } } } |
