Skip to content

Commit b6cceda

Browse files
committed
Use AttrItem instead of Attribute in more places
1 parent 586ad39 commit b6cceda

File tree

13 files changed

+715
-403
lines changed

13 files changed

+715
-403
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 286 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,23 @@ impl AttrPath {
11641164
span: path.span,
11651165
}
11661166
}
1167+
1168+
/// For a single-segment attribute (i.e., `#[attr]` and not `#[path::atrr]`),
1169+
/// return the name of the attribute; otherwise, returns `None`.
1170+
pub fn name(&self) -> Option<Symbol> {
1171+
self.ident().map(|ident| ident.name)
1172+
}
1173+
1174+
/// For a single-segment attribute, returns its ident; otherwise, returns `None`.
1175+
1176+
pub fn ident(&self) -> Option<Ident> {
1177+
if let [ident] = self.segments.as_ref() { Some(*ident) } else { None }
1178+
}
1179+
1180+
#[inline]
1181+
pub fn has_name(&self, name: Symbol) -> bool {
1182+
self.name() == Some(name)
1183+
}
11671184
}
11681185

11691186
impl fmt::Display for AttrPath {
@@ -1206,27 +1223,48 @@ pub enum Attribute {
12061223
Unparsed(Box<AttrItem>),
12071224
}
12081225

1226+
pub fn find_attritems_by_name(
1227+
attrs: &[Attribute],
1228+
name: Symbol,
1229+
) -> impl Iterator<Item = &AttrItem> {
1230+
attrs.iter().filter_map(move |attr| match attr {
1231+
Attribute::Unparsed(attr_item) if attr_item.has_name(name) => Some(&**attr_item),
1232+
_ => None,
1233+
})
1234+
}
1235+
12091236
impl Attribute {
1210-
pub fn get_normal_item(&self) -> &AttrItem {
1237+
pub fn attritem(self) -> Option<AttrItem> {
1238+
match self {
1239+
Attribute::Parsed(_) => None,
1240+
Attribute::Unparsed(attr_item) => Some(*attr_item),
1241+
}
1242+
}
1243+
pub fn attritem_ref(&self) -> Option<&AttrItem> {
1244+
match self {
1245+
Attribute::Parsed(_) => None,
1246+
Attribute::Unparsed(attr_item) => Some(attr_item),
1247+
}
1248+
}
1249+
1250+
pub fn unwrap_attritem_ref(&self) -> &AttrItem {
12111251
match &self {
12121252
Attribute::Unparsed(normal) => &normal,
12131253
_ => panic!("unexpected parsed attribute"),
12141254
}
12151255
}
12161256

1217-
pub fn unwrap_normal_item(self) -> AttrItem {
1257+
pub fn unwrap_attritem(self) -> AttrItem {
12181258
match self {
12191259
Attribute::Unparsed(normal) => *normal,
12201260
_ => panic!("unexpected parsed attribute"),
12211261
}
12221262
}
1223-
1263+
}
1264+
impl AttrItem {
12241265
pub fn value_lit(&self) -> Option<&MetaItemLit> {
12251266
match &self {
1226-
Attribute::Unparsed(n) => match n.as_ref() {
1227-
AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
1228-
_ => None,
1229-
},
1267+
AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
12301268
_ => None,
12311269
}
12321270
}
@@ -1256,12 +1294,18 @@ impl AttributeExt for Attribute {
12561294

12571295
#[inline]
12581296
fn value_str(&self) -> Option<Symbol> {
1259-
self.value_lit().and_then(|x| x.value_str())
1297+
match self {
1298+
Attribute::Parsed(_) => None,
1299+
Attribute::Unparsed(attr_item) => attr_item.value_lit().and_then(|x| x.value_str()),
1300+
}
12601301
}
12611302

12621303
#[inline]
12631304
fn value_span(&self) -> Option<Span> {
1264-
self.value_lit().map(|i| i.span)
1305+
match self {
1306+
Attribute::Parsed(_) => None,
1307+
Attribute::Unparsed(attr_item) => attr_item.value_lit().map(|i| i.span),
1308+
}
12651309
}
12661310

12671311
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
@@ -1355,6 +1399,239 @@ impl AttributeExt for Attribute {
13551399
}
13561400
}
13571401

1402+
impl AttributeExt for AttrItem {
1403+
#[inline]
1404+
fn id(&self) -> AttrId {
1405+
self.id.attr_id
1406+
}
1407+
1408+
#[inline]
1409+
fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
1410+
match &self {
1411+
AttrItem { args: AttrArgs::Delimited(d), .. } => {
1412+
ast::MetaItemKind::list_from_tokens(d.tokens.clone())
1413+
}
1414+
_ => None,
1415+
}
1416+
}
1417+
1418+
#[inline]
1419+
fn value_str(&self) -> Option<Symbol> {
1420+
self.value_lit().and_then(|x| x.value_str())
1421+
}
1422+
1423+
#[inline]
1424+
fn value_span(&self) -> Option<Span> {
1425+
self.value_lit().map(|i| i.span)
1426+
}
1427+
1428+
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
1429+
#[inline]
1430+
fn ident(&self) -> Option<Ident> {
1431+
self.path.ident()
1432+
}
1433+
1434+
#[inline]
1435+
fn path_matches(&self, name: &[Symbol]) -> bool {
1436+
self.path.segments.len() == name.len()
1437+
&& self.path.segments.iter().zip(name).all(|(s, n)| s.name == *n)
1438+
}
1439+
1440+
#[inline]
1441+
fn is_doc_comment(&self) -> bool {
1442+
false
1443+
}
1444+
1445+
#[inline]
1446+
fn span(&self) -> Span {
1447+
self.span
1448+
}
1449+
1450+
#[inline]
1451+
fn is_word(&self) -> bool {
1452+
matches!(self.args, AttrArgs::Empty)
1453+
}
1454+
1455+
#[inline]
1456+
fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1457+
Some(self.path.segments.iter().copied().collect())
1458+
}
1459+
1460+
#[inline]
1461+
fn doc_str(&self) -> Option<Symbol> {
1462+
if self.has_name(sym::doc) { self.value_str() } else { None }
1463+
}
1464+
#[inline]
1465+
fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1466+
if self.has_name(sym::doc) {
1467+
self.value_str().map(|s| (s, CommentKind::Line))
1468+
} else {
1469+
None
1470+
}
1471+
}
1472+
1473+
#[inline]
1474+
fn style(&self) -> AttrStyle {
1475+
self.style
1476+
}
1477+
}
1478+
1479+
// FIXME(fn_delegation): use function delegation instead of manually forwarding
1480+
impl AttributeExt for &'_ AttrItem {
1481+
#[inline]
1482+
fn id(&self) -> AttrId {
1483+
<AttrItem as AttributeExt>::id(self)
1484+
}
1485+
1486+
#[inline]
1487+
fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1488+
<AttrItem as AttributeExt>::meta_item_list(self)
1489+
}
1490+
1491+
#[inline]
1492+
fn value_str(&self) -> Option<Symbol> {
1493+
<AttrItem as AttributeExt>::value_str(self)
1494+
}
1495+
1496+
#[inline]
1497+
fn value_span(&self) -> Option<Span> {
1498+
<AttrItem as AttributeExt>::value_span(self)
1499+
}
1500+
1501+
#[inline]
1502+
fn ident(&self) -> Option<Ident> {
1503+
<AttrItem as AttributeExt>::ident(self)
1504+
}
1505+
1506+
#[inline]
1507+
fn path_matches(&self, name: &[Symbol]) -> bool {
1508+
<AttrItem as AttributeExt>::path_matches(self, name)
1509+
}
1510+
1511+
#[inline]
1512+
fn is_doc_comment(&self) -> bool {
1513+
<AttrItem as AttributeExt>::is_doc_comment(self)
1514+
}
1515+
1516+
#[inline]
1517+
fn span(&self) -> Span {
1518+
<AttrItem as AttributeExt>::span(self)
1519+
}
1520+
1521+
#[inline]
1522+
fn is_word(&self) -> bool {
1523+
<AttrItem as AttributeExt>::is_word(self)
1524+
}
1525+
1526+
#[inline]
1527+
fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1528+
<AttrItem as AttributeExt>::ident_path(self)
1529+
}
1530+
1531+
#[inline]
1532+
fn doc_str(&self) -> Option<Symbol> {
1533+
<AttrItem as AttributeExt>::doc_str(self)
1534+
}
1535+
1536+
#[inline]
1537+
fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1538+
<AttrItem as AttributeExt>::doc_str_and_comment_kind(self)
1539+
}
1540+
1541+
#[inline]
1542+
fn style(&self) -> AttrStyle {
1543+
<AttrItem as AttributeExt>::style(self)
1544+
}
1545+
}
1546+
1547+
// FIXME(fn_delegation): use function delegation instead of manually forwarding
1548+
impl AttrItem {
1549+
#[inline]
1550+
pub fn id(&self) -> AttrId {
1551+
<AttrItem as AttributeExt>::id(self)
1552+
}
1553+
1554+
#[inline]
1555+
pub fn path(&self) -> SmallVec<[Symbol; 1]> {
1556+
<AttrItem as AttributeExt>::path(self)
1557+
}
1558+
1559+
#[inline]
1560+
pub fn name(&self) -> Option<Symbol> {
1561+
<AttrItem as AttributeExt>::name(self)
1562+
}
1563+
1564+
#[inline]
1565+
pub fn has_name(&self, name: Symbol) -> bool {
1566+
<AttrItem as AttributeExt>::has_name(self, name)
1567+
}
1568+
1569+
#[inline]
1570+
pub fn has_any_name(&self, names: &[Symbol]) -> bool {
1571+
<AttrItem as AttributeExt>::has_any_name(self, names)
1572+
}
1573+
1574+
#[inline]
1575+
pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
1576+
<AttrItem as AttributeExt>::meta_item_list(self)
1577+
}
1578+
1579+
#[inline]
1580+
pub fn value_str(&self) -> Option<Symbol> {
1581+
<AttrItem as AttributeExt>::value_str(self)
1582+
}
1583+
1584+
#[inline]
1585+
pub fn value_span(&self) -> Option<Span> {
1586+
<AttrItem as AttributeExt>::value_span(self)
1587+
}
1588+
1589+
#[inline]
1590+
pub fn ident(&self) -> Option<Ident> {
1591+
<AttrItem as AttributeExt>::ident(self)
1592+
}
1593+
1594+
#[inline]
1595+
pub fn path_matches(&self, name: &[Symbol]) -> bool {
1596+
<AttrItem as AttributeExt>::path_matches(self, name)
1597+
}
1598+
1599+
#[inline]
1600+
pub fn is_doc_comment(&self) -> bool {
1601+
<AttrItem as AttributeExt>::is_doc_comment(self)
1602+
}
1603+
1604+
#[inline]
1605+
pub fn span(&self) -> Span {
1606+
<AttrItem as AttributeExt>::span(self)
1607+
}
1608+
1609+
#[inline]
1610+
pub fn is_word(&self) -> bool {
1611+
<AttrItem as AttributeExt>::is_word(self)
1612+
}
1613+
1614+
#[inline]
1615+
pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
1616+
<AttrItem as AttributeExt>::ident_path(self)
1617+
}
1618+
1619+
#[inline]
1620+
pub fn doc_str(&self) -> Option<Symbol> {
1621+
<AttrItem as AttributeExt>::doc_str(self)
1622+
}
1623+
1624+
#[inline]
1625+
pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
1626+
<AttrItem as AttributeExt>::doc_str_and_comment_kind(self)
1627+
}
1628+
1629+
#[inline]
1630+
pub fn style(&self) -> AttrStyle {
1631+
<AttrItem as AttributeExt>::style(self)
1632+
}
1633+
}
1634+
13581635
// FIXME(fn_delegation): use function delegation instead of manually forwarding
13591636
impl Attribute {
13601637
#[inline]

0 commit comments

Comments
 (0)