mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-07 12:33:14 +00:00
Prevent to recompute should_show_cast
by passing down self_def_id
This commit is contained in:
parent
4054c0f3e6
commit
2e1369c198
@ -379,19 +379,31 @@ impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> Type {
|
||||
let lifted = self.lift_to_tcx(cx.tcx).unwrap();
|
||||
fn clean_projection<'tcx>(
|
||||
ty: ty::ProjectionTy<'tcx>,
|
||||
cx: &mut DocContext<'_>,
|
||||
def_id: Option<DefId>,
|
||||
) -> Type {
|
||||
let lifted = ty.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 self_type = ty.self_ty().clean(cx);
|
||||
let self_def_id = if let Some(def_id) = def_id {
|
||||
cx.tcx.opt_parent(def_id).or(Some(def_id))
|
||||
} else {
|
||||
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)),
|
||||
assoc: Box::new(projection_to_path_segment(ty, cx)),
|
||||
should_show_cast,
|
||||
self_type: box self_type,
|
||||
trait_,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> Type {
|
||||
clean_projection(*self, cx, None)
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,23 +434,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
|
||||
}
|
||||
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
|
||||
let default = if has_default {
|
||||
let mut default = cx.tcx.type_of(self.def_id).clean(cx);
|
||||
|
||||
// We need to reassign the `self_def_id`, if there's a parent (which is the
|
||||
// `Self` type), so we can properly render `<Self as X>` casts, because the
|
||||
// information about which type `Self` is, is only present here, but not in
|
||||
// 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 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)
|
||||
Some(clean_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id)))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -1534,10 +1530,9 @@ fn normalize<'tcx>(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> Type {
|
||||
trace!("cleaning type: {:?}", self);
|
||||
let ty = normalize(cx, *self).unwrap_or(*self);
|
||||
fn clean_ty<'tcx>(this: Ty<'tcx>, cx: &mut DocContext<'_>, def_id: Option<DefId>) -> Type {
|
||||
trace!("cleaning type: {:?}", this);
|
||||
let ty = normalize(cx, this).unwrap_or(this);
|
||||
match *ty.kind() {
|
||||
ty::Never => Primitive(PrimitiveType::Never),
|
||||
ty::Bool => Primitive(PrimitiveType::Bool),
|
||||
@ -1558,7 +1553,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
BorrowedRef { lifetime: r.clean(cx), mutability: mutbl, type_: box ty.clean(cx) }
|
||||
}
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
let ty = cx.tcx.lift(*self).expect("FnPtr lift failed");
|
||||
let ty = cx.tcx.lift(this).expect("FnPtr lift failed");
|
||||
let sig = ty.fn_sig(cx.tcx);
|
||||
let decl = clean_fn_decl_from_did_and_sig(cx, None, sig);
|
||||
BareFunction(box BareFunctionDecl {
|
||||
@ -1591,7 +1586,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
let mut dids = obj.principal_def_id().into_iter().chain(obj.auto_traits());
|
||||
let did = dids
|
||||
.next()
|
||||
.unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", self));
|
||||
.unwrap_or_else(|| panic!("found trait object `{:?}` with no traits?", this));
|
||||
let substs = match obj.principal() {
|
||||
Some(principal) => principal.skip_binder().substs,
|
||||
// marker traits have no substs.
|
||||
@ -1635,7 +1630,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
}
|
||||
ty::Tuple(t) => Tuple(t.iter().map(|t| t.clean(cx)).collect()),
|
||||
|
||||
ty::Projection(ref data) => data.clean(cx),
|
||||
ty::Projection(ref data) => clean_projection(*data, cx, def_id),
|
||||
|
||||
ty::Param(ref p) => {
|
||||
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
|
||||
@ -1682,17 +1677,11 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
let bindings: Vec<_> = bounds
|
||||
.iter()
|
||||
.filter_map(|bound| {
|
||||
if let ty::PredicateKind::Projection(proj) =
|
||||
bound.kind().skip_binder()
|
||||
{
|
||||
if proj.projection_ty.trait_ref(cx.tcx)
|
||||
== trait_ref.skip_binder()
|
||||
if let ty::PredicateKind::Projection(proj) = bound.kind().skip_binder()
|
||||
{
|
||||
if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
|
||||
Some(TypeBinding {
|
||||
assoc: projection_to_path_segment(
|
||||
proj.projection_ty,
|
||||
cx,
|
||||
),
|
||||
assoc: projection_to_path_segment(proj.projection_ty, cx),
|
||||
kind: TypeBindingKind::Equality {
|
||||
term: proj.term.clean(cx),
|
||||
},
|
||||
@ -1724,6 +1713,11 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
ty::Infer(..) => panic!("Infer"),
|
||||
ty::Error(_) => panic!("Error"),
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> Type {
|
||||
clean_ty(*self, cx, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user