Skip to content
4 changes: 1 addition & 3 deletions src/librustdoc/clean/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
visibility: Inherited,
def_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
kind: box ImplItem(Impl {
span: Span::dummy(),
unsafety: hir::Unsafety::Normal,
generics: new_generics,
trait_: Some(trait_ref.clean(self.cx)),
for_: ty.clean(self.cx),
items: Vec::new(),
negative_polarity,
synthetic: true,
blanket_impl: None,
kind: ImplKind::Auto,
}),
cfg: None,
})
Expand Down
4 changes: 1 addition & 3 deletions src/librustdoc/clean/blanket_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
visibility: Inherited,
def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
kind: box ImplItem(Impl {
span: Span::new(self.cx.tcx.def_span(impl_def_id)),
unsafety: hir::Unsafety::Normal,
generics: (
self.cx.tcx.generics_of(impl_def_id),
Expand All @@ -125,8 +124,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
.collect::<Vec<_>>()
.clean(self.cx),
negative_polarity: false,
synthetic: false,
blanket_impl: Some(box trait_ref.self_ty().clean(self.cx)),
kind: ImplKind::Blanket(box trait_ref.self_ty().clean(self.cx)),
}),
cfg: None,
});
Expand Down
8 changes: 4 additions & 4 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};

use crate::clean::{self, utils, Attributes, AttributesExt, ItemId, NestedAttributesExt, Type};
use crate::clean::{
self, utils, Attributes, AttributesExt, ImplKind, ItemId, NestedAttributesExt, Type,
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;

Expand Down Expand Up @@ -490,15 +492,13 @@ crate fn build_impl(
did,
None,
clean::ImplItem(clean::Impl {
span: clean::types::rustc_span(did, cx.tcx),
unsafety: hir::Unsafety::Normal,
generics,
trait_,
for_,
items: trait_items,
negative_polarity: polarity.clean(cx),
synthetic: false,
blanket_impl: None,
kind: ImplKind::Normal,
}),
box merged_attrs,
cx,
Expand Down
4 changes: 1 addition & 3 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1889,15 +1889,13 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
});
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
let kind = ImplItem(Impl {
span: types::rustc_span(tcx.hir().local_def_id(hir_id).to_def_id(), tcx),
unsafety: impl_.unsafety,
generics: impl_.generics.clean(cx),
trait_,
for_,
items,
negative_polarity: tcx.impl_polarity(def_id).clean(cx),
synthetic: false,
blanket_impl: None,
kind: ImplKind::Normal,
});
Item::from_hir_id_and_parts(hir_id, None, kind, cx)
};
Expand Down
59 changes: 50 additions & 9 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,12 +391,19 @@ impl Item {
ItemKind::StrippedItem(k) => k,
_ => &*self.kind,
};
if let ItemKind::ModuleItem(Module { span, .. }) | ItemKind::ImplItem(Impl { span, .. }) =
kind
{
*span
} else {
self.def_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy)
match kind {
ItemKind::ModuleItem(Module { span, .. }) => *span,
ItemKind::ImplItem(Impl { kind: ImplKind::Auto, .. }) => Span::dummy(),
ItemKind::ImplItem(Impl { kind: ImplKind::Blanket(_), .. }) => {
if let ItemId::Blanket { impl_id, .. } = self.def_id {
rustc_span(impl_id, tcx)
} else {
panic!("blanket impl item has non-blanket ID")
}
}
_ => {
self.def_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy)
}
}
}

