Rollup merge of #109443 - GuillaumeGomez:doc-primitive-hard-error, r=notriddle

Move `doc(primitive)` future incompat warning to `invalid_doc_attributes`

Fixes #88070.

It's been a while since this was turned into a "future incompatible lint" so I think we can now turn it into a hard error without problem.

r? `@jyn514`
This commit is contained in:
Guillaume Gomez 2023-03-31 22:32:49 +02:00 committed by GitHub
commit 6c93c63771
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 217 additions and 165 deletions

View File

@ -225,7 +225,7 @@ declare_features! (
(active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None),
/// Allows using compiler's own crates.
(active, rustc_private, "1.0.0", Some(27812), None),
/// Allows using internal rustdoc features like `doc(primitive)` or `doc(keyword)`.
/// Allows using internal rustdoc features like `doc(keyword)`.
(active, rustdoc_internals, "1.58.0", Some(90418), None),
/// Allows using the `rustdoc::missing_doc_code_examples` lint
(active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None),

View File

@ -778,6 +778,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
definition of a trait, it's currently in experimental form and should be changed before \
being exposed outside of the std"
),
rustc_attr!(
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
r#"`rustc_doc_primitive` is a rustc internal attribute"#,
),
// ==========================================================================
// Internal attributes, Testing:

View File

@ -148,9 +148,6 @@ passes_doc_test_unknown =
passes_doc_test_takes_list =
`#[doc(test(...)]` takes a list of attributes
passes_doc_primitive =
`doc(primitive)` should never have been stable
passes_doc_cfg_hide_takes_list =
`#[doc(cfg_hide(...)]` takes a list of attributes

View File

