Skip to content

Commit d4822c2

Browse files
committed
Auto merge of rust-lang#127589 - notriddle:notriddle/search-sem-3, r=GuillaumeGomez
rustdoc-search: simplify rules for generics and type params **Heads up!**: This PR is a follow-up that depends on rust-lang#124544. It adds 12dc24f, a change to the filtering behavior, and 9900ea4, a minor ranking tweak. Part of rust-lang/rust-project-goals#112 This PR overturns rust-lang#109802 ## Preview * no results: [`Box<[A]> -> Vec<B>`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3/std/index.html?search=Box%3C%5BA%5D%3E%20-%3E%20Vec%3CB%3E) * results: [`Box<[A]> -> Vec<A>`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3/std/index.html?search=Box%3C%5BA%5D%3E%20-%3E%20Vec%3CA%3E) * [`T -> U`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3/std/index.html?search=T%20-%3E%20U) * [`Cx -> TyCtxt`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3-compiler/rustdoc/index.html?search=Cx%20-%3E%20TyCtxt) ![image](https://github.com/user-attachments/assets/015ae28c-7469-4f7f-be03-157d28d7ec97) ## Description This commit is a response to feedback on the displayed type signatures results, by making generics act stricter. - Order within generics is significant. This means `Vec<Allocator>` now matches only with a true vector of allocators, instead of matching the second type param. It also makes unboxing within generics stricter, so `Result<A, B>` only matches if `B` is in the error type and `A` is in the success type. The top level of the function search is unaffected. - Generics are only "unboxed" if a type is explicitly opted into it. References and tuples are hardcoded to allow unboxing, and Box, Rc, Arc, Option, Result, and Future are opted in with an unstable attribute. Search result unboxing is the process that allows you to search for `i32 -> str` and get back a function with the type signature `&Future<i32> -> Box<str>`. - Instead of ranking by set overlap, it ranks by the number of items in the type signature. This makes it easier to find single type signatures like transmute. ## Find the discussion on * <https://rust-lang.zulipchat.com/#narrow/stream/393423-t-rustdoc.2Fmeetings/topic/meeting.202024-07-08/near/449965149> * <rust-lang#124544 (comment)> * <https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/deciding.20on.20semantics.20of.20generics.20in.20rustdoc.20search>
2 parents 71042b4 + 9900ea4 commit d4822c2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1980
-851
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
204204
"meant for internal use only" {
205205
keyword => rustdoc_internals
206206
fake_variadic => rustdoc_internals
207+
search_unbox => rustdoc_internals
207208
}
208209
);
209210
}

compiler/rustc_passes/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,9 @@ passes_doc_masked_only_extern_crate =
234234
passes_doc_rust_logo =
235235
the `#[doc(rust_logo)]` attribute is used for Rust branding
236236
237+
passes_doc_search_unbox_invalid =
238+
`#[doc(search_unbox)]` should be used on generic structs and enums
239+
237240
passes_doc_test_literal = `#![doc(test(...)]` does not take a literal
238241
239242
passes_doc_test_takes_list =

compiler/rustc_passes/src/check_attr.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, B
1616
use rustc_hir::def_id::LocalModDefId;
1717
use rustc_hir::intravisit::{self, Visitor};
1818
use rustc_hir::{
19-
self as hir, self, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId, Item, ItemKind,
20-
MethodKind, Safety, Target, TraitItem,
19+
self as hir, self, AssocItemKind, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId,
20+
Item, ItemKind, MethodKind, Safety, Target, TraitItem,
2121
};
2222
use rustc_macros::LintDiagnostic;
2323
use rustc_middle::hir::nested_filter;
@@ -937,6 +937,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
937937
}
938938
}
939939

940+
fn check_doc_search_unbox(&self, meta: &MetaItemInner, hir_id: HirId) {
941+
let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else {
942+
self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
943+
return;
944+
};
945+
match item.kind {
946+
ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics)
947+
if generics.params.len() != 0 => {}
948+
ItemKind::Trait(_, _, generics, _, items)
949+
if generics.params.len() != 0
950+
|| items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
951+
_ => {
952+
self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
953+
}
954+
}
955+
}
956+
940957
/// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes.
941958
///
942959
/// A doc inlining attribute is invalid if it is applied to a non-`use` item, or
@@ -1149,6 +1166,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
11491166
}
11501167
}
11511168

