mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 19:58:32 +00:00
Only show notable traits if both types are the same
Checking only their DefId doesn't work because all slices have the same fake DefId. Fixes #91347
This commit is contained in:
parent
6db0a0e9a4
commit
85ba6c7b34
@ -1468,6 +1468,45 @@ crate enum Type {
|
|||||||
rustc_data_structures::static_assert_size!(Type, 72);
|
rustc_data_structures::static_assert_size!(Type, 72);
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
|
/// When comparing types for equality, it can help to ignore `&` wrapping.
|
||||||
|
crate fn without_borrowed_ref(&self) -> &Type {
|
||||||
|
let mut result = self;
|
||||||
|
while let Type::BorrowedRef { type_, .. } = result {
|
||||||
|
result = &*type_;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if two types are "potentially the same."
|
||||||
|
/// This is different from Eq, because it knows that things like
|
||||||
|
/// `Placeholder` are possible matches for everything.
|
||||||
|
crate fn is_same(&self, other: &Self, cache: &Cache) -> bool {
|
||||||
|
match (self, other) {
|
||||||
|
// Recursive cases.
|
||||||
|
(Type::Tuple(a), Type::Tuple(b)) => {
|
||||||
|
a.len() == b.len() && a.iter().zip(b).all(|(a, b)| a.is_same(&b, cache))
|
||||||
|
}
|
||||||
|
(Type::Slice(a), Type::Slice(b)) => a.is_same(&b, cache),
|
||||||
|
(Type::Array(a, al), Type::Array(b, bl)) => al == bl && a.is_same(&b, cache),
|
||||||
|
(Type::RawPointer(mutability, type_), Type::RawPointer(b_mutability, b_type_)) => {
|
||||||
|
mutability == b_mutability && type_.is_same(&b_type_, cache)
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Type::BorrowedRef { mutability, type_, .. },
|
||||||
|
Type::BorrowedRef { mutability: b_mutability, type_: b_type_, .. },
|
||||||
|
) => mutability == b_mutability && type_.is_same(&b_type_, cache),
|
||||||
|
// Placeholders and generics are equal to all other types.
|
||||||
|
(Type::Infer, _) | (_, Type::Infer) => true,
|
||||||
|
(Type::Generic(_), _) | (_, Type::Generic(_)) => true,
|
||||||
|
// Other cases, such as primitives, just use recursion.
|
||||||
|
(a, b) => a
|
||||||
|
.def_id(cache)
|
||||||
|
.and_then(|a| Some((a, b.def_id(cache)?)))
|
||||||
|
.map(|(a, b)| a == b)
|
||||||
|
.unwrap_or(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crate fn primitive_type(&self) -> Option<PrimitiveType> {
|
crate fn primitive_type(&self) -> Option<PrimitiveType> {
|
||||||
match *self {
|
match *self {
|
||||||
Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
|
Primitive(p) | BorrowedRef { type_: box Primitive(p), .. } => Some(p),
|
||||||
|
@ -1235,10 +1235,17 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
|
|||||||
fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
|
fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
|
||||||
let mut out = Buffer::html();
|
let mut out = Buffer::html();
|
||||||
|
|
||||||
if let Some(did) = decl.output.as_return().and_then(|t| t.def_id(cx.cache())) {
|
if let Some((did, ty)) = decl.output.as_return().and_then(|t| Some((t.def_id(cx.cache())?, t)))
|
||||||
|
{
|
||||||
if let Some(impls) = cx.cache().impls.get(&did) {
|
if let Some(impls) = cx.cache().impls.get(&did) {
|
||||||
for i in impls {
|
for i in impls {
|
||||||
let impl_ = i.inner_impl();
|
let impl_ = i.inner_impl();
|
||||||
|
if !impl_.for_.without_borrowed_ref().is_same(ty.without_borrowed_ref(), cx.cache())
|
||||||
|
{
|
||||||
|
// Two different types might have the same did,
|
||||||
|
// without actually being the same.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if let Some(trait_) = &impl_.trait_ {
|
if let Some(trait_) = &impl_.trait_ {
|
||||||
let trait_did = trait_.def_id();
|
let trait_did = trait_.def_id();
|
||||||
|
|
||||||
|
20
src/test/rustdoc/doc-notable_trait-slice.rs
Normal file
20
src/test/rustdoc/doc-notable_trait-slice.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#![feature(doc_notable_trait)]
|
||||||
|
|
||||||
|
#[doc(notable_trait)]
|
||||||
|
pub trait SomeTrait {}
|
||||||
|
|
||||||
|
pub struct SomeStruct;
|
||||||
|
pub struct OtherStruct;
|
||||||
|
impl SomeTrait for &[SomeStruct] {}
|
||||||
|
|
||||||
|
// @has doc_notable_trait_slice/fn.bare_fn_matches.html
|
||||||
|
// @has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
|
||||||
|
pub fn bare_fn_matches() -> &'static [SomeStruct] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// @has doc_notable_trait_slice/fn.bare_fn_no_matches.html
|
||||||
|
// @!has - '//code[@class="content"]' 'impl SomeTrait for &[SomeStruct]'
|
||||||
|
pub fn bare_fn_no_matches() -> &'static [OtherStruct] {
|
||||||
|
&[]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user