Skip to content

Commit ba876c2

Browse files
committed
Rollup merge of #35850 - SergioBenitez:master, r=nrc
Implement RFC#1559: allow all literals in attributes Implemented rust-lang/rfcs#1559, tracked by #34981.
2 parents 6f074ba + 5d525ec commit ba876c2

File tree

3 files changed

+46
-19
lines changed

3 files changed

+46
-19
lines changed

clean/mod.rs

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ pub use self::Visibility::*;
2626
use syntax::abi::Abi;
2727
use syntax::ast;
2828
use syntax::attr;
29-
use syntax::attr::{AttributeMethods, AttrMetaMethods};
29+
use syntax::attr::{AttributeMethods, AttrMetaMethods, AttrNestedMetaItemMethods};
3030
use syntax::codemap::Spanned;
3131
use syntax::parse::token::{self, InternedString, keywords};
3232
use syntax::ptr::P;
33+
use syntax::print::pprust as syntax_pprust;
3334
use syntax_pos::{self, DUMMY_SP, Pos};
3435

3536
use rustc_trans::back::link;
@@ -501,11 +502,24 @@ impl Attributes for [Attribute] {
501502
}
502503
}
503504

505+
/// This is a flattened version of the AST's Attribute + MetaItem.
504506
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
505507
pub enum Attribute {
506508
Word(String),
507509
List(String, Vec<Attribute>),
508-
NameValue(String, String)
510+
NameValue(String, String),
511+
Literal(String),
512+
}
513+
514+
impl Clean<Attribute> for ast::NestedMetaItem {
515+
fn clean(&self, cx: &DocContext) -> Attribute {
516+
if let Some(mi) = self.meta_item() {
517+
mi.clean(cx)
518+
} else { // must be a literal
519+
let lit = self.literal().unwrap();
520+
Literal(syntax_pprust::lit_to_string(lit))
521+
}
522+
}
509523
}
510524

511525
impl Clean<Attribute> for ast::MetaItem {
@@ -528,12 +542,28 @@ impl Clean<Attribute> for ast::Attribute {
528542
}
529543

530544
// This is a rough approximation that gets us what we want.
531-
impl attr::AttrMetaMethods for Attribute {
532-
fn name(&self) -> InternedString {
545+
impl attr::AttrNestedMetaItemMethods for Attribute {
546+
fn check_name(&self, name: &str) -> bool {
547+
self.name().map_or(false, |mi_name| &*mi_name == name)
548+
}
549+
550+
fn literal(&self) -> Option<&ast::Lit> { None }
551+
552+
fn is_literal(&self) -> bool {
553+
match *self {
554+
Literal(..) => true,
555+
_ => false,
556+
}
557+
}
558+
559+
fn meta_item(&self) -> Option<&P<ast::MetaItem>> { None }
560+
561+
fn name(&self) -> Option<InternedString> {
533562
match *self {
534563
Word(ref n) | List(ref n, _) | NameValue(ref n, _) => {
535-
token::intern_and_get_ident(n)
536-
}
564+
Some(token::intern_and_get_ident(n))
565+
},
566+
_ => None
537567
}
538568
}
539569

@@ -545,7 +575,8 @@ impl attr::AttrMetaMethods for Attribute {
545575
_ => None,
546576
}
547577
}
548-
fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }
578+
579+
fn word(&self) -> Option<&P<ast::MetaItem>> { None }
549580

550581
fn is_word(&self) -> bool {
551582
match *self {
@@ -554,12 +585,7 @@ impl attr::AttrMetaMethods for Attribute {
554585
}
555586
}
556587

557-
fn is_value_str(&self) -> bool {
558-
match *self {
559-
NameValue(..) => true,
560-
_ => false,
561-
}
562-
}
588+
fn meta_item_list<'a>(&'a self) -> Option<&'a [ast::NestedMetaItem]> { None }
563589

564590
fn is_meta_item_list(&self) -> bool {
565591
match *self {
@@ -2534,8 +2560,8 @@ impl Clean<Vec<Item>> for doctree::Import {
25342560
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
25352561
let denied = self.vis != hir::Public || self.attrs.iter().any(|a| {
25362562
&a.name()[..] == "doc" && match a.meta_item_list() {
2537-
Some(l) => attr::contains_name(l, "no_inline") ||
2538-
attr::contains_name(l, "hidden"),
2563+
Some(l) => attr::list_contains_name(l, "no_inline") ||
2564+
attr::list_contains_name(l, "hidden"),
25392565
None => false,
25402566
}
25412567
});

test.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ pub fn run(input: &str,
141141
// Look for #![doc(test(no_crate_inject))], used by crates in the std facade
142142
fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
143143
use syntax::attr::AttrMetaMethods;
144+
use syntax::attr::AttrNestedMetaItemMethods;
144145
use syntax::print::pprust;
145146

146147
let mut opts = TestOptions {
@@ -162,7 +163,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
162163
if attr.check_name("attr") {
163164
if let Some(l) = attr.meta_item_list() {
164165
for item in l {
165-
opts.attrs.push(pprust::meta_item_to_string(item));
166+
opts.attrs.push(pprust::meta_list_item_to_string(item));
166167
}
167168
}
168169
}

visit_ast.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::mem;
1717
use syntax::abi;
1818
use syntax::ast;
1919
use syntax::attr;
20-
use syntax::attr::AttrMetaMethods;
20+
use syntax::attr::{AttrMetaMethods, AttrNestedMetaItemMethods};
2121
use syntax_pos::Span;
2222

2323
use rustc::hir::map as hir_map;
@@ -333,8 +333,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
333333
let node = if item.vis == hir::Public {
334334
let please_inline = item.attrs.iter().any(|item| {
335335
match item.meta_item_list() {
336-
Some(list) if &item.name()[..] == "doc" => {
337-
list.iter().any(|i| &i.name()[..] == "inline")
336+
Some(list) if item.check_name("doc") => {
337+
list.iter().any(|i| i.check_name("inline"))
338338
}
339339
_ => false,
340340
}

0 commit comments

Comments
 (0)