mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
Port #[rustc_doc_primitive] to the new attribute parser
This commit is contained in:
@@ -296,6 +296,10 @@ fn is_doc_keyword_or_attribute(&self) -> bool {
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn is_rustc_doc_primitive(&self) -> bool {
|
||||
self.has_name(sym::rustc_doc_primitive)
|
||||
}
|
||||
}
|
||||
|
||||
impl Attribute {
|
||||
@@ -935,6 +939,9 @@ fn is_proc_macro_attr(&self) -> bool {
|
||||
|
||||
/// Returns `true` is this attribute contains `doc(keyword)` or `doc(attribute)`.
|
||||
fn is_doc_keyword_or_attribute(&self) -> bool;
|
||||
|
||||
/// Returns `true` if this is a `#[rustc_doc_primitive]` attribute.
|
||||
fn is_rustc_doc_primitive(&self) -> bool;
|
||||
}
|
||||
|
||||
// FIXME(fn_delegation): use function delegation instead of manually forwarding
|
||||
|
||||
@@ -1319,3 +1319,27 @@ impl<S: Stage> NoArgsAttributeParser<S> for PreludeImportParser {
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Use)]);
|
||||
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::PreludeImport;
|
||||
}
|
||||
|
||||
pub(crate) struct RustcDocPrimitiveParser;
|
||||
|
||||
impl<S: Stage> SingleAttributeParser<S> for RustcDocPrimitiveParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_doc_primitive];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Mod)]);
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
|
||||
let Some(nv) = args.name_value() else {
|
||||
cx.expected_name_value(args.span().unwrap_or(cx.attr_span), None);
|
||||
return None;
|
||||
};
|
||||
|
||||
let Some(value_str) = nv.value_as_str() else {
|
||||
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(AttributeKind::RustcDocPrimitive(cx.attr_span, value_str))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,7 @@ mod late {
|
||||
Single<RustcDefPath>,
|
||||
Single<RustcDeprecatedSafe2024Parser>,
|
||||
Single<RustcDiagnosticItemParser>,
|
||||
Single<RustcDocPrimitiveParser>,
|
||||
Single<RustcForceInlineParser>,
|
||||
Single<RustcIfThisChangedParser>,
|
||||
Single<RustcLayoutScalarValidRangeEndParser>,
|
||||
|
||||
@@ -1169,6 +1169,9 @@ pub enum AttributeKind {
|
||||
/// Represents `#[rustc_do_not_const_check]`
|
||||
RustcDoNotConstCheck,
|
||||
|
||||
/// Represents `#[rustc_doc_primitive = ...]`
|
||||
RustcDocPrimitive(Span, Symbol),
|
||||
|
||||
/// Represents `#[rustc_dummy]`.
|
||||
RustcDummy,
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ pub fn encode_cross_crate(&self) -> EncodeCrossCrate {
|
||||
RustcDeprecatedSafe2024 { .. } => Yes,
|
||||
RustcDiagnosticItem(..) => Yes,
|
||||
RustcDoNotConstCheck => Yes,
|
||||
RustcDocPrimitive(..) => Yes,
|
||||
RustcDummy => No,
|
||||
RustcDumpDefParents => No,
|
||||
RustcDumpItemBounds => No,
|
||||
|
||||
@@ -1467,6 +1467,10 @@ fn is_doc_hidden(&self) -> bool {
|
||||
fn is_doc_keyword_or_attribute(&self) -> bool {
|
||||
matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some())
|
||||
}
|
||||
|
||||
fn is_rustc_doc_primitive(&self) -> bool {
|
||||
matches!(self, Attribute::Parsed(AttributeKind::RustcDocPrimitive(..)))
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(fn_delegation): use function delegation instead of manually forwarding
|
||||
|
||||
@@ -312,6 +312,7 @@ fn check_attributes(
|
||||
| AttributeKind::RustcDeprecatedSafe2024 {..}
|
||||
| AttributeKind::RustcDiagnosticItem(..)
|
||||
| AttributeKind::RustcDoNotConstCheck
|
||||
| AttributeKind::RustcDocPrimitive(..)
|
||||
| AttributeKind::RustcDummy
|
||||
| AttributeKind::RustcDumpDefParents
|
||||
| AttributeKind::RustcDumpItemBounds
|
||||
@@ -402,7 +403,6 @@ fn check_attributes(
|
||||
// internal
|
||||
| sym::rustc_inherit_overflow_checks
|
||||
| sym::rustc_on_unimplemented
|
||||
| sym::rustc_doc_primitive
|
||||
| sym::rustc_layout
|
||||
| sym::rustc_autodiff
|
||||
| sym::rustc_capture_analysis
|
||||
|
||||
@@ -367,7 +367,7 @@ pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool {
|
||||
/// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]` or `#[doc(attribute)]`.
|
||||
pub fn has_primitive_or_keyword_or_attribute_docs(attrs: &[impl AttributeExt]) -> bool {
|
||||
for attr in attrs {
|
||||
if attr.has_name(sym::rustc_doc_primitive) || attr.is_doc_keyword_or_attribute() {
|
||||
if attr.is_rustc_doc_primitive() || attr.is_doc_keyword_or_attribute() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,17 +308,16 @@ pub(crate) fn primitives(
|
||||
// duplicately for the same primitive. This is handled later on when
|
||||
// rendering by delegating everything to a hash map.
|
||||
fn as_primitive(def_id: DefId, tcx: TyCtxt<'_>) -> Option<(DefId, PrimitiveType)> {
|
||||
tcx.get_attrs(def_id, sym::rustc_doc_primitive).next().map(|attr| {
|
||||
let attr_value = attr.value_str().expect("syntax should already be validated");
|
||||
let Some(prim) = PrimitiveType::from_symbol(attr_value) else {
|
||||
span_bug!(
|
||||
attr.span(),
|
||||
"primitive `{attr_value}` is not a member of `PrimitiveType`"
|
||||
);
|
||||
};
|
||||
|
||||
(def_id, prim)
|
||||
})
|
||||
let Some((attr_span, prim_sym)) = find_attr!(
|
||||
tcx.get_all_attrs(def_id),
|
||||
AttributeKind::RustcDocPrimitive(span, prim) => (*span, *prim)
|
||||
) else {
|
||||
return None;
|
||||
};
|
||||
let Some(prim) = PrimitiveType::from_symbol(prim_sym) else {
|
||||
span_bug!(attr_span, "primitive `{prim_sym}` is not a member of `PrimitiveType`");
|
||||
};
|
||||
Some((def_id, prim))
|
||||
}
|
||||
|
||||
self.mapped_root_modules(tcx, as_primitive)
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
//! other phases think of as an "item".
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_span::{Symbol, sym};
|
||||
use rustc_hir::find_attr;
|
||||
use rustc_span::Symbol;
|
||||
use rustdoc_json_types as types;
|
||||
|
||||
use super::JsonRenderer;
|
||||
@@ -88,12 +89,10 @@ fn id_from_item_inner(
|
||||
// We need this workaround because primitive types' DefId actually refers to
|
||||
// their parent module, which isn't present in the output JSON items. So
|
||||
// instead, we directly get the primitive symbol
|
||||
if matches!(self.tcx.def_kind(def_id), DefKind::Mod)
|
||||
&& let Some(prim) = self
|
||||
.tcx
|
||||
.get_attrs(def_id, sym::rustc_doc_primitive)
|
||||
.find_map(|attr| attr.value_str())
|
||||
{
|
||||
if let Some(prim) = find_attr!(
|
||||
self.tcx.get_all_attrs(def_id),
|
||||
AttributeKind::RustcDocPrimitive(_, prim) => *prim
|
||||
) {
|
||||
Some(prim)
|
||||
} else {
|
||||
self.tcx.opt_item_name(def_id)
|
||||
|
||||
Reference in New Issue
Block a user