rustdoc: Refactor Impl.{synthetic,blanket_impl}
into enum
This change has two advantages: 1. It makes the possible states clearer, and it makes it impossible to construct invalid states, such as a blanket impl that is also an auto trait impl. 2. It shrinks the size of `Impl` a bit, since now there is only one field, rather than two.
This commit is contained in:
parent
c32ee54380
commit
7b7023cb72
@ -121,8 +121,7 @@ fn generate_for_trait(
|
||||
for_: ty.clean(self.cx),
|
||||
items: Vec::new(),
|
||||
negative_polarity,
|
||||
synthetic: true,
|
||||
blanket_impl: None,
|
||||
kind: ImplKind::Auto,
|
||||
}),
|
||||
cfg: None,
|
||||
})
|
||||
|
@ -124,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,
|
||||
});
|
||||
|
@ -14,7 +14,9 @@
|
||||
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;
|
||||
|
||||
@ -496,8 +498,7 @@ fn merge_attrs(
|
||||
for_,
|
||||
items: trait_items,
|
||||
negative_polarity: polarity.clean(cx),
|
||||
synthetic: false,
|
||||
blanket_impl: None,
|
||||
kind: ImplKind::Normal,
|
||||
}),
|
||||
box merged_attrs,
|
||||
cx,
|
||||
|
@ -1895,8 +1895,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
|
||||
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)
|
||||
};
|
||||
|
@ -393,8 +393,8 @@ impl Item {
|
||||
};
|
||||
match kind {
|
||||
ItemKind::ModuleItem(Module { span, .. }) => *span,
|
||||
ItemKind::ImplItem(Impl { synthetic: true, .. }) => Span::dummy(),
|
||||
ItemKind::ImplItem(Impl { blanket_impl: Some(_), .. }) => {
|
||||
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 {
|
||||
@ -2178,11 +2178,22 @@ impl Constant {
|
||||
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()
|
||||
@ -2192,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,
|
||||
|
@ -228,7 +228,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
|
||||
// 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())
|
||||
|
@ -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)?;
|
||||
|
@ -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);
|
||||
@ -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);
|
||||
|
@ -746,7 +746,7 @@ fn trait_item(w: &mut Buffer, cx: &Context<'_>, m: &clean::Item, t: &clean::Item
|
||||
});
|
||||
|
||||
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));
|
||||
|
@ -585,7 +585,7 @@ struct Implementor {
|
||||
} 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),
|
||||
})
|
||||
}
|
||||
|
@ -500,21 +500,19 @@ fn from_tcx(trait_: clean::Trait, tcx: TyCtxt<'_>) -> Self {
|
||||
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,
|
||||
} = 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),
|
||||
@ -527,7 +525,7 @@ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
|
||||
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)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,12 +111,12 @@ fn add_deref_target(
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user