diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d4233309627f5..b382ba7f22da7 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -512,7 +512,16 @@ fn separate_supertrait_bounds(mut g: clean::Generics) } pub fn record_extern_trait(cx: &DocContext, did: DefId) { - cx.external_traits.borrow_mut().entry(did).or_insert_with(|| { - build_external_trait(cx, did) - }); + if cx.external_traits.borrow().contains_key(&did) || + cx.active_extern_traits.borrow().contains(&did) + { + return; + } + + cx.active_extern_traits.borrow_mut().push(did); + + let trait_ = build_external_trait(cx, did); + + cx.external_traits.borrow_mut().insert(did, trait_); + cx.active_extern_traits.borrow_mut().remove_item(&did); } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index df7371cdf817b..9ee0937f425c9 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -61,6 +61,9 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { pub renderinfo: RefCell, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` pub external_traits: RefCell>, + /// Used while populating `external_traits` to ensure we don't process the same trait twice at + /// the same time. + pub active_extern_traits: RefCell>, // The current set of type and lifetime substitutions, // for expanding type aliases at the HIR level: @@ -253,6 +256,7 @@ pub fn run_core(search_paths: SearchPaths, populated_all_crate_impls: Cell::new(false), access_levels: RefCell::new(access_levels), external_traits: Default::default(), + active_extern_traits: Default::default(), renderinfo: Default::default(), ty_substs: Default::default(), lt_substs: Default::default(), diff --git a/src/test/rustdoc/auxiliary/issue-48414.rs b/src/test/rustdoc/auxiliary/issue-48414.rs new file mode 100644 index 0000000000000..7e0edf76f6ac9 --- /dev/null +++ b/src/test/rustdoc/auxiliary/issue-48414.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// Woah, this trait links to [OtherTrait](OtherTrait)! +pub trait SomeTrait {} + +/// Woah, this trait links to [SomeTrait](SomeTrait)! +pub trait OtherTrait {} diff --git a/src/test/rustdoc/issue-48414.rs b/src/test/rustdoc/issue-48414.rs new file mode 100644 index 0000000000000..0136f9c4759c7 --- /dev/null +++ b/src/test/rustdoc/issue-48414.rs @@ -0,0 +1,21 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:issue-48414.rs + +// ICE when resolving paths for a trait that linked to another trait, when both were in an external +// crate + +#![crate_name = "base"] + +extern crate issue_48414; + +#[doc(inline)] +pub use issue_48414::{SomeTrait, OtherTrait};