let lifted = self.lift_to_tcx(cx.tcx).unwrap();
let trait_ = lifted.trait_ref(cx.tcx).clean(cx);
let self_type = self.self_ty().clean(cx);
+ let self_def_id = self_type.def_id(&cx.cache);
+ let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
Type::QPath {
assoc: Box::new(projection_to_path_segment(*self, cx)),
- self_def_id: self_type.def_id(&cx.cache),
+ should_show_cast,
self_type: box self_type,
trait_,
}
}
}
+fn compute_should_show_cast(self_def_id: Option<DefId>, trait_: &Path, self_type: &Type) -> bool {
+ !trait_.segments.is_empty()
+ && self_def_id
+ .zip(Some(trait_.def_id()))
+ .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_)
+}
+
fn projection_to_path_segment(ty: ty::ProjectionTy<'_>, cx: &mut DocContext<'_>) -> PathSegment {
let item = cx.tcx.associated_item(ty.item_def_id);
let generics = cx.tcx.generics_of(ty.item_def_id);
// the cleaning process of the type itself. To resolve this and have the
// `self_def_id` set, we override it here.
// See https://github.com/rust-lang/rust/issues/85454
- if let QPath { ref mut self_def_id, .. } = default {
- *self_def_id = Some(cx.tcx.parent(self.def_id));
+ if let QPath { ref mut should_show_cast, ref trait_, ref self_type, .. } =
+ default
+ {
+ let self_def_id = cx.tcx.parent(self.def_id);
+ *should_show_cast =
+ compute_should_show_cast(self_def_id, trait_, self_type);
}
Some(default)
segments: trait_segments.iter().map(|x| x.clean(cx)).collect(),
};
register_res(cx, trait_.res);
+ let self_def_id = DefId::local(qself.hir_id.owner.local_def_index);
+ let self_type = qself.clean(cx);
+ let should_show_cast = compute_should_show_cast(Some(self_def_id), &trait_, &self_type);
Type::QPath {
assoc: Box::new(p.segments.last().expect("segments were empty").clean(cx)),
- self_def_id: Some(DefId::local(qself.hir_id.owner.local_def_index)),
- self_type: box qself.clean(cx),
+ should_show_cast,
+ self_type: box self_type,
trait_,
}
}
};
let trait_ = hir::Path { span, res, segments: &[] }.clean(cx);
register_res(cx, trait_.res);
+ let self_def_id = res.opt_def_id();
+ let self_type = qself.clean(cx);
+ let should_show_cast = compute_should_show_cast(self_def_id, &trait_, &self_type);
Type::QPath {
assoc: Box::new(segment.clean(cx)),
- self_def_id: res.opt_def_id(),
- self_type: box qself.clean(cx),
+ should_show_cast,
+ self_type: box self_type,
trait_,
}
}
QPath {
assoc: Box<PathSegment>,
self_type: Box<Type>,
- /// FIXME: This is a hack that should be removed; see [this discussion][1].
- ///
- /// [1]: https://github.com/rust-lang/rust/pull/85479#discussion_r635729093
- self_def_id: Option<DefId>,
+ /// FIXME: compute this field on demand.
+ should_show_cast: bool,
trait_: Path,
},
// `Type` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Type, 80);
+rustc_data_structures::static_assert_size!(Type, 72);
impl Type {
/// When comparing types for equality, it can help to ignore `&` wrapping.
// `GenericArg` can occur many times in a single `Path`, so make sure it
// doesn't increase in size unexpectedly.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(GenericArg, 88);
+rustc_data_structures::static_assert_size!(GenericArg, 80);
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
crate enum GenericArgs {
write!(f, "impl {}", print_generic_bounds(bounds, cx))
}
}
- clean::QPath { ref assoc, ref self_type, ref trait_, ref self_def_id } => {
- let should_show_cast = !trait_.segments.is_empty()
- && self_def_id
- .zip(Some(trait_.def_id()))
- .map_or(!self_type.is_self_type(), |(id, trait_)| id != trait_);
+ clean::QPath { ref assoc, ref self_type, ref trait_, should_show_cast } => {
if f.alternate() {
if should_show_cast {
write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?