Expand Down Expand Up @@ -2165,18 +2172,28 @@ impl Constant {

#[derive(Clone, Debug)]
crate struct Impl {
crate span: Span,
crate unsafety: hir::Unsafety,
crate generics: Generics,
crate trait_: Option<Path>,
crate for_: Type,
crate items: Vec<Item>,
crate negative_polarity: bool,
crate synthetic: bool,
crate blanket_impl: Option<Box<Type>>,
crate kind: ImplKind,
}

impl Impl {
crate fn is_auto_impl(&self) -> bool {
self.kind.is_auto()
}

crate fn is_blanket_impl(&self) -> bool {
self.kind.is_blanket()
}

crate fn blanket_impl_ty(&self) -> Option<&Type> {
self.kind.as_blanket_ty()
}

crate fn provided_trait_methods(&self, tcx: TyCtxt<'_>) -> FxHashSet<Symbol> {
self.trait_
.as_ref()
Expand All @@ -2186,6 +2203,30 @@ impl Impl {
}
}

#[derive(Clone, Debug)]
crate enum ImplKind {
Normal,
Auto,
Blanket(Box<Type>),
}

impl ImplKind {
crate fn is_auto(&self) -> bool {
matches!(self, ImplKind::Auto)
}

crate fn is_blanket(&self) -> bool {
matches!(self, ImplKind::Blanket(_))
}

crate fn as_blanket_ty(&self) -> Option<&Type> {
match self {
ImplKind::Blanket(ty) => Some(ty),
_ => None,
}
}
}

#[derive(Clone, Debug)]
crate struct Import {
crate kind: ImportKind,
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
// Collect all the implementors of traits.
if let clean::ImplItem(ref i) = *item.kind {
if let Some(trait_) = &i.trait_ {
if i.blanket_impl.is_none() {
if !i.is_blanket_impl() {
self.cache
.implementors
.entry(trait_.def_id())
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ impl clean::Impl {
write!(f, " for ")?;
}

if let Some(ref ty) = self.blanket_impl {
if let Some(ref ty) = self.blanket_impl_ty() {
fmt_type(ty, f, use_absolute, cx)?;
} else {
fmt_type(&self.for_, f, use_absolute, cx)?;
Expand Down
11 changes: 5 additions & 6 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1147,9 +1147,9 @@ fn render_assoc_items_inner(
}

let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) =
traits.iter().partition(|t| t.inner_impl().synthetic);
traits.iter().partition(|t| t.inner_impl().is_auto_impl());
let (blanket_impl, concrete): (Vec<&&Impl>, _) =
concrete.into_iter().partition(|t| t.inner_impl().blanket_impl.is_some());
concrete.into_iter().partition(|t| t.inner_impl().is_blanket_impl());

let mut impls = Buffer::empty_from(w);
render_impls(cx, &mut impls, &concrete, containing_item);
Expand Down Expand Up @@ -2058,10 +2058,9 @@ fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
};

let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
v.iter().partition::<Vec<_>, _>(|i| i.inner_impl().synthetic);
let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = concrete
.into_iter()
.partition::<Vec<_>, _>(|i| i.inner_impl().blanket_impl.is_some());
v.iter().partition::<Vec<_>, _>(|i| i.inner_impl().is_auto_impl());
let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) =
concrete.into_iter().partition::<Vec<_>, _>(|i| i.inner_impl().is_blanket_impl());

let concrete_format = format_impls(concrete);
let synthetic_format = format_impls(synthetic);
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
});

let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) =
local.iter().partition(|i| i.inner_impl().synthetic);
local.iter().partition(|i| i.inner_impl().is_auto_impl());

synthetic.sort_by(|a, b| compare_impl(a, b, cx));
concrete.sort_by(|a, b| compare_impl(a, b, cx));
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/render/write_shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ pub(super) fn write_shared(
} else {
Some(Implementor {
text: imp.inner_impl().print(false, cx).to_string(),
synthetic: imp.inner_impl().synthetic,
synthetic: imp.inner_impl().is_auto_impl(),
types: collect_paths_for_type(imp.inner_impl().for_.clone(), cache),
})
}
Expand Down
21 changes: 9 additions & 12 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,22 +500,19 @@ impl FromWithTcx<clean::Trait> for Trait {
impl FromWithTcx<clean::Impl> for Impl {
fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
let provided_trait_methods = impl_.provided_trait_methods(tcx);
let clean::Impl {
unsafety,
generics,
trait_,
for_,
items,
negative_polarity,
synthetic,
blanket_impl,
span: _span,
} = impl_;
let clean::Impl { unsafety, generics, trait_, for_, items, negative_polarity, kind } =
impl_;
// FIXME: should `trait_` be a clean::Path equivalent in JSON?
let trait_ = trait_.map(|path| {
let did = path.def_id();
clean::ResolvedPath { path, did }.into_tcx(tcx)
});
// FIXME: use something like ImplKind in JSON?
let (synthetic, blanket_impl) = match kind {
clean::ImplKind::Normal => (false, None),
clean::ImplKind::Auto => (true, None),
clean::ImplKind::Blanket(ty) => (false, Some(*ty)),
};
Impl {
is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe,
generics: generics.into_tcx(tcx),
Expand All @@ -528,7 +525,7 @@ impl FromWithTcx<clean::Impl> for Impl {
items: ids(items),
negative: negative_polarity,
synthetic,
blanket_impl: blanket_impl.map(|x| (*x).into_tcx(tcx)),
blanket_impl: blanket_impl.map(|x| x.into_tcx(tcx)),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/passes/collect_trait_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,12 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate
}

new_items.retain(|it| {
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
if let ImplItem(Impl { ref for_, ref trait_, ref kind, .. }) = *it.kind {
cleaner.keep_impl(
for_,
trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait(),
) || trait_.as_ref().map_or(false, |t| cleaner.keep_impl_with_def_id(t.def_id().into()))
|| blanket_impl.is_some()
|| kind.is_blanket()
} else {
true
}
Expand Down