1
Fork 0

rustdoc-search: simplify rules for generics and type params

This commit is a response to feedback on the displayed type
signatures results, by making generics act stricter.

Generics are tightened by making order 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.

Find the discussion on:

* <https://rust-lang.zulipchat.com/#narrow/stream/393423-t-rustdoc.2Fmeetings/topic/meeting.202024-07-08/near/449965149>
* <https://github.com/rust-lang/rust/pull/124544#issuecomment-2204272265>
* <https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/deciding.20on.20semantics.20of.20generics.20in.20rustdoc.20search/near/476841363>
This commit is contained in:
Michael Howell 2024-09-24 18:18:01 -07:00
parent 20a4b4fea1
commit 12dc24f460
40 changed files with 630 additions and 217 deletions

View file

@ -16,8 +16,8 @@ use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, B
use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{
self as hir, self, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId, Item, ItemKind,
MethodKind, Safety, Target, TraitItem,
self as hir, self, AssocItemKind, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId,
Item, ItemKind, MethodKind, Safety, Target, TraitItem,
};
use rustc_macros::LintDiagnostic;
use rustc_middle::hir::nested_filter;
@ -940,6 +940,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
fn check_doc_search_unbox(&self, meta: &MetaItemInner, hir_id: HirId) {
let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else {
self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
return;
};
match item.kind {
ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics)
if generics.params.len() != 0 => {}
ItemKind::Trait(_, _, generics, _, items)
if generics.params.len() != 0
|| items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
_ => {
self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
}
}
}
/// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes.
///
/// A doc inlining attribute is invalid if it is applied to a non-`use` item, or
@ -1152,6 +1169,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
sym::search_unbox => {
if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
self.check_doc_search_unbox(meta, hir_id);
}
}
sym::test => {
if self.check_attr_crate_level(attr, meta, hir_id) {
self.check_test_attr(meta, hir_id);

View file

@ -244,6 +244,13 @@ pub(crate) struct DocKeywordOnlyImpl {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_doc_search_unbox_invalid)]
pub(crate) struct DocSearchUnboxInvalid {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_doc_inline_conflict)]
#[help]