Skip to content

Commit 911245b

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

File tree

13 files changed

+711
-403
lines changed

13 files changed

+711
-403
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 285 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,22 @@ 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+
pub fn ident(&self) -> Option<Ident> {
1176+
if let [ident] = self.segments.as_ref() { Some(*ident) } else { None }
1177+
}
1178+
1179+
#[inline]
1180+
pub fn has_name(&self, name: Symbol) -> bool {
1181+
self.name() == Some(name)
1182+
}
11671183
}
11681184

11691185
impl fmt::Display for AttrPath {
@@ -1206,27 +1222,48 @@ pub enum Attribute {
12061222
Unparsed(Box<AttrItem>),
12071223
}
12081224

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

1217-
pub fn unwrap_normal_item(self) -> AttrItem {
1256+
pub fn unwrap_attritem(self) -> AttrItem {
12181257
match self {
12191258
Attribute::Unparsed(normal) => *normal,
12201259
_ => panic!("unexpected parsed attribute"),
12211260
}
12221261
}
1223-
1262+
}
1263+
impl AttrItem {
12241264
pub fn value_lit(&self) -> Option<&MetaItemLit> {
12251265
match &self {
1226-
Attribute::Unparsed(n) => match n.as_ref() {
1227-
AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
1228-
_ => None,
1229-
},
1266+
AttrItem { args: AttrArgs::Eq { eq_span: _, expr }, .. } => Some(expr),
12301267
_ => None,
12311268
}
12321269
}
@@ -1256,12 +1293,18 @@ impl AttributeExt for Attribute {
12561293

12571294
#[inline]
12581295
fn value_str(&self) -> Option<Symbol> {
1259-
self.value_lit().and_then(|x| x.value_str())
1296+
match self {
1297+
Attribute::Parsed(_) => None,
1298+
Attribute::Unparsed(attr_item) => attr_item.value_lit().and_then(|x| x.value_str()),
1299+
}
12601300
}
12611301

12621302
#[inline]
12631303
fn value_span(&self) -> Option<Span> {
1264-
self.value_lit().map(|i| i.span)
1304+
match self {
1305+
Attribute::Parsed(_) => None,
1306+
Attribute::Unparsed(attr_item) => attr_item.value_lit().map(|i| i.span),
1307+
}
12651308
}
12661309

12671310
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
@@ -1355,6 +1398,239 @@ impl AttributeExt for Attribute {
13551398
}
13561399
}
13571400

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

0 commit comments

Comments
 (0)