Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_hir::{ConstStability, StabilityLevel, StableSince};
use rustc_metadata::creader::CStore;
use rustc_middle::ty::{self, Ty, TyCtxt, TypingMode};
use rustc_span::symbol::kw;
use rustc_span::{Ident, Symbol};
use rustc_span::{Ident, Symbol, sym};
use tracing::{debug, trace};

use super::url_parts_builder::UrlPartsBuilder;
Expand Down Expand Up @@ -537,11 +537,25 @@ fn generate_item_def_id_path(
&& !def_id.is_local()
&& def_id.krate != original_def_id.krate;
} else {
// This hack is because primitive types are only documented in `core` and `std`.
// However, with `#[rustc_allow_incoherent_impl]`, a lot of primitive methods are
// implemented in `core`. Some of them are documented in `core` (like `[]::sort`) while
// others aren't (like `[]::to_vec`). So in case we're not documenting `core`, we link
// to `std`.
if !of_trait && crate_name != sym::core {
Comment thread
GuillaumeGomez marked this conversation as resolved.
if ![sym::alloc, sym::std].contains(&crate_name) {
// We cannot link to this primitive's associated item as it's not part of
// `core`, `alloc` or `std` so returning early.
return Err(HrefError::UnnamableItem);
}
maybe_have_impl_not_in_def_crate = true;
}
prim = PrimitiveType::from_ty(ty);
}
}

let (shortty, fqp) = if let Some(prim) = prim {
let crate_name = if maybe_have_impl_not_in_def_crate { sym::std } else { crate_name };
Comment thread
Urgau marked this conversation as resolved.
(ItemType::Primitive, vec![crate_name, prim.as_sym()])
} else {
(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(rustc_attrs)]
#![allow(internal_features)]

impl<T> [T] {
#[rustc_allow_incoherent_impl]
pub fn f(&self) {}
}
25 changes: 25 additions & 0 deletions tests/rustdoc-html/jump-to-def/incoherent_impl-primitive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This test checks that outside of `core`/`alloc`/`std`, we don't link to incoherent method impl
// because there is no page to link to since primitive are only documented in `core` and `std`.

//@ aux-build: incoherent_impl_primitive.rs
//@ build-aux-docs
//@ compile-flags: -Zunstable-options --generate-link-to-definition

#![crate_name = "foo"]

extern crate incoherent_impl_primitive;

//@ has 'src/foo/incoherent_impl-primitive.rs.html'

// It should contain only the link to "first". Sadly, because of the limit, we cannot test
// if a link doesn't have an attribute so for now, we simply ensure that the number of `<a>`
// (including both line numbers and jump to def links) is superior by one to the number of
// line `<a>`. If so, we know there is only one jump to def link.
//@ count - '//pre/code/a' 7
//@ count - '//pre/code/a[@id]' 6
//@ has - '//pre/code/a[@href="{{channel}}/core/primitive.slice.html#method.first"]' 'first'

fn foo() {
let x = ["a"].f();
["a"].first();
}
Loading