diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 1436e51f318..c83a191baf5 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -118,7 +118,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { span: Span::dummy(), unsafety: hir::Unsafety::Normal, generics: new_generics, - trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()), + trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap().expect_path()), for_: ty.clean(self.cx), items: Vec::new(), negative_polarity, diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 8135d4a2085..4385c1adc09 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -114,7 +114,9 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .clean(self.cx), // FIXME(eddyb) compute both `trait_` and `for_` from // the post-inference `trait_ref`, as it's more accurate. - trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()), + trait_: Some( + trait_ref.clean(self.cx).get_trait_type().unwrap().expect_path(), + ), for_: ty.clean(self.cx), items: self .cx diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index daff902aaa5..7a08e54d4b1 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -483,7 +483,7 @@ crate fn build_impl( span: clean::types::rustc_span(did, cx.tcx), unsafety: hir::Unsafety::Normal, generics, - trait_, + trait_: trait_.map(|t| t.expect_path()), for_, items: trait_items, negative_polarity: polarity.clean(cx), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a7960807f4c..21389fa38a8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -903,6 +903,12 @@ impl Clean for hir::TraitRef<'_> { } } +impl Clean for hir::TraitRef<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Path { + self.path.clean(cx) + } +} + impl Clean for hir::PolyTraitRef<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait { PolyTrait { @@ -1902,7 +1908,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_> DefKind::TyAlias => Some(tcx.type_of(did).clean(cx)), _ => None, }); - let mut make_item = |trait_: Option, for_: Type, items: Vec| { + let mut make_item = |trait_: Option, for_: Type, items: Vec| { let kind = ImplItem(Impl { span: types::rustc_span(tcx.hir().local_def_id(hir_id).to_def_id(), tcx), unsafety: impl_.unsafety, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7b0d331045c..a5f71c4a849 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1473,6 +1473,15 @@ impl Type { } } + // FIXME: temporary + #[track_caller] + crate fn expect_path(self) -> Path { + match self { + ResolvedPath { path, .. } => path, + _ => panic!("not a ResolvedPath: {:?}", self), + } + } + crate fn is_self_type(&self) -> bool { match *self { Generic(name) => name == kw::SelfUpper, @@ -1481,21 +1490,8 @@ impl Type { } crate fn generics(&self) -> Option> { - match *self { - ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| { - if let GenericArgs::AngleBracketed { ref args, .. } = seg.args { - Some( - args.iter() - .filter_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty), - _ => None, - }) - .collect(), - ) - } else { - None - } - }), + match self { + ResolvedPath { path, .. } => path.generics(), _ => None, } } @@ -1993,6 +1989,34 @@ impl Path { _ => false, } } + + crate fn generics(&self) -> Option> { + self.segments.last().and_then(|seg| { + if let GenericArgs::AngleBracketed { ref args, .. } = seg.args { + Some( + args.iter() + .filter_map(|arg| match arg { + GenericArg::Type(ty) => Some(ty), + _ => None, + }) + .collect(), + ) + } else { + None + } + }) + } +} + +// FIXME: this is temporary +impl GetDefId for Path { + fn def_id(&self) -> Option { + Some(self.res.def_id()) + } + + fn def_id_full(&self, _: &Cache) -> Option { + self.def_id() + } } #[derive(Clone, PartialEq, Eq, Debug, Hash)] @@ -2136,7 +2160,7 @@ crate struct Impl { crate span: Span, crate unsafety: hir::Unsafety, crate generics: Generics, - crate trait_: Option, + crate trait_: Option, crate for_: Type, crate items: Vec, crate negative_polarity: bool, diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index 6060b0560cf..86e867d4006 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -14,7 +14,7 @@ use crate::formats::cache::Cache; /// impl. crate enum AssocItemRender<'a> { All, - DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool }, + DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool }, } /// For different handling of associated items from the Deref target of a type rather than the type diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index bcd78b2adc0..4338ed7160c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -979,6 +979,15 @@ impl clean::Type { } } +impl clean::Path { + crate fn print<'b, 'a: 'b, 'tcx: 'a>( + &'a self, + cx: &'a Context<'tcx>, + ) -> impl fmt::Display + 'b + Captures<'tcx> { + display_fn(move |f| resolved_path(f, self.res.def_id(), self, false, false, cx)) + } +} + impl clean::Impl { crate fn print<'a, 'tcx: 'a>( &'a self, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1f27357f6c6..83cd2af169a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2056,10 +2056,10 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea fn get_id_for_impl_on_foreign_type( for_: &clean::Type, - trait_: &clean::Type, + trait_: &clean::Path, cx: &Context<'_>, ) -> String { - small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx),)) + small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx))) } fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index ea81b041c3b..df9a07499ac 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -507,6 +507,11 @@ impl FromWithTcx for Impl { blanket_impl, span: _span, } = impl_; + // FIXME: should `trait_` be a Path in JSON? + let trait_ = trait_.map(|path| { + let did = path.res.def_id(); + clean::ResolvedPath { path, did }.into_tcx(tcx) + }); Impl { is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe, generics: generics.into_tcx(tcx), @@ -514,7 +519,7 @@ impl FromWithTcx for Impl { .into_iter() .map(|x| x.to_string()) .collect(), - trait_: trait_.map(|x| x.into_tcx(tcx)), + trait_, for_: for_.into_tcx(tcx), items: ids(items), negative: negative_polarity, diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index eefe50caa34..e8aa37c8868 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -78,7 +78,9 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { new_items.retain(|it| { if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind { cleaner.keep_impl(for_) - || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t)) + || trait_ + .as_ref() + .map_or(false, |t| cleaner.keep_impl_with_def_id(t.res.def_id().into())) || blanket_impl.is_some() } else { true