Skip to content

Commit

Permalink
Rollup merge of #128471 - camelid:rustdoc-self, r=notriddle
Browse files Browse the repository at this point in the history
rustdoc: Fix handling of `Self` type in search index and refactor its representation

### Summary

- Add enum variant `clean::Type::SelfTy` and use it instead of `clean::Type::Generic(kw::SelfUpper)`.
- Stop treating `Self` as a generic in the search index.
- Remove struct formerly known as `clean::SelfTy` (constructed as representation of function receiver type). We're better off without it.

### Before

![image](https://github.com/user-attachments/assets/d257bdd8-3a62-4c71-84a5-9c950f2e4f00)

### After

![image](https://github.com/user-attachments/assets/8f6d3f22-92c1-41e3-9ab8-a881b66816c0)

r? ```@notriddle```
cc #127589 (comment)
  • Loading branch information
matthiaskrgr authored Aug 5, 2024
2 parents 02c3837 + dac7f20 commit 4adefa4
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 306 deletions.
16 changes: 5 additions & 11 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::LOCAL_CRATE;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::symbol::{sym, Symbol};
use thin_vec::{thin_vec, ThinVec};
use {rustc_ast as ast, rustc_hir as hir};

Expand Down Expand Up @@ -792,11 +792,7 @@ fn build_macro(
fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
for pred in &mut g.where_predicates {
match *pred {
clean::WherePredicate::BoundPredicate {
ty: clean::Generic(ref s),
ref mut bounds,
..
} if *s == kw::SelfUpper => {
clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref mut bounds, .. } => {
bounds.retain(|bound| match bound {
clean::GenericBound::TraitBound(clean::PolyTrait { trait_, .. }, _) => {
trait_.def_id() != trait_did
Expand All @@ -812,13 +808,13 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
clean::WherePredicate::BoundPredicate {
ty:
clean::QPath(box clean::QPathData {
self_type: clean::Generic(ref s),
self_type: clean::Generic(_),
trait_: Some(trait_),
..
}),
bounds,
..
} => !(bounds.is_empty() || *s == kw::SelfUpper && trait_.def_id() == trait_did),
} => !bounds.is_empty() && trait_.def_id() != trait_did,
_ => true,
});
g
Expand All @@ -832,9 +828,7 @@ fn separate_supertrait_bounds(
) -> (clean::Generics, Vec<clean::GenericBound>) {
let mut ty_bounds = Vec::new();
g.where_predicates.retain(|pred| match *pred {
clean::WherePredicate::BoundPredicate { ty: clean::Generic(ref s), ref bounds, .. }
if *s == kw::SelfUpper =>
{
clean::WherePredicate::BoundPredicate { ty: clean::SelfTy, ref bounds, .. } => {
ty_bounds.extend(bounds.iter().cloned());
false
}
Expand Down
11 changes: 6 additions & 5 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,11 +1351,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
let self_arg_ty =
tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
if self_arg_ty == self_ty {
item.decl.inputs.values[0].type_ = Generic(kw::SelfUpper);
item.decl.inputs.values[0].type_ = SelfTy;
} else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
if ty == self_ty {
match item.decl.inputs.values[0].type_ {
BorrowedRef { ref mut type_, .. } => **type_ = Generic(kw::SelfUpper),
BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
_ => unreachable!(),
}
}
Expand Down Expand Up @@ -1439,9 +1439,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
if trait_.def_id() != assoc_item.container_id(tcx) {
return true;
}
match *self_type {
Generic(ref s) if *s == kw::SelfUpper => {}
_ => return true,
if *self_type != SelfTy {
return true;
}
match &assoc.args {
GenericArgs::AngleBracketed { args, constraints } => {
Expand Down Expand Up @@ -2228,6 +2227,8 @@ pub(crate) fn clean_middle_ty<'tcx>(
ty::Param(ref p) => {
if let Some(bounds) = cx.impl_trait_bounds.remove(&p.index.into()) {
ImplTrait(bounds)
} else if p.name == kw::SelfUpper {
SelfTy
} else {
Generic(p.name)
}
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/clean/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ pub(crate) fn sized_bounds(cx: &mut DocContext<'_>, generics: &mut clean::Generi
// should be handled when cleaning associated types.
generics.where_predicates.retain(|pred| {
if let WP::BoundPredicate { ty: clean::Generic(param), bounds, .. } = pred
&& *param != rustc_span::symbol::kw::SelfUpper
&& bounds.iter().any(|b| b.is_sized_bound(cx))
{
sized_params.insert(*param);
Expand Down
37 changes: 11 additions & 26 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ use thin_vec::ThinVec;
use {rustc_ast as ast, rustc_hir as hir};

pub(crate) use self::ItemKind::*;
pub(crate) use self::SelfTy::*;
pub(crate) use self::Type::{
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
RawPointer, Slice, Tuple,
RawPointer, SelfTy, Slice, Tuple,
};
use crate::clean::cfg::Cfg;
use crate::clean::clean_middle_path;
Expand Down Expand Up @@ -1384,8 +1383,8 @@ pub(crate) struct FnDecl {
}

impl FnDecl {
pub(crate) fn self_type(&self) -> Option<SelfTy> {
self.inputs.values.get(0).and_then(|v| v.to_self())
pub(crate) fn receiver_type(&self) -> Option<&Type> {
self.inputs.values.get(0).and_then(|v| v.to_receiver())
}
}

Expand All @@ -1403,27 +1402,9 @@ pub(crate) struct Argument {
pub(crate) is_const: bool,
}

#[derive(Clone, PartialEq, Debug)]
pub(crate) enum SelfTy {
SelfValue,
SelfBorrowed(Option<Lifetime>, Mutability),
SelfExplicit(Type),
}

impl Argument {
pub(crate) fn to_self(&self) -> Option<SelfTy> {
if self.name != kw::SelfLower {
return None;
}
if self.type_.is_self_type() {
return Some(SelfValue);
}
match self.type_ {
BorrowedRef { ref lifetime, mutability, ref type_ } if type_.is_self_type() => {
Some(SelfBorrowed(lifetime.clone(), mutability))
}
_ => Some(SelfExplicit(self.type_.clone())),
}
pub(crate) fn to_receiver(&self) -> Option<&Type> {
if self.name == kw::SelfLower { Some(&self.type_) } else { None }
}
}

Expand Down Expand Up @@ -1477,6 +1458,8 @@ pub(crate) enum Type {
DynTrait(Vec<PolyTrait>, Option<Lifetime>),
/// A type parameter.
Generic(Symbol),
/// The `Self` type.
SelfTy,
/// A primitive (aka, builtin) type.
Primitive(PrimitiveType),
/// A function pointer: `extern "ABI" fn(...) -> ...`
Expand Down Expand Up @@ -1571,6 +1554,8 @@ impl Type {
// If both sides are generic, this returns true.
(_, Type::Generic(_)) => true,
(Type::Generic(_), _) => false,
// `Self` only matches itself.
(Type::SelfTy, Type::SelfTy) => true,
// Paths account for both the path itself and its generics.
(Type::Path { path: a }, Type::Path { path: b }) => {
a.def_id() == b.def_id()
Expand Down Expand Up @@ -1642,7 +1627,7 @@ impl Type {

pub(crate) fn is_self_type(&self) -> bool {
match *self {
Generic(name) => name == kw::SelfUpper,
SelfTy => true,
_ => false,
}
}
Expand Down Expand Up @@ -1700,7 +1685,7 @@ impl Type {
Type::Pat(..) => PrimitiveType::Pat,
RawPointer(..) => PrimitiveType::RawPointer,
QPath(box QPathData { ref self_type, .. }) => return self_type.def_id(cache),
Generic(_) | Infer | ImplTrait(_) => return None,
Generic(_) | SelfTy | Infer | ImplTrait(_) => return None,
};
Primitive(t).def_id(cache)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
match path.res {
Res::PrimTy(p) => Primitive(PrimitiveType::from(p)),
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } if path.segments.len() == 1 => {
Generic(kw::SelfUpper)
Type::SelfTy
}
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name),
_ => {
Expand Down
30 changes: 12 additions & 18 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ fn fmt_type<'cx>(

match *t {
clean::Generic(name) => f.write_str(name.as_str()),
clean::SelfTy => f.write_str("Self"),
clean::Type::Path { ref path } => {
// Paths like `T::Output` and `Self::Output` should be rendered with all segments.
let did = path.def_id();
Expand Down Expand Up @@ -1452,29 +1453,22 @@ impl clean::FnDecl {

let last_input_index = self.inputs.values.len().checked_sub(1);
for (i, input) in self.inputs.values.iter().enumerate() {
if let Some(selfty) = input.to_self() {
if let Some(selfty) = input.to_receiver() {
match selfty {
clean::SelfValue => {
clean::SelfTy => {
write!(f, "self")?;
}
clean::SelfBorrowed(Some(ref lt), mutability) => {
write!(
f,
"{amp}{lifetime} {mutability}self",
lifetime = lt.print(),
mutability = mutability.print_with_space(),
)?;
}
clean::SelfBorrowed(None, mutability) => {
write!(
f,
"{amp}{mutability}self",
mutability = mutability.print_with_space(),
)?;
clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
write!(f, "{amp}")?;
match lifetime {
Some(lt) => write!(f, "{lt} ", lt = lt.print())?,
None => {}
}
write!(f, "{mutability}self", mutability = mutability.print_with_space())?;
}
clean::SelfExplicit(ref typ) => {
_ => {
write!(f, "self: ")?;
typ.print(cx).fmt(f)?;
selfty.print(cx).fmt(f)?;
}
}
} else {
Expand Down
15 changes: 7 additions & 8 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use serde::{Serialize, Serializer};

pub(crate) use self::context::*;
pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc};
use crate::clean::{self, ItemId, RenderedLink, SelfTy};
use crate::clean::{self, ItemId, RenderedLink};
use crate::error::Error;
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
Expand Down Expand Up @@ -1372,21 +1372,20 @@ fn render_deref_methods(

fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool {
let self_type_opt = match *item.kind {
clean::MethodItem(ref method, _) => method.decl.self_type(),
clean::TyMethodItem(ref method) => method.decl.self_type(),
clean::MethodItem(ref method, _) => method.decl.receiver_type(),
clean::TyMethodItem(ref method) => method.decl.receiver_type(),
_ => None,
};

if let Some(self_ty) = self_type_opt {
let (by_mut_ref, by_box, by_value) = match self_ty {
SelfTy::SelfBorrowed(_, mutability)
| SelfTy::SelfExplicit(clean::BorrowedRef { mutability, .. }) => {
let (by_mut_ref, by_box, by_value) = match *self_ty {
clean::Type::BorrowedRef { mutability, .. } => {
(mutability == Mutability::Mut, false, false)
}
SelfTy::SelfExplicit(clean::Type::Path { path }) => {
clean::Type::Path { ref path } => {
(false, Some(path.def_id()) == tcx.lang_items().owned_box(), false)
}
SelfTy::SelfValue => (false, false, true),
clean::Type::SelfTy => (false, false, true),
_ => (false, false, false),
};

Expand Down
Loading

0 comments on commit 4adefa4

Please sign in to comment.