Skip to content

Commit 664b3ff

Browse files
committed
rustdoc: Create SelfTy to replace Generic(kw::SelfUpper)
Rustdoc often has to special-case `Self` because it is, well, a special type of generic parameter (although it also behaves as an alias in concrete impls). Instead of spreading this special-casing throughout the code base, create a new variant of the `clean::Type` enum that is for `Self` types. This is a refactoring that has almost no impact on rustdoc's behavior, except that `&Self`, `(Self,)`, `&[Self]`, and other similar occurrences of `Self` no longer link to the wrapping type (reference primitive, tuple primitive, etc.) as regular generics do. I felt this made more sense since users would expect `Self` to link to the containing trait or aliased type (though those are usually expanded), not the primitive that is wrapping it. For an example of the change, see the docs for `std::alloc::Allocator::by_ref`.
1 parent 249d686 commit 664b3ff

File tree

8 files changed

+35
-25
lines changed

8 files changed

+35
-25
lines changed

src/librustdoc/clean/inline.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType;
1212
use rustc_middle::ty::{self, TyCtxt};
1313
use rustc_span::def_id::LOCAL_CRATE;
1414
use rustc_span::hygiene::MacroKind;
15-
use rustc_span::symbol::{kw, sym, Symbol};
15+
use rustc_span::symbol::{sym, Symbol};
1616
use thin_vec::{thin_vec, ThinVec};
1717
use {rustc_ast as ast, rustc_hir as hir};
1818

@@ -792,11 +792,7 @@ fn build_macro(
792792
fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
793793
for pred in &mut g.where_predicates {
794794
match *pred {
795-
clean::WherePredicate::BoundPredicate {
796-
ty: clean::Generic(ref s),
797-
ref mut bounds,
798-
..
799-
} if *s == kw::SelfUpper => {
795+
clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref mut bounds, .. } => {
800796
bounds.retain(|bound| match bound {
801797
clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => {
802798
trait_.def_id() != trait_did
@@ -812,13 +808,13 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
812808
clean::WherePredicate::BoundPredicate {
813809
ty:
814810
clean::QPath(box clean::QPathData {
815-
self_type: clean::Generic(ref s),
811+
self_type: clean::Generic(_),
816812
trait_: Some(trait_),
817813
..
818814
}),
819815
bounds,
820816
..
821-
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
817+
} => !bounds.is_empty() && trait_.def_id() != trait_did,
822818
_ => true,
823819
});
824820
g
@@ -832,9 +828,7 @@ fn separate_supertrait_bounds(
832828
) -> (clean::Generics, Vec<clean::GenericBound>) {
833829
let mut ty_bounds = Vec::new();
834830
g.where_predicates.retain(|pred| match *pred {
835-
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
836-
if *s == kw::SelfUpper =>
837-
{
831+
clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref bounds, .. } => {
838832
ty_bounds.extend(bounds.iter().cloned());
839833
false
840834
}

src/librustdoc/clean/mod.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1351,11 +1351,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
13511351
let self_arg_ty =
13521352
tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
13531353
if self_arg_ty == self_ty {
1354-
item.decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
1354+
item.decl.inputs.values[0].type_ = SelfTy;
13551355
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
13561356
if ty == self_ty {
13571357
match item.decl.inputs.values[0].type_ {
1358-
BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
1358+
BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
13591359
_ => unreachable!(),
13601360
}
13611361
}
@@ -1439,9 +1439,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
14391439
if trait_.def_id() != assoc_item.container_id(tcx) {
14401440
return true;
14411441
}
1442-
match *self_type {
1443-
Generic(ref s) if *s == kw::SelfUpper => {}
1444-
_ => return true,
1442+
if *self_type != SelfTy {
1443+
return true;
14451444
}
14461445
match &assoc.args {
14471446
GenericArgs::AngleBracketed { args, constraints } => {
@@ -2228,6 +2227,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
22282227
ty::Param(ref p) => {
22292228
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
22302229
ImplTrait(bounds)
2230+
} else if p.name == kw::SelfUpper {
2231+
SelfTy
22312232
} else {
22322233
Generic(p.name)
22332234
}

src/librustdoc/clean/simplify.rs

-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi
145145
// should be handled when cleaning associated types.
146146
generics.where_predicates.retain(|pred| {
147147
if let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred
148-
&& *param != rustc_span::symbol::kw::SelfUpper
149148
&& bounds.iter().any(|b| b.is_sized_bound(cx))
150149
{
151150
sized_params.insert(*param);

src/librustdoc/clean/types.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub(crate) use self::ItemKind::*;
3737
pub(crate) use self::ReceiverTy::*;
3838
pub(crate) use self::Type::{
3939
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
40-
RawPointer, Slice, Tuple,
40+
RawPointer, SelfTy, Slice, Tuple,
4141
};
4242
use crate::clean::cfg::Cfg;
4343
use crate::clean::clean_middle_path;
@@ -1477,6 +1477,8 @@ pub(crate) enum Type {
14771477
DynTrait(Vec<PolyTrait>, Option<Lifetime>),
14781478
/// A type parameter.
14791479
Generic(Symbol),
1480+
/// The `Self` type.
1481+
SelfTy,
14801482
/// A primitive (aka, builtin) type.
14811483
Primitive(PrimitiveType),
14821484
/// A function pointer: `extern "ABI" fn(...) -> ...`
@@ -1571,6 +1573,8 @@ impl Type {
15711573
// If both sides are generic, this returns true.
15721574
(_, Type::Generic(_)) => true,
15731575
(Type::Generic(_), _) => false,
1576+
// `Self` only matches itself.
1577+
(Type::SelfTy, Type::SelfTy) => true,
15741578
// Paths account for both the path itself and its generics.
15751579
(Type::Path { path: a }, Type::Path { path: b }) => {
15761580
a.def_id() == b.def_id()
@@ -1642,7 +1646,7 @@ impl Type {
16421646

16431647
pub(crate) fn is_self_type(&self) -> bool {
16441648
match *self {
1645-
Generic(name) => name == kw::SelfUpper,
1649+
SelfTy => true,
16461650
_ => false,
16471651
}
16481652
}
@@ -1700,7 +1704,7 @@ impl Type {
17001704
Type::Pat(..) => PrimitiveType::Pat,
17011705
RawPointer(..) => PrimitiveType::RawPointer,
17021706
QPath(box QPathData { ref self_type, .. }) => return self_type.def_id(cache),
1703-
Generic(_) | Infer | ImplTrait(_) => return None,
1707+
Generic(_) | SelfTy | Infer | ImplTrait(_) => return None,
17041708
};
17051709
Primitive(t).def_id(cache)
17061710
}

src/librustdoc/clean/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
468468
match path.res {
469469
Res::PrimTy(p) => Primitive(PrimitiveType::from(p)),
470470
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } if path.segments.len() == 1 => {
471-
Generic(kw::SelfUpper)
471+
Type::SelfTy
472472
}
473473
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
474474
_ => {

src/librustdoc/html/format.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,7 @@ fn fmt_type<'cx>(
10061006

10071007
match *t {
10081008
clean::Generic(name) => f.write_str(name.as_str()),
1009+
clean::SelfTy => f.write_str("Self"),
10091010
clean::Type::Path { ref path } => {
10101011
// Paths like `T::Output` and `Self::Output` should be rendered with all segments.
10111012
let did = path.def_id();

src/librustdoc/html/render/search_index.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,11 @@ fn get_index_type_id(
797797
}
798798
}
799799
// Not supported yet
800-
clean::Type::Pat(..) | clean::Generic(_) | clean::ImplTrait(_) | clean::Infer => None,
800+
clean::Type::Pat(..)
801+
| clean::Generic(_)
802+
| clean::SelfTy
803+
| clean::ImplTrait(_)
804+
| clean::Infer => None,
801805
}
802806
}
803807

@@ -848,13 +852,18 @@ fn simplify_fn_type<'tcx, 'a>(
848852
(false, arg)
849853
};
850854

855+
let as_arg_s = |t: &Type| match *t {
856+
Type::Generic(arg_s) => Some(arg_s),
857+
Type::SelfTy => Some(kw::SelfUpper),
858+
_ => None,
859+
};
851860
// If this argument is a type parameter and not a trait bound or a type, we need to look
852861
// for its bounds.
853-
if let Type::Generic(arg_s) = *arg {
862+
if let Some(arg_s) = as_arg_s(arg) {
854863
// First we check if the bounds are in a `where` predicate...
855864
let mut type_bounds = Vec::new();
856865
for where_pred in generics.where_predicates.iter().filter(|g| match g {
857-
WherePredicate::BoundPredicate { ty: Type::Generic(ty_s), .. } => *ty_s == arg_s,
866+
WherePredicate::BoundPredicate { ty, .. } => *ty == *arg,
858867
_ => false,
859868
}) {
860869
let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);

src/librustdoc/json/conversions.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ impl FromWithTcx<clean::Type> for Type {
578578
fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
579579
use clean::Type::{
580580
Array, BareFunction, BorrowedRef, Generic, ImplTrait, Infer, Primitive, QPath,
581-
RawPointer, Slice, Tuple,
581+
RawPointer, SelfTy, Slice, Tuple,
582582
};
583583

584584
match ty {
@@ -588,6 +588,8 @@ impl FromWithTcx<clean::Type> for Type {
588588
traits: bounds.into_tcx(tcx),
589589
}),
590590
Generic(s) => Type::Generic(s.to_string()),
591+
// FIXME: add dedicated variant to json Type?
592+
SelfTy => Type::Generic("Self".to_owned()),
591593
Primitive(p) => Type::Primitive(p.as_sym().to_string()),
592594
BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
593595
Tuple(t) => Type::Tuple(t.into_tcx(tcx)),

0 commit comments

Comments
 (0)