diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 83be1a16eb2..1196f944faa 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -99,53 +99,6 @@ fn get_impls(&mut self, id: DefId) -> Vec { }) .unwrap_or_default() } - - fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> { - debug!("Adding foreign trait items"); - Rc::clone(&self.cache) - .traits - .iter() - .filter_map(|(&id, trait_item)| { - // only need to synthesize items for external traits - if !id.is_local() { - for item in &trait_item.items { - trace!("Adding subitem to {id:?}: {:?}", item.item_id); - self.item(item.clone()).unwrap(); - } - let item_id = from_item_id(id.into(), self.tcx); - Some(( - item_id.clone(), - types::Item { - id: item_id, - crate_id: id.krate.as_u32(), - name: self - .cache - .paths - .get(&id) - .unwrap_or_else(|| { - self.cache - .external_paths - .get(&id) - .expect("Trait should either be in local or external paths") - }) - .0 - .last() - .map(|s| s.to_string()), - visibility: types::Visibility::Public, - inner: types::ItemEnum::Trait(trait_item.clone().into_tcx(self.tcx)), - span: None, - docs: Default::default(), - links: Default::default(), - attrs: Default::default(), - deprecation: Default::default(), - }, - )) - } else { - None - } - }) - .collect() - } } impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { @@ -276,11 +229,7 @@ fn after_krate(&mut self) -> Result<(), Error> { let e = ExternalCrate { crate_num: LOCAL_CRATE }; - // FIXME(adotinthevoid): Remove this, as it's not consistent with not - // inlining foreign items. - let foreign_trait_items = self.get_trait_items(); - let mut index = (*self.index).clone().into_inner(); - index.extend(foreign_trait_items); + let index = (*self.index).clone().into_inner(); debug!("Constructing Output"); // This needs to be the default HashMap for compatibility with the public interface for diff --git a/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs new file mode 100644 index 00000000000..bfe85f59e81 --- /dev/null +++ b/src/test/rustdoc-json/intra-doc-links/auxiliary/enum_variant_in_trait_method.rs @@ -0,0 +1,8 @@ +pub trait Trait { + /// [`Enum::Variant`] + fn method() {} +} + +pub enum Enum { + Variant, +} diff --git a/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs new file mode 100644 index 00000000000..e2968231338 --- /dev/null +++ b/src/test/rustdoc-json/intra-doc-links/foreign_variant.rs @@ -0,0 +1,13 @@ +// Regression test for +// aux-build: enum_variant_in_trait_method.rs + +extern crate enum_variant_in_trait_method; + +pub struct Local; + +/// local impl +impl enum_variant_in_trait_method::Trait for Local {} + +// @!has "$.index[*][?(@.name == 'Trait')]" +// @!has "$.index[*][?(@.name == 'method')]" +// @count "$.index[*][?(@.docs == 'local impl')].inner.items[*]" 0 diff --git a/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs new file mode 100644 index 00000000000..1e87966b28a --- /dev/null +++ b/src/test/rustdoc-json/reexport/auxiliary/trait_with_docs.rs @@ -0,0 +1,2 @@ +/// The Docs +pub trait HasDocs {} diff --git a/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs new file mode 100644 index 00000000000..25a7c08d689 --- /dev/null +++ b/src/test/rustdoc-json/reexport/synthesize_trait_with_docs.rs @@ -0,0 +1,10 @@ +// Regression test for +// aux-build: trait_with_docs.rs + +extern crate trait_with_docs; + +pub struct Local; + +impl trait_with_docs::HasDocs for Local {} + +// @!has "$.index[*][?(@.name == 'HasDocs')]" diff --git a/src/test/rustdoc-json/traits/uses_extern_trait.rs b/src/test/rustdoc-json/traits/uses_extern_trait.rs index a4add43c6a1..55a51f739ab 100644 --- a/src/test/rustdoc-json/traits/uses_extern_trait.rs +++ b/src/test/rustdoc-json/traits/uses_extern_trait.rs @@ -1,12 +1,5 @@ #![no_std] pub fn drop_default(_x: T) {} -// FIXME(adotinthevoid): Theses shouldn't be here -// @has "$.index[*][?(@.name=='Debug')]" - -// Debug may have several items. All we depend on here the that `fmt` is first. See -// https://github.com/rust-lang/rust/pull/104525#issuecomment-1331087852 for why we -// can't use [*]. - -// @set Debug_fmt = "$.index[*][?(@.name=='Debug')].inner.items[0]" -// @has "$.index[*][?(@.name=='fmt')].id" $Debug_fmt +// @!has "$.index[*][?(@.name=='Debug')]" +// @!has "$.index[*][?(@.name=='Default')]" diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index 5046ab9c7cb..e15f5fe3ccc 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -60,6 +60,8 @@ pub fn check_crate(&mut self) { fn check_item(&mut self, id: &'a Id) { if let Some(item) = &self.krate.index.get(id) { + item.links.values().for_each(|id| self.add_any_id(id)); + match &item.inner { ItemEnum::Import(x) => self.check_import(x), ItemEnum::Union(x) => self.check_union(x), @@ -376,6 +378,10 @@ fn add_id_checked(&mut self, id: &'a Id, valid: fn(Kind) -> bool, expected: &str } } + fn add_any_id(&mut self, id: &'a Id) { + self.add_id_checked(id, |_| true, "any kind of item"); + } + fn add_field_id(&mut self, id: &'a Id) { self.add_id_checked(id, Kind::is_struct_field, "StructField"); } @@ -446,3 +452,6 @@ fn set_remove(set: &mut HashSet) -> Option { None } } + +#[cfg(test)] +mod tests; diff --git a/src/tools/jsondoclint/src/validator/tests.rs b/src/tools/jsondoclint/src/validator/tests.rs new file mode 100644 index 00000000000..c4aeee9c53b --- /dev/null +++ b/src/tools/jsondoclint/src/validator/tests.rs @@ -0,0 +1,50 @@ +use std::collections::HashMap; + +use rustdoc_json_types::{Crate, Item, Visibility}; + +use super::*; + +#[track_caller] +fn check(krate: &Crate, errs: &[Error]) { + let mut validator = Validator::new(krate); + validator.check_crate(); + + assert_eq!(errs, &validator.errs[..]); +} + +fn id(s: &str) -> Id { + Id(s.to_owned()) +} + +#[test] +fn errors_on_missing_links() { + let k = Crate { + root: id("0"), + crate_version: None, + includes_private: false, + index: HashMap::from_iter([( + id("0"), + Item { + name: Some("root".to_owned()), + id: id(""), + crate_id: 0, + span: None, + visibility: Visibility::Public, + docs: None, + links: HashMap::from_iter([("Not Found".to_owned(), id("1"))]), + attrs: vec![], + deprecation: None, + inner: ItemEnum::Module(Module { + is_crate: true, + items: vec![], + is_stripped: false, + }), + }, + )]), + paths: HashMap::new(), + external_crates: HashMap::new(), + format_version: rustdoc_json_types::FORMAT_VERSION, + }; + + check(&k, &[Error { kind: ErrorKind::NotFound, id: id("1") }]); +}