1use std::fmt;
2
3use rustc_ast::attr::AttributeExt;
4use rustc_ast::token::DocFragmentKind;
5use rustc_ast::{AttrStyle, DelimArgs, MetaItemInner, MetaItemLit, ast, join_path_idents};
6use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher};
7use rustc_error_messages::{DiagArgValue, IntoDiagArg};
8use rustc_macros::{Decodable, Encodable, StableHash};
9use rustc_span::{AttrId, DUMMY_SP, Ident, Span, Symbol, sym};
10use smallvec::SmallVec;
11use thin_vec::ThinVec;
12
13use crate::AttributeKind;
14#[derive(#[automatically_derived]
impl ::core::clone::Clone for AttrArgs {
#[inline]
fn clone(&self) -> AttrArgs {
match self {
AttrArgs::Empty => AttrArgs::Empty,
AttrArgs::Delimited(__self_0) =>
AttrArgs::Delimited(::core::clone::Clone::clone(__self_0)),
AttrArgs::Eq { eq_span: __self_0, expr: __self_1 } =>
AttrArgs::Eq {
eq_span: ::core::clone::Clone::clone(__self_0),
expr: ::core::clone::Clone::clone(__self_1),
},
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AttrArgs {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
AttrArgs::Empty => ::core::fmt::Formatter::write_str(f, "Empty"),
AttrArgs::Delimited(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Delimited", &__self_0),
AttrArgs::Eq { eq_span: __self_0, expr: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f, "Eq",
"eq_span", __self_0, "expr", &__self_1),
}
}
}Debug, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for AttrArgs {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
AttrArgs::Empty => {}
AttrArgs::Delimited(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
AttrArgs::Eq {
eq_span: ref __binding_0, expr: ref __binding_1 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for AttrArgs {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
AttrArgs::Empty => { 0usize }
AttrArgs::Delimited(ref __binding_0) => { 1usize }
AttrArgs::Eq {
eq_span: ref __binding_0, expr: ref __binding_1 } => {
2usize
}
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
AttrArgs::Empty => {}
AttrArgs::Delimited(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
AttrArgs::Eq {
eq_span: ref __binding_0, expr: ref __binding_1 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for AttrArgs {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { AttrArgs::Empty }
1usize => {
AttrArgs::Delimited(::rustc_serialize::Decodable::decode(__decoder))
}
2usize => {
AttrArgs::Eq {
eq_span: ::rustc_serialize::Decodable::decode(__decoder),
expr: ::rustc_serialize::Decodable::decode(__decoder),
}
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AttrArgs`, expected 0..3, actual {0}",
n));
}
}
}
}
};Decodable)]
16pub enum AttrArgs {
17 Empty,
19 Delimited(DelimArgs),
21 Eq {
23 eq_span: Span,
25 expr: MetaItemLit,
27 },
28}
29
30#[derive(#[automatically_derived]
impl ::core::clone::Clone for AttrPath {
#[inline]
fn clone(&self) -> AttrPath {
AttrPath {
segments: ::core::clone::Clone::clone(&self.segments),
span: ::core::clone::Clone::clone(&self.span),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AttrPath {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "AttrPath",
"segments", &self.segments, "span", &&self.span)
}
}Debug, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for AttrPath {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
AttrPath { segments: ref __binding_0, span: ref __binding_1
} => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for AttrPath {
fn encode(&self, __encoder: &mut __E) {
match *self {
AttrPath { segments: ref __binding_0, span: ref __binding_1
} => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for AttrPath {
fn decode(__decoder: &mut __D) -> Self {
AttrPath {
segments: ::rustc_serialize::Decodable::decode(__decoder),
span: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
31pub struct AttrPath {
32 pub segments: Box<[Symbol]>,
33 pub span: Span,
34}
35
36impl IntoDiagArg for AttrPath {
37 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
38 self.to_string().into_diag_arg(path)
39 }
40}
41
42impl AttrPath {
43 pub fn from_ast(path: &ast::Path, lower_span: impl Copy + Fn(Span) -> Span) -> Self {
44 AttrPath {
45 segments: path
46 .segments
47 .iter()
48 .map(|i| i.ident.name)
49 .collect::<Vec<_>>()
50 .into_boxed_slice(),
51 span: lower_span(path.span),
52 }
53 }
54}
55
56impl fmt::Display for AttrPath {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 f.write_fmt(format_args!("{0}",
join_path_idents(self.segments.iter().map(|i|
Ident { name: *i, span: DUMMY_SP }))))write!(
59 f,
60 "{}",
61 join_path_idents(self.segments.iter().map(|i| Ident { name: *i, span: DUMMY_SP }))
62 )
63 }
64}
65
66#[derive(#[automatically_derived]
impl ::core::clone::Clone for AttrItem {
#[inline]
fn clone(&self) -> AttrItem {
AttrItem {
path: ::core::clone::Clone::clone(&self.path),
args: ::core::clone::Clone::clone(&self.args),
id: ::core::clone::Clone::clone(&self.id),
style: ::core::clone::Clone::clone(&self.style),
span: ::core::clone::Clone::clone(&self.span),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for AttrItem {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field5_finish(f, "AttrItem",
"path", &self.path, "args", &self.args, "id", &self.id, "style",
&self.style, "span", &&self.span)
}
}Debug, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for AttrItem {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
AttrItem {
path: ref __binding_0,
args: ref __binding_1,
id: ref __binding_2,
style: ref __binding_3,
span: ref __binding_4 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
{ __binding_3.stable_hash(__hcx, __hasher); }
{ __binding_4.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for AttrItem {
fn encode(&self, __encoder: &mut __E) {
match *self {
AttrItem {
path: ref __binding_0,
args: ref __binding_1,
id: ref __binding_2,
style: ref __binding_3,
span: ref __binding_4 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_4,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for AttrItem {
fn decode(__decoder: &mut __D) -> Self {
AttrItem {
path: ::rustc_serialize::Decodable::decode(__decoder),
args: ::rustc_serialize::Decodable::decode(__decoder),
id: ::rustc_serialize::Decodable::decode(__decoder),
style: ::rustc_serialize::Decodable::decode(__decoder),
span: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
67pub struct AttrItem {
68 pub path: AttrPath,
70 pub args: AttrArgs,
71 pub id: HashIgnoredAttrId,
72 pub style: AttrStyle,
75 pub span: Span,
77}
78
79#[derive(#[automatically_derived]
impl ::core::marker::Copy for HashIgnoredAttrId { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for HashIgnoredAttrId {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"HashIgnoredAttrId", "attr_id", &&self.attr_id)
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for HashIgnoredAttrId {
fn encode(&self, __encoder: &mut __E) {
match *self {
HashIgnoredAttrId { attr_id: ref __binding_0 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for HashIgnoredAttrId {
fn decode(__decoder: &mut __D) -> Self {
HashIgnoredAttrId {
attr_id: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable, #[automatically_derived]
impl ::core::clone::Clone for HashIgnoredAttrId {
#[inline]
fn clone(&self) -> HashIgnoredAttrId {
let _: ::core::clone::AssertParamIsClone<AttrId>;
*self
}
}Clone)]
82pub struct HashIgnoredAttrId {
83 pub attr_id: AttrId,
84}
85
86impl StableHash for HashIgnoredAttrId {
87 fn stable_hash<Hcx: StableHashCtxt>(&self, _hcx: &mut Hcx, _hasher: &mut StableHasher) {
88 }
90}
91
92#[derive(#[automatically_derived]
impl ::core::clone::Clone for Attribute {
#[inline]
fn clone(&self) -> Attribute {
match self {
Attribute::Parsed(__self_0) =>
Attribute::Parsed(::core::clone::Clone::clone(__self_0)),
Attribute::Unparsed(__self_0) =>
Attribute::Unparsed(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Attribute {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Attribute::Parsed(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Parsed",
&__self_0),
Attribute::Unparsed(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Unparsed", &__self_0),
}
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Attribute {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Attribute::Parsed(ref __binding_0) => { 0usize }
Attribute::Unparsed(ref __binding_0) => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Attribute::Parsed(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
Attribute::Unparsed(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Attribute {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
Attribute::Parsed(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
Attribute::Unparsed(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Attribute`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for Attribute {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
Attribute::Parsed(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
Attribute::Unparsed(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
95pub enum Attribute {
96 Parsed(AttributeKind),
102
103 Unparsed(Box<AttrItem>),
106}
107
108impl Attribute {
109 pub fn get_normal_item(&self) -> &AttrItem {
110 match &self {
111 Attribute::Unparsed(normal) => &normal,
112 _ => { ::core::panicking::panic_fmt(format_args!("unexpected parsed attribute")); }panic!("unexpected parsed attribute"),
113 }
114 }
115
116 pub fn value_lit(&self) -> Option<&MetaItemLit> {
117 match &self {
118 Attribute::Unparsed(n) => match n.as_ref() {
119 AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
120 _ => None,
121 },
122 _ => None,
123 }
124 }
125
126 pub fn is_parsed_attr(&self) -> bool {
127 match self {
128 Attribute::Parsed(_) => true,
129 Attribute::Unparsed(_) => false,
130 }
131 }
132
133 pub fn is_prefix_attr_for_suggestions(&self) -> bool {
134 match self {
135 Attribute::Unparsed(attr) => attr.span.desugaring_kind().is_none(),
136 Attribute::Parsed(_) => true,
139 }
140 }
141}
142
143impl AttributeExt for Attribute {
144 #[inline]
145 fn id(&self) -> AttrId {
146 match &self {
147 Attribute::Unparsed(u) => u.id.attr_id,
148 _ => ::core::panicking::panic("explicit panic")panic!(),
149 }
150 }
151
152 #[inline]
153 fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
154 match &self {
155 Attribute::Unparsed(n) => match n.as_ref() {
156 AttrItem { args: AttrArgs::Delimited(d), .. } => {
157 ast::MetaItemKind::list_from_tokens(d.tokens.clone())
158 }
159 _ => None,
160 },
161 _ => None,
162 }
163 }
164
165 #[inline]
166 fn value_str(&self) -> Option<Symbol> {
167 self.value_lit().and_then(|x| x.value_as_str())
168 }
169
170 #[inline]
171 fn value_span(&self) -> Option<Span> {
172 self.value_lit().map(|i| i.span)
173 }
174
175 #[inline]
177 fn name(&self) -> Option<Symbol> {
178 match &self {
179 Attribute::Unparsed(n) => {
180 if let [ident] = n.path.segments.as_ref() {
181 Some(*ident)
182 } else {
183 None
184 }
185 }
186 _ => None,
187 }
188 }
189
190 #[inline]
191 fn path_matches(&self, name: &[Symbol]) -> bool {
192 match &self {
193 Attribute::Unparsed(n) => n.path.segments.iter().eq(name),
194 _ => false,
195 }
196 }
197
198 #[inline]
199 fn is_doc_comment(&self) -> Option<Span> {
200 if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self {
201 Some(*span)
202 } else {
203 None
204 }
205 }
206
207 #[inline]
208 fn span(&self) -> Span {
209 match &self {
210 Attribute::Unparsed(u) => u.span,
211 Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
213 Attribute::Parsed(AttributeKind::Deprecated { span, .. }) => *span,
214 Attribute::Parsed(AttributeKind::CfgTrace(cfgs)) => cfgs[0].1,
215 a => {
::core::panicking::panic_fmt(format_args!("can\'t get the span of an arbitrary parsed attribute: {0:?}",
a));
}panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
216 }
217 }
218
219 #[inline]
220 fn is_word(&self) -> bool {
221 match &self {
222 Attribute::Unparsed(n) => {
223 #[allow(non_exhaustive_omitted_patterns)] match n.args {
AttrArgs::Empty => true,
_ => false,
}matches!(n.args, AttrArgs::Empty)
224 }
225 _ => false,
226 }
227 }
228
229 #[inline]
230 fn symbol_path(&self) -> Option<SmallVec<[Symbol; 1]>> {
231 match &self {
232 Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
233 _ => None,
234 }
235 }
236
237 fn path_span(&self) -> Option<Span> {
238 match &self {
239 Attribute::Unparsed(attr) => Some(attr.path.span),
240 Attribute::Parsed(_) => None,
241 }
242 }
243
244 #[inline]
245 fn doc_str(&self) -> Option<Symbol> {
246 match &self {
247 Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment),
248 _ => None,
249 }
250 }
251
252 fn is_automatically_derived_attr(&self) -> bool {
253 #[allow(non_exhaustive_omitted_patterns)] match self {
Attribute::Parsed(AttributeKind::AutomaticallyDerived) => true,
_ => false,
}matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived))
254 }
255
256 #[inline]
257 fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> {
258 match &self {
259 Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
260 Some((*comment, *kind))
261 }
262 _ => None,
263 }
264 }
265
266 fn doc_resolution_scope(&self) -> Option<AttrStyle> {
267 match self {
268 Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style),
269 Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => {
270 Some(attr.style)
271 }
272 _ => None,
273 }
274 }
275
276 fn is_proc_macro_attr(&self) -> bool {
277 #[allow(non_exhaustive_omitted_patterns)] match self {
Attribute::Parsed(AttributeKind::ProcMacro |
AttributeKind::ProcMacroAttribute | AttributeKind::ProcMacroDerive {
.. }) => true,
_ => false,
}matches!(
278 self,
279 Attribute::Parsed(
280 AttributeKind::ProcMacro
281 | AttributeKind::ProcMacroAttribute
282 | AttributeKind::ProcMacroDerive { .. }
283 )
284 )
285 }
286
287 fn is_doc_hidden(&self) -> bool {
288 #[allow(non_exhaustive_omitted_patterns)] match self {
Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some() => true,
_ => false,
}matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some())
289 }
290
291 fn is_doc_keyword_or_attribute(&self) -> bool {
292 #[allow(non_exhaustive_omitted_patterns)] match self {
Attribute::Parsed(AttributeKind::Doc(d)) if
d.attribute.is_some() || d.keyword.is_some() => true,
_ => false,
}matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some())
293 }
294
295 fn is_rustc_doc_primitive(&self) -> bool {
296 #[allow(non_exhaustive_omitted_patterns)] match self {
Attribute::Parsed(AttributeKind::RustcDocPrimitive(..)) => true,
_ => false,
}matches!(self, Attribute::Parsed(AttributeKind::RustcDocPrimitive(..)))
297 }
298}
299
300impl Attribute {
302 #[inline]
303 pub fn id(&self) -> AttrId {
304 AttributeExt::id(self)
305 }
306
307 #[inline]
308 pub fn name(&self) -> Option<Symbol> {
309 AttributeExt::name(self)
310 }
311
312 #[inline]
313 pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
314 AttributeExt::meta_item_list(self)
315 }
316
317 #[inline]
318 pub fn value_str(&self) -> Option<Symbol> {
319 AttributeExt::value_str(self)
320 }
321
322 #[inline]
323 pub fn value_span(&self) -> Option<Span> {
324 AttributeExt::value_span(self)
325 }
326
327 #[inline]
328 pub fn path_matches(&self, name: &[Symbol]) -> bool {
329 AttributeExt::path_matches(self, name)
330 }
331
332 #[inline]
333 pub fn is_doc_comment(&self) -> Option<Span> {
334 AttributeExt::is_doc_comment(self)
335 }
336
337 #[inline]
338 pub fn has_name(&self, name: Symbol) -> bool {
339 AttributeExt::has_name(self, name)
340 }
341
342 #[inline]
343 pub fn has_any_name(&self, names: &[Symbol]) -> bool {
344 AttributeExt::has_any_name(self, names)
345 }
346
347 #[inline]
348 pub fn span(&self) -> Span {
349 AttributeExt::span(self)
350 }
351
352 #[inline]
353 pub fn is_word(&self) -> bool {
354 AttributeExt::is_word(self)
355 }
356
357 #[inline]
358 pub fn path(&self) -> SmallVec<[Symbol; 1]> {
359 AttributeExt::path(self)
360 }
361
362 #[inline]
363 pub fn doc_str(&self) -> Option<Symbol> {
364 AttributeExt::doc_str(self)
365 }
366
367 #[inline]
368 pub fn is_proc_macro_attr(&self) -> bool {
369 AttributeExt::is_proc_macro_attr(self)
370 }
371
372 #[inline]
373 pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> {
374 AttributeExt::doc_str_and_fragment_kind(self)
375 }
376}