提交 4c6385ff 编写于 作者: N Noah Lev

Make `Impl.trait_` a `Path`, not a `Type`

It should only ever be a `ResolvedPath`, so this (a) enforces that, and
(b) reduces the size of `Impl`.

I had to update a test because the order of the rendered auto trait impl
bounds changed. I think the order changed because rustdoc sorts auto
trait bounds using their `Debug` output.
上级 d91946b3
......@@ -118,7 +118,7 @@ fn generate_for_trait(
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,
......
......@@ -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
......
......@@ -483,7 +483,7 @@ fn merge_attrs(
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),
......
......@@ -903,6 +903,12 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
}
}
impl Clean<Path> for hir::TraitRef<'_> {
fn clean(&self, cx: &mut DocContext<'_>) -> Path {
self.path.clean(cx)
}
}
impl Clean<PolyTrait> 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<Type>, for_: Type, items: Vec<Item>| {
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,
......
......@@ -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<Vec<&Type>> {
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<Vec<&Type>> {
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<DefId> {
Some(self.res.def_id())
}
fn def_id_full(&self, _: &Cache) -> Option<DefId> {
self.def_id()
}
}
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
......@@ -2136,7 +2160,7 @@ impl Constant {
crate span: Span,
crate unsafety: hir::Unsafety,
crate generics: Generics,
crate trait_: Option<Type>,
crate trait_: Option<Path>,
crate for_: Type,
crate items: Vec<Item>,
crate negative_polarity: bool,
......
......@@ -14,7 +14,7 @@
/// 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
......
......@@ -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,
......
......@@ -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)> {
......
......@@ -507,6 +507,11 @@ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
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 @@ fn from_tcx(impl_: clean::Impl, tcx: TyCtxt<'_>) -> Self {
.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,
......
......@@ -78,7 +78,9 @@
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册