1169+
sym::search_unbox => {
1170+
if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
1171+
self.check_doc_search_unbox(meta, hir_id);
1172+
}
1173+
}
1174+
11521175
sym::test => {
11531176
if self.check_attr_crate_level(attr, meta, hir_id) {
11541177
self.check_test_attr(meta, hir_id);

compiler/rustc_passes/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,13 @@ pub(crate) struct DocKeywordOnlyImpl {
244244
pub span: Span,
245245
}
246246

247+
#[derive(Diagnostic)]
248+
#[diag(passes_doc_search_unbox_invalid)]
249+
pub(crate) struct DocSearchUnboxInvalid {
250+
#[primary_span]
251+
pub span: Span,
252+
}
253+
247254
#[derive(Diagnostic)]
248255
#[diag(passes_doc_inline_conflict)]
249256
#[help]

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,7 @@ symbols! {
17611761
saturating_add,
17621762
saturating_div,
17631763
saturating_sub,
1764+
search_unbox,
17641765
select_unpredictable,
17651766
self_in_typedefs,
17661767
self_struct_ctor,

library/alloc/src/boxed.rs

+1
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ pub use thin::ThinBox;
225225
#[fundamental]
226226
#[stable(feature = "rust1", since = "1.0.0")]
227227
#[rustc_insignificant_dtor]
228+
#[cfg_attr(not(bootstrap), doc(search_unbox))]
228229
// The declaration of the `Box` struct must be kept in sync with the
229230
// compiler or ICEs will happen.
230231
pub struct Box<

library/alloc/src/rc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout {
307307
/// `value.get_mut()`. This avoids conflicts with methods of the inner type `T`.
308308
///
309309
/// [get_mut]: Rc::get_mut
310+
#[cfg_attr(not(bootstrap), doc(search_unbox))]
310311
#[cfg_attr(not(test), rustc_diagnostic_item = "Rc")]
311312
#[stable(feature = "rust1", since = "1.0.0")]
312313
#[rustc_insignificant_dtor]

library/alloc/src/sync.rs

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ macro_rules! acquire {
235235
/// counting in general.
236236
///
237237
/// [rc_examples]: crate::rc#examples
238+
#[cfg_attr(not(bootstrap), doc(search_unbox))]
238239
#[cfg_attr(not(test), rustc_diagnostic_item = "Arc")]
239240
#[stable(feature = "rust1", since = "1.0.0")]
240241
#[rustc_insignificant_dtor]

library/core/src/future/future.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::task::{Context, Poll};
2525
/// [`async`]: ../../std/keyword.async.html
2626
/// [`Waker`]: crate::task::Waker
2727
#[doc(notable_trait)]
28+
#[cfg_attr(not(bootstrap), doc(search_unbox))]
2829
#[must_use = "futures do nothing unless you `.await` or poll them"]
2930
#[stable(feature = "futures_api", since = "1.36.0")]
3031
#[lang = "future_trait"]

library/core/src/option.rs

+1
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ use crate::pin::Pin;
563563
use crate::{cmp, convert, hint, mem, slice};
564564

565565
/// The `Option` type. See [the module level documentation](self) for more.
566+
#[cfg_attr(not(bootstrap), doc(search_unbox))]
566567
#[derive(Copy, Eq, Debug, Hash)]
567568
#[rustc_diagnostic_item = "Option"]
568569
#[lang = "Option"]

library/core/src/result.rs

+1
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ use crate::{convert, fmt, hint};
520520
/// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
521521
///
522522
/// See the [module documentation](self) for details.
523+
#[cfg_attr(not(bootstrap), doc(search_unbox))]
523524
#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
524525
#[must_use = "this `Result` may be an `Err` variant, which should be handled"]
525526
#[rustc_diagnostic_item = "Result"]

src/doc/rustdoc/src/read-documentation/search.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -130,29 +130,31 @@ pub trait MyTrait {
130130
/// This function can be found using the following search queries:
131131
///
132132
/// MyTrait<First=u8, Second=u32> -> bool
133-
/// MyTrait<u32, First=u8> -> bool
134133
/// MyTrait<Second=u32> -> bool
135-
/// MyTrait<u32, u8> -> bool
136134
///
137135
/// The following queries, however, will *not* match it:
138136
///
139137
/// MyTrait<First=u32> -> bool
140138
/// MyTrait<u32, u32> -> bool
139+
/// MyTrait<u32, First=u8> -> bool
140+
/// MyTrait<u32, u8> -> bool
141141
pub fn my_fn(x: impl MyTrait<First=u8, Second=u32>) -> bool { true }
142142
```
143143

144-
Generics and function parameters are order-agnostic, but sensitive to nesting
144+
Function parameters are order-agnostic, but sensitive to nesting
145145
and number of matches. For example, a function with the signature
146146
`fn read_all(&mut self: impl Read) -> Result<Vec<u8>, Error>`
147147
will match these queries:
148148

149149
* `&mut Read -> Result<Vec<u8>, Error>`
150150
* `Read -> Result<Vec<u8>, Error>`
151-
* `Read -> Result<Error, Vec>`
152151
* `Read -> Result<Vec<u8>>`
153152
* `Read -> u8`
154153

155-
But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`.
154+
But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`,
155+
because those are nested incorrectly, and it does not match
156+
`Result<Error, Vec<u8>>` or `Result<Error>`, because those are
157+
in the wrong order.
156158

157159
To search for a function that accepts a function as a parameter,
158160
like `Iterator::all`, wrap the nested signature in parenthesis,

src/librustdoc/html/render/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ pub(crate) struct IndexItemFunctionType {
204204
inputs: Vec<RenderType>,
205205
output: Vec<RenderType>,
206206
where_clause: Vec<Vec<RenderType>>,
207+
param_names: Vec<Symbol>,
207208
}
208209

209210
impl IndexItemFunctionType {

0 commit comments

Comments
 (0)