diff options
| author | J. Ryan Stinnett <jryans@gmail.com> | 2021-01-28 22:03:20 +0000 |
|---|---|---|
| committer | J. Ryan Stinnett <jryans@gmail.com> | 2021-01-30 14:23:50 +0000 |
| commit | 7e3217845dc5dea331b26efb2bf51b60afae2082 (patch) | |
| tree | c40c88774ac954d5b09f55aee3b820c53d45c3e5 /src | |
| parent | 7ce1b3b24491cbe10669cbe2b5733c2fe7cfe5b7 (diff) | |
| download | rust-7e3217845dc5dea331b26efb2bf51b60afae2082.tar.gz rust-7e3217845dc5dea331b26efb2bf51b60afae2082.zip | |
Balance sidebar `Deref` cycle check with main content
The `Deref` cycle checks added as part of #80653 were "unbalanced" in the sense that the main content code path checks for cycles _before_ descending, while the sidebar checks _after_. Checking _before_ is correct, so this changes the sidebar path to match the main content path.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 18 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/deref-generic.rs | 15 |
2 files changed, 26 insertions, 7 deletions
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index daaa2c719b0..6909ab870db 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -3510,6 +3510,7 @@ fn render_assoc_items( "deref-methods-{:#}", type_.print(cx.cache()) ))); + debug!("Adding {} to deref id map", type_.print(cx.cache())); cx.deref_id_map .borrow_mut() .insert(type_.def_id_full(cx.cache()).unwrap(), id.clone()); @@ -3626,6 +3627,7 @@ fn render_deref_methods( _ => None, }) .expect("Expected associated type binding"); + debug!("Render deref methods for {:#?}, target {:#?}", impl_.inner_impl().for_, target); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; if let Some(did) = target.def_id_full(cx.cache()) { @@ -4416,6 +4418,15 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V }) { debug!("found target, real_target: {:?} {:?}", target, real_target); + if let Some(did) = target.def_id_full(cx.cache()) { + if let Some(type_did) = impl_.inner_impl().for_.def_id_full(cx.cache()) { + // `impl Deref<Target = S> for S` + if did == type_did { + // Avoid infinite cycles + return; + } + } + } let deref_mut = v .iter() .filter(|i| i.inner_impl().trait_.is_some()) @@ -4464,13 +4475,6 @@ fn sidebar_deref_methods(cx: &Context<'_>, out: &mut Buffer, impl_: &Impl, v: &V .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id_full(cx.cache()) == c.deref_trait_did) { - if let Some(type_did) = impl_.inner_impl().for_.def_id_full(cx.cache()) { - // `impl Deref<Target = S> for S` - if target_did == type_did { - // Avoid infinite cycles - return; - } - } sidebar_deref_methods(cx, out, target_deref_impl, target_impls); } } diff --git a/src/test/rustdoc-ui/deref-generic.rs b/src/test/rustdoc-ui/deref-generic.rs new file mode 100644 index 00000000000..bc64beb1b93 --- /dev/null +++ b/src/test/rustdoc-ui/deref-generic.rs @@ -0,0 +1,15 @@ +// check-pass +// #81395: Fix ICE when recursing into Deref target only differing in type args + +pub struct Generic<T>(T); + +impl<'a> std::ops::Deref for Generic<&'a mut ()> { + type Target = Generic<&'a ()>; + fn deref(&self) -> &Self::Target { + unimplemented!() + } +} + +impl<'a> Generic<&'a ()> { + pub fn some_method(&self) {} +} |