@ -1109,17 +1109,6 @@ impl CheckAttrVisitor<'_> {
}
}
sym::primitive => {
if !self.tcx.features().rustdoc_internals {
self.tcx.emit_spanned_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
i_meta.span,
errors::DocPrimitive,
);
}
}
_ => {
let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path);
if i_meta.has_name(sym::spotlight) {

View File

@ -288,10 +288,6 @@ pub struct DocTestTakesList;
#[diag(passes_doc_cfg_hide_takes_list)]
pub struct DocCfgHideTakesList;
#[derive(LintDiagnostic)]
#[diag(passes_doc_primitive)]
pub struct DocPrimitive;
#[derive(LintDiagnostic)]
#[diag(passes_doc_test_unknown_any)]
pub struct DocTestUnknownAny {

View File

@ -339,12 +339,14 @@ pub fn inner_docs(attrs: &[ast::Attribute]) -> bool {
attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner)
}
/// Has `#[doc(primitive)]` or `#[doc(keyword)]`.
/// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`.
pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool {
for attr in attrs {
if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() {
if attr.has_name(sym::rustc_doc_primitive) {
return true;
} else if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() {
for item in items {
if item.has_name(sym::primitive) || item.has_name(sym::keyword) {
if item.has_name(sym::keyword) {
return true;
}
}

View File

@ -1246,6 +1246,7 @@ symbols! {
rustc_diagnostic_macros,
rustc_dirty,
rustc_do_not_const_check,
rustc_doc_primitive,
rustc_dummy,
rustc_dump_env_program_clauses,
rustc_dump_program_clauses,

View File

@ -1,7 +1,8 @@
// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
// These are different files so that relative links work properly without
// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
#[doc(primitive = "bool")]
#[cfg_attr(bootstrap, doc(primitive = "bool"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "bool")]
#[doc(alias = "true")]
#[doc(alias = "false")]
/// The boolean type.
@ -63,7 +64,8 @@
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_bool {}
#[doc(primitive = "never")]
#[cfg_attr(bootstrap, doc(primitive = "never"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "never")]
#[doc(alias = "!")]
//
/// The `!` type, also called "never".
@ -274,7 +276,8 @@ mod prim_bool {}
#[unstable(feature = "never_type", issue = "35121")]
mod prim_never {}
#[doc(primitive = "char")]
#[cfg_attr(bootstrap, doc(primitive = "char"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "char")]
#[allow(rustdoc::invalid_rust_codeblocks)]
/// A character type.
///
@ -398,7 +401,8 @@ mod prim_never {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_char {}
#[doc(primitive = "unit")]
#[cfg_attr(bootstrap, doc(primitive = "unit"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "unit")]
#[doc(alias = "(")]
#[doc(alias = ")")]
#[doc(alias = "()")]
@ -460,7 +464,8 @@ impl Copy for () {
// empty
}
#[doc(primitive = "pointer")]
#[cfg_attr(bootstrap, doc(primitive = "pointer"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "pointer")]
#[doc(alias = "ptr")]
#[doc(alias = "*")]
#[doc(alias = "*const")]
@ -577,7 +582,8 @@ impl Copy for () {
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_pointer {}
#[doc(primitive = "array")]
#[cfg_attr(bootstrap, doc(primitive = "array"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "array")]
#[doc(alias = "[]")]
#[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases
#[doc(alias = "[T; N]")]
@ -778,7 +784,8 @@ mod prim_pointer {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_array {}
#[doc(primitive = "slice")]
#[cfg_attr(bootstrap, doc(primitive = "slice"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "slice")]
#[doc(alias = "[")]
#[doc(alias = "]")]
#[doc(alias = "[]")]
@ -870,7 +877,8 @@ mod prim_array {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_slice {}
#[doc(primitive = "str")]
#[cfg_attr(bootstrap, doc(primitive = "str"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "str")]
/// String slices.
///
/// *[See also the `std::str` module](crate::str).*
@ -937,7 +945,8 @@ mod prim_slice {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_str {}
#[doc(primitive = "tuple")]
#[cfg_attr(bootstrap, doc(primitive = "tuple"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "tuple")]
#[doc(alias = "(")]
#[doc(alias = ")")]
#[doc(alias = "()")]
@ -1081,7 +1090,8 @@ impl<T: Copy> Copy for (T,) {
// empty
}
#[doc(primitive = "f32")]
#[cfg_attr(bootstrap, doc(primitive = "f32"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f32")]
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
///
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
@ -1147,7 +1157,8 @@ impl<T: Copy> Copy for (T,) {
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_f32 {}
#[doc(primitive = "f64")]
#[cfg_attr(bootstrap, doc(primitive = "f64"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f64")]
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
///
/// This type is very similar to [`f32`], but has increased
@ -1162,67 +1173,78 @@ mod prim_f32 {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_f64 {}
#[doc(primitive = "i8")]
#[cfg_attr(bootstrap, doc(primitive = "i8"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i8")]
//
/// The 8-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i8 {}
#[doc(primitive = "i16")]
#[cfg_attr(bootstrap, doc(primitive = "i16"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i16")]
//
/// The 16-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i16 {}
#[doc(primitive = "i32")]
#[cfg_attr(bootstrap, doc(primitive = "i32"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i32")]
//
/// The 32-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i32 {}
#[doc(primitive = "i64")]
#[cfg_attr(bootstrap, doc(primitive = "i64"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i64")]
//
/// The 64-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i64 {}
#[doc(primitive = "i128")]
#[cfg_attr(bootstrap, doc(primitive = "i128"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i128")]
//
/// The 128-bit signed integer type.
#[stable(feature = "i128", since = "1.26.0")]
mod prim_i128 {}
#[doc(primitive = "u8")]
#[cfg_attr(bootstrap, doc(primitive = "u8"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u8")]
//
/// The 8-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u8 {}
#[doc(primitive = "u16")]
#[cfg_attr(bootstrap, doc(primitive = "u16"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u16")]
//
/// The 16-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u16 {}
#[doc(primitive = "u32")]
#[cfg_attr(bootstrap, doc(primitive = "u32"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u32")]
//
/// The 32-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u32 {}
#[doc(primitive = "u64")]
#[cfg_attr(bootstrap, doc(primitive = "u64"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u64")]
//
/// The 64-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u64 {}
#[doc(primitive = "u128")]
#[cfg_attr(bootstrap, doc(primitive = "u128"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u128")]
//
/// The 128-bit unsigned integer type.
#[stable(feature = "i128", since = "1.26.0")]
mod prim_u128 {}
#[doc(primitive = "isize")]
#[cfg_attr(bootstrap, doc(primitive = "isize"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "isize")]
//
/// The pointer-sized signed integer type.
///
@ -1232,7 +1254,8 @@ mod prim_u128 {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_isize {}
#[doc(primitive = "usize")]
#[cfg_attr(bootstrap, doc(primitive = "usize"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "usize")]
//
/// The pointer-sized unsigned integer type.
///
@ -1242,7 +1265,8 @@ mod prim_isize {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_usize {}
#[doc(primitive = "reference")]
#[cfg_attr(bootstrap, doc(primitive = "reference"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "reference")]
#[doc(alias = "&")]
#[doc(alias = "&mut")]
//
@ -1373,7 +1397,8 @@ mod prim_usize {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_ref {}
#[doc(primitive = "fn")]
#[cfg_attr(bootstrap, doc(primitive = "fn"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "fn")]
//
/// Function pointers, like `fn(usize) -> bool`.
///

View File

@ -1,7 +1,8 @@
// `library/{std,core}/src/primitive_docs.rs` should have the same contents.
// These are different files so that relative links work properly without
// having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same.
#[doc(primitive = "bool")]
#[cfg_attr(bootstrap, doc(primitive = "bool"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "bool")]
#[doc(alias = "true")]
#[doc(alias = "false")]
/// The boolean type.
@ -63,7 +64,8 @@
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_bool {}
#[doc(primitive = "never")]
#[cfg_attr(bootstrap, doc(primitive = "never"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "never")]
#[doc(alias = "!")]
//
/// The `!` type, also called "never".
@ -274,7 +276,8 @@ mod prim_bool {}
#[unstable(feature = "never_type", issue = "35121")]
mod prim_never {}
#[doc(primitive = "char")]
#[cfg_attr(bootstrap, doc(primitive = "char"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "char")]
#[allow(rustdoc::invalid_rust_codeblocks)]
/// A character type.
///
@ -398,7 +401,8 @@ mod prim_never {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_char {}
#[doc(primitive = "unit")]
#[cfg_attr(bootstrap, doc(primitive = "unit"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "unit")]
#[doc(alias = "(")]
#[doc(alias = ")")]
#[doc(alias = "()")]
@ -460,7 +464,8 @@ impl Copy for () {
// empty
}
#[doc(primitive = "pointer")]
#[cfg_attr(bootstrap, doc(primitive = "pointer"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "pointer")]
#[doc(alias = "ptr")]
#[doc(alias = "*")]
#[doc(alias = "*const")]
@ -577,7 +582,8 @@ impl Copy for () {
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_pointer {}
#[doc(primitive = "array")]
#[cfg_attr(bootstrap, doc(primitive = "array"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "array")]
#[doc(alias = "[]")]
#[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases
#[doc(alias = "[T; N]")]
@ -778,7 +784,8 @@ mod prim_pointer {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_array {}
#[doc(primitive = "slice")]
#[cfg_attr(bootstrap, doc(primitive = "slice"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "slice")]
#[doc(alias = "[")]
#[doc(alias = "]")]
#[doc(alias = "[]")]
@ -870,7 +877,8 @@ mod prim_array {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_slice {}
#[doc(primitive = "str")]
#[cfg_attr(bootstrap, doc(primitive = "str"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "str")]
/// String slices.
///
/// *[See also the `std::str` module](crate::str).*
@ -937,7 +945,8 @@ mod prim_slice {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_str {}
#[doc(primitive = "tuple")]
#[cfg_attr(bootstrap, doc(primitive = "tuple"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "tuple")]
#[doc(alias = "(")]
#[doc(alias = ")")]
#[doc(alias = "()")]
@ -1081,7 +1090,8 @@ impl<T: Copy> Copy for (T,) {
// empty
}
#[doc(primitive = "f32")]
#[cfg_attr(bootstrap, doc(primitive = "f32"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f32")]
/// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008).
///
/// This type can represent a wide range of decimal numbers, like `3.5`, `27`,
@ -1147,7 +1157,8 @@ impl<T: Copy> Copy for (T,) {
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_f32 {}
#[doc(primitive = "f64")]
#[cfg_attr(bootstrap, doc(primitive = "f64"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f64")]
/// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008).
///
/// This type is very similar to [`f32`], but has increased
@ -1162,67 +1173,78 @@ mod prim_f32 {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_f64 {}
#[doc(primitive = "i8")]
#[cfg_attr(bootstrap, doc(primitive = "i8"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i8")]
//
/// The 8-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i8 {}
#[doc(primitive = "i16")]
#[cfg_attr(bootstrap, doc(primitive = "i16"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i16")]
//
/// The 16-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i16 {}
#[doc(primitive = "i32")]
#[cfg_attr(bootstrap, doc(primitive = "i32"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i32")]
//
/// The 32-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i32 {}
#[doc(primitive = "i64")]
#[cfg_attr(bootstrap, doc(primitive = "i64"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i64")]
//
/// The 64-bit signed integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_i64 {}
#[doc(primitive = "i128")]
#[cfg_attr(bootstrap, doc(primitive = "i128"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i128")]
//
/// The 128-bit signed integer type.
#[stable(feature = "i128", since = "1.26.0")]
mod prim_i128 {}
#[doc(primitive = "u8")]
#[cfg_attr(bootstrap, doc(primitive = "u8"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u8")]
//
/// The 8-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u8 {}
#[doc(primitive = "u16")]
#[cfg_attr(bootstrap, doc(primitive = "u16"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u16")]
//
/// The 16-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u16 {}
#[doc(primitive = "u32")]
#[cfg_attr(bootstrap, doc(primitive = "u32"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u32")]
//
/// The 32-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u32 {}
#[doc(primitive = "u64")]
#[cfg_attr(bootstrap, doc(primitive = "u64"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u64")]
//
/// The 64-bit unsigned integer type.
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_u64 {}
#[doc(primitive = "u128")]
#[cfg_attr(bootstrap, doc(primitive = "u128"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u128")]
//
/// The 128-bit unsigned integer type.
#[stable(feature = "i128", since = "1.26.0")]
mod prim_u128 {}
#[doc(primitive = "isize")]
#[cfg_attr(bootstrap, doc(primitive = "isize"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "isize")]
//
/// The pointer-sized signed integer type.
///
@ -1232,7 +1254,8 @@ mod prim_u128 {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_isize {}
#[doc(primitive = "usize")]
#[cfg_attr(bootstrap, doc(primitive = "usize"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "usize")]
//
/// The pointer-sized unsigned integer type.
///
@ -1242,7 +1265,8 @@ mod prim_isize {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_usize {}
#[doc(primitive = "reference")]
#[cfg_attr(bootstrap, doc(primitive = "reference"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "reference")]
#[doc(alias = "&")]
#[doc(alias = "&mut")]
//
@ -1373,7 +1397,8 @@ mod prim_usize {}
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_ref {}
#[doc(primitive = "fn")]
#[cfg_attr(bootstrap, doc(primitive = "fn"))]
#[cfg_attr(not(bootstrap), rustc_doc_primitive = "fn")]
//
/// Function pointers, like `fn(usize) -> bool`.
///

View File

@ -177,9 +177,9 @@ Book][unstable-masked] and [its tracking issue][issue-masked].
This is for Rust compiler internal use only.
Since primitive types are defined in the compiler, there's no place to attach documentation
attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way
to generate documentation for primitive types, and requires `#![feature(rustdoc_internals)]` to
enable.
attributes. The `#[rustc_doc_primitive = "..."]` attribute is used by the standard library to
provide a way to generate documentation for primitive types, and requires `#![feature(rustc_attrs)]`
to enable.
### Document keywords

View File

@ -249,38 +249,24 @@ impl ExternalCrate {
//
// Note that this loop only searches the top-level items of the crate,
// and this is intentional. If we were to search the entire crate for an
// item tagged with `#[doc(primitive)]` then we would also have to
// item tagged with `#[rustc_doc_primitive]` then we would also have to
// search the entirety of external modules for items tagged
// `#[doc(primitive)]`, which is a pretty inefficient process (decoding
// `#[rustc_doc_primitive]`, which is a pretty inefficient process (decoding
// all that metadata unconditionally).
//
// In order to keep the metadata load under control, the
// `#[doc(primitive)]` feature is explicitly designed to only allow the
// `#[rustc_doc_primitive]` feature is explicitly designed to only allow the
// primitive tags to show up as the top level items in a crate.
//
// Also note that this does not attempt to deal with modules tagged
// duplicately for the same primitive. This is handled later on when
// rendering by delegating everything to a hash map.
let as_primitive = |res: Res<!>| {
if let Res::Def(DefKind::Mod, def_id) = res {
let mut prim = None;
let meta_items = tcx
.get_attrs(def_id, sym::doc)
.flat_map(|attr| attr.meta_item_list().unwrap_or_default());
for meta in meta_items {
if let Some(v) = meta.value_str() {
if meta.has_name(sym::primitive) {
prim = PrimitiveType::from_symbol(v);
if prim.is_some() {
break;
}
// FIXME: should warn on unknown primitives?
}
}
}
return prim.map(|p| (def_id, p));
}
None
let Res::Def(DefKind::Mod, def_id) = res else { return None };
tcx.get_attrs(def_id, sym::rustc_doc_primitive).find_map(|attr| {
// FIXME: should warn on unknown primitives?
Some((def_id, PrimitiveType::from_symbol(attr.value_str()?)?))
})
};
if root.is_local() {
@ -1829,13 +1815,17 @@ impl PrimitiveType {
}
}
/// Returns the DefId of the module with `doc(primitive)` for this primitive type.
/// Returns the DefId of the module with `rustc_doc_primitive` for this primitive type.
/// Panics if there is no such module.
///
/// This gives precedence to primitives defined in the current crate, and deprioritizes primitives defined in `core`,
/// but otherwise, if multiple crates define the same primitive, there is no guarantee of which will be picked.
/// In particular, if a crate depends on both `std` and another crate that also defines `doc(primitive)`, then
/// it's entirely random whether `std` or the other crate is picked. (no_std crates are usually fine unless multiple dependencies define a primitive.)
/// This gives precedence to primitives defined in the current crate, and deprioritizes
/// primitives defined in `core`,
/// but otherwise, if multiple crates define the same primitive, there is no guarantee of which
/// will be picked.
///
/// In particular, if a crate depends on both `std` and another crate that also defines
/// `rustc_doc_primitive`, then it's entirely random whether `std` or the other crate is picked.
/// (no_std crates are usually fine unless multiple dependencies define a primitive.)
pub(crate) fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap<PrimitiveType, DefId> {
static PRIMITIVE_LOCATIONS: OnceCell<FxHashMap<PrimitiveType, DefId>> = OnceCell::new();
PRIMITIVE_LOCATIONS.get_or_init(|| {

View File

@ -249,9 +249,7 @@ pub(crate) fn id_from_item_inner(
// instead, we directly get the primitive symbol and convert it to u32 to
// generate the ID.
if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
let Some(prim) = tcx.get_attrs(*def_id, sym::doc)
.flat_map(|attr| attr.meta_item_list().unwrap_or_default())
.filter(|attr| attr.has_name(sym::primitive))
let Some(prim) = tcx.get_attrs(*def_id, sym::rustc_doc_primitive)
.find_map(|attr| attr.value_str()) {
format!(":{}", prim.as_u32())
} else {

View File

@ -78,7 +78,7 @@ impl<'tcx> JsonRenderer<'tcx> {
// HACK(hkmatsumoto): For impls of primitive types, we index them
// regardless of whether they're local. This is because users can
// document primitive items in an arbitrary crate by using
// `doc(primitive)`.
// `rustc_doc_primitive`.
let mut is_primitive_impl = false;
if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind &&
impl_.trait_.is_none() &&

View File

@ -453,8 +453,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
})?;
// FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support
// links to primitives when `#[doc(primitive)]` is present. It should give an ambiguity
// error instead and special case *only* modules with `#[doc(primitive)]`, not all
// links to primitives when `#[rustc_doc_primitive]` is present. It should give an ambiguity
// error instead and special case *only* modules with `#[rustc_doc_primitive]`, not all
// primitives.
match resolve_primitive(&path_root, TypeNS)
.or_else(|| self.resolve_path(&path_root, TypeNS, item_id, module_id))
@ -1144,7 +1144,7 @@ impl LinkCollector<'_, '_> {
}
}
// item can be non-local e.g. when using #[doc(primitive = "pointer")]
// item can be non-local e.g. when using `#[rustc_doc_primitive = "pointer"]`
if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| {
item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
}) {

View File

@ -1,5 +1,5 @@
#![feature(no_core)]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#![no_core]
// @set Local = "$.index[*][?(@.name=='Local')].id"
@ -16,6 +16,6 @@ impl Local for bool {}
// FIXME(#101695): Test bool's `impls` include "Local for bool"
// @has "$.index[*][?(@.name=='bool')]"
#[doc(primitive = "bool")]
#[rustc_doc_primitive = "bool"]
/// Boolean docs
mod prim_bool {}

View File

@ -8,7 +8,7 @@
//! Link to [i32][prim@i32] [i64][prim@i64]
#[doc(primitive = "i32")]
#[rustc_doc_primitive = "i32"]
mod prim_i32 {}
// @set local_i32 = "$.index[*][?(@.name=='i32')].id"

View File

@ -25,7 +25,7 @@ pub trait Trait {}
impl Trait for i32 {}
/// i32
#[doc(primitive = "i32")]
#[rustc_doc_primitive = "i32"]
mod prim_i32 {}
// @set i32 = "$.index[*][?(@.docs=='i32')].id"

View File

@ -2,7 +2,7 @@
// Regression test for <https://github.com/rust-lang/rust/issues/98006>.
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#![feature(no_core)]
#![no_core]
@ -10,7 +10,7 @@
// @has "$.index[*][?(@.name=='usize')]"
// @has "$.index[*][?(@.name=='prim')]"
#[doc(primitive = "usize")]
#[rustc_doc_primitive = "usize"]
/// This is the built-in type `usize`.
mod prim {
}

View File

@ -1,8 +1,8 @@
// edition:2018
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#[doc(primitive = "usize")]
#[rustc_doc_primitive = "usize"]
mod usize {}
// @set local_crate_id = "$.index[*][?(@.name=='use_primitive')].crate_id"

View File

@ -2,12 +2,13 @@
// check-pass
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
//! the features only used in std also have entries in the table, so make sure those get pulled out
//! properly as well
/// woo, check it out, we can write our own primitive docs lol
#[doc(primitive="unit")]
#[rustc_doc_primitive = "unit"]
mod prim_unit {}
/// keywords? sure, pile them on

View File

@ -1,10 +1,10 @@
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#![crate_name = "foo"]
pub use std::fs::File;
// @has 'foo/primitive.i16.html' '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementation'
#[doc(primitive = "i16")]
#[rustc_doc_primitive = "i16"]
/// I love poneys!
mod prim {}

View File

@ -2,6 +2,7 @@
// compile-flags: -Cmetadata=aux
#![crate_type = "rlib"]
#![doc(html_root_url = "http://example.com/")]
#![feature(rustc_attrs)]
#![feature(lang_items)]
#![no_std]
@ -12,5 +13,5 @@ fn foo() {}
fn bar(_: &core::panic::PanicInfo) -> ! { loop {} }
/// dox
#[doc(primitive = "pointer")]
#[rustc_doc_primitive = "pointer"]
pub mod ptr {}

View File

@ -1,9 +1,10 @@
// compile-flags: --crate-type lib --edition 2018
#![feature(rustc_attrs)]
#![feature(no_core)]
#![no_core]
#[doc(primitive = "usize")]
#[rustc_doc_primitive = "usize"]
/// This is the built-in type `usize`.
mod usize {
}

View File

@ -2,7 +2,7 @@
// aux-build:source_code.rs
// build-aux-docs
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#![crate_name = "foo"]
@ -65,5 +65,5 @@ pub fn foo4() {
}
// @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool'
#[doc(primitive = "bool")]
#[rustc_doc_primitive = "bool"]
mod whatever {}

View File

@ -3,7 +3,7 @@
#![rustc_coherence_is_core]
#![crate_type="rlib"]
#[doc(primitive = "char")]
#[rustc_doc_primitive = "char"]
/// Some char docs
mod char {}

View File

@ -1,4 +1,4 @@
// Crate tree without a `doc(primitive)` module for primitive type linked to by a doc link.
// Crate tree without a `rustc_doc_primitive` module for primitive type linked to by a doc link.
#![deny(rustdoc::broken_intra_doc_links)]
#![feature(no_core, lang_items, rustc_attrs)]

View File

@ -10,7 +10,7 @@
//! A [prim@`char`] and its [`char::len_utf8`].
#[doc(primitive = "char")]
#[rustc_doc_primitive = "char"]
mod char {}
impl char {

View File

@ -25,7 +25,7 @@ impl usize {
pub type ME = usize;
}
#[doc(primitive = "usize")]
#[rustc_doc_primitive = "usize"]
/// This has some docs.
mod usize {}

View File

@ -1,7 +1,7 @@
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @has issue_15318_3/primitive.pointer.html
/// dox
#[doc(primitive = "pointer")]
#[rustc_doc_primitive = "pointer"]
pub mod ptr {}

View File

@ -3,7 +3,7 @@
#![no_std]
pub mod str {
#![doc(primitive = "str")]
#![rustc_doc_primitive = "str"]
impl str {
// @hasraw search-index.js foo

View File

@ -6,10 +6,10 @@
//!
//! [#80737]: https://github.com/rust-lang/rust/issues/80737
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#![no_std]
#[doc(primitive = "reference")]
#[rustc_doc_primitive = "reference"]
/// Some useless docs, wouhou!
///
/// We need to put this in here, because notable traits

View File

@ -5,9 +5,9 @@
//!
//! [#78160]: https://github.com/rust-lang/rust/issues/78160
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#[doc(primitive = "reference")]
#[rustc_doc_primitive = "reference"]
/// Some useless docs, wouhou!
///
/// We need to put this in here, because notable traits

View File

@ -1,6 +1,6 @@
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @has foo/index.html
// @has - '//h2[@id="primitives"]' 'Primitive Types'
@ -16,7 +16,7 @@
// @count - '//*[@class="impl"]' 1
// @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header"]' \
// 'impl<A, B> Foo<&A> for &B'
#[doc(primitive = "reference")]
#[rustc_doc_primitive = "reference"]
/// this is a test!
mod reference {}

View File

@ -1,7 +1,7 @@
// compile-flags: --crate-type lib --edition 2018
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @has foo/primitive.slice.html '//a[@class="primitive"]' 'slice'
// @has - '//h1' 'Primitive Type slice'
@ -9,6 +9,6 @@
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Send for [T]where T: Send'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl<T> Sync for [T]where T: Sync'
#[doc(primitive = "slice")]
#[rustc_doc_primitive = "slice"]
/// this is a test!
mod slice_prim {}

View File

@ -1,7 +1,7 @@
// compile-flags: --crate-type lib --edition 2018
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @has foo/primitive.tuple.html '//a[@class="primitive"]' 'tuple'
// @has - '//h1' 'Primitive Type tuple'
@ -9,7 +9,7 @@
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'Send'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'Sync'
#[doc(primitive = "tuple")]
#[rustc_doc_primitive = "tuple"]
/// this is a test!
///
// Hardcoded anchor to header written in library/core/src/primitive_docs.rs

View File

@ -1,7 +1,7 @@
// compile-flags: --crate-type lib --edition 2018
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @has foo/primitive.unit.html '//a[@class="primitive"]' 'unit'
// @has - '//h1' 'Primitive Type unit'
@ -9,6 +9,6 @@
// @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Send for ()'
// @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for ()'
#[doc(primitive = "unit")]
#[rustc_doc_primitive = "unit"]
/// this is a test!
mod unit_prim {}

View File

@ -1,8 +1,8 @@
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
#![crate_name = "foo"]
// @has foo/primitive.i32.html '//*[@id="impl-ToString-for-i32"]//h3[@class="code-header"]' 'impl<T> ToString for T'
#[doc(primitive = "i32")]
#[rustc_doc_primitive = "i32"]
/// Some useless docs, wouhou!
mod i32 {}

View File

@ -1,6 +1,6 @@
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @has foo/index.html '//h2[@id="primitives"]' 'Primitive Types'
// @has foo/index.html '//a[@href="primitive.i32.html"]' 'i32'
@ -11,11 +11,11 @@
// @has foo/primitive.i32.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!'
// @has foo/index.html '//a/@href' '../foo/index.html'
// @!has foo/index.html '//span' '🔒'
#[doc(primitive = "i32")]
#[rustc_doc_primitive = "i32"]
/// this is a test!
mod i32{}
// @has foo/primitive.bool.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello'
#[doc(primitive = "bool")]
#[rustc_doc_primitive = "bool"]
/// hello
mod bool {}

View File

@ -1,6 +1,6 @@
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @has 'foo/all.html'
// @has - '//*[@class="sidebar-elems"]//li' 'Structs'
@ -31,5 +31,5 @@ macro_rules! foo {
pub type Type = u8;
pub const FOO: u8 = 0;
pub static BAR: u8 = 0;
#[doc(primitive = "u8")]
#[rustc_doc_primitive = "u8"]
mod u8 {}

View File

@ -1,4 +1,5 @@
#![crate_name = "foo"]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
// tests for the html <title> element
@ -39,6 +40,6 @@ mod continue_keyword {}
// @has foo/primitive.u8.html '//head/title' 'u8 - Rust'
// @!has - '//head/title' 'foo'
#[doc(primitive = "u8")]
#[rustc_doc_primitive = "u8"]
/// `u8` docs
mod u8 {}

View File

@ -1,5 +1,5 @@
#![crate_name = "foo"]
#![feature(rustdoc_internals)]
#![feature(rustc_attrs)]
// @matches 'foo/index.html' '//h1' 'Crate foo'
// @matches 'foo/index.html' '//h2[@class="location"]' 'Crate foo'
@ -41,7 +41,7 @@ macro_rules! foo_macro {
}
// @matches 'foo/primitive.bool.html' '//h1' 'Primitive Type bool'
#[doc(primitive = "bool")]
#[rustc_doc_primitive = "bool"]
mod bool {}
// @matches 'foo/static.FOO_STATIC.html' '//h1' 'Static foo::FOO_STATIC'

View File

@ -0,0 +1,8 @@
#![deny(invalid_doc_attributes)]
#[doc(primitive = "foo")]
//~^ ERROR unknown `doc` attribute `primitive`
//~| WARN
mod bar {}
fn main() {}

View File

@ -0,0 +1,16 @@
error: unknown `doc` attribute `primitive`
--> $DIR/doc-primitive.rs:3:7
|
LL | #[doc(primitive = "foo")]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
note: the lint level is defined here
--> $DIR/doc-primitive.rs:1:9
|
LL | #![deny(invalid_doc_attributes)]
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error

View File

@ -1,7 +1,5 @@
// check-pass
#[doc(primitive = "usize")]
//~^ WARNING `doc(primitive)` should never have been stable
//~| WARNING hard error in a future release
#[rustc_doc_primitive = "usize"]
//~^ ERROR `rustc_doc_primitive` is a rustc internal attribute
/// Some docs
mod usize {}

View File

@ -1,12 +1,11 @@
warning: `doc(primitive)` should never have been stable
--> $DIR/feature-gate-doc_primitive.rs:2:7
error[E0658]: `rustc_doc_primitive` is a rustc internal attribute
--> $DIR/feature-gate-doc_primitive.rs:1:1
|
LL | #[doc(primitive = "usize")]
| ^^^^^^^^^^^^^^^^^^^
LL | #[rustc_doc_primitive = "usize"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
= note: `#[warn(invalid_doc_attributes)]` on by default
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
warning: 1 warning emitted
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.