Skip to content

Commit 2cb1293

Browse files
committed
Change ast::meta_name_value to accept any literal, not just string
This isn't useful for much of anything yet, since metadata::encoder doesn't know how to handle the non-string variants. Issue #611
1 parent 8261d2e commit 2cb1293

File tree

10 files changed

+94
-51
lines changed

10 files changed

+94
-51
lines changed

src/comp/back/link.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import std::sha1::sha1;
1414
import std::sort;
1515
import trans::crate_ctxt;
1616
import syntax::ast;
17+
import syntax::print::pprust;
1718
import lib::llvm::llvm::ModuleRef;
1819
import lib::llvm::llvm::ValueRef;
1920
import lib::llvm::mk_pass_manager;
@@ -294,16 +295,18 @@ fn build_link_meta(&session::session sess, &ast::crate c,
294295
auto linkage_metas = attr::find_linkage_metas(c.node.attrs);
295296
attr::require_unique_names(sess, linkage_metas);
296297
for (@ast::meta_item meta in linkage_metas) {
297-
alt (meta.node) {
298-
case (ast::meta_name_value("name", ?v)) {
299-
name = some(v);
298+
if (attr::get_meta_item_name(meta) == "name") {
299+
alt (attr::get_meta_item_value_str(meta)) {
300+
case (some(?v)) { name = some(v); }
301+
case (none) { cmh_items += [meta]; }
300302
}
301-
case (ast::meta_name_value("vers", ?v)) {
302-
vers = some(v);
303-
}
304-
case (_) {
305-
cmh_items += [meta];
303+
} else if (attr::get_meta_item_name(meta) == "vers") {
304+
alt (attr::get_meta_item_value_str(meta)) {
305+
case (some(?v)) { vers = some(v); }
306+
case (none) { cmh_items += [meta]; }
306307
}
308+
} else {
309+
cmh_items += [meta];
307310
}
308311
}
309312
ret rec(name = name,
@@ -317,6 +320,10 @@ fn build_link_meta(&session::session sess, &ast::crate c,
317320
fn len_and_str(&str s) -> str {
318321
ret #fmt("%u_%s", str::byte_len(s), s);
319322
}
323+
324+
fn len_and_str_lit(&ast::lit l) -> str {
325+
ret len_and_str(pprust::lit_to_str(@l));
326+
}
320327

321328
auto cmh_items = attr::sort_meta_items(metas.cmh_items);
322329

@@ -326,7 +333,7 @@ fn build_link_meta(&session::session sess, &ast::crate c,
326333
alt (m.node) {
327334
case (ast::meta_name_value(?key, ?value)) {
328335
sha.input_str(len_and_str(key));
329-
sha.input_str(len_and_str(value));
336+
sha.input_str(len_and_str_lit(value));
330337
}
331338
case (ast::meta_word(?name)) {
332339
sha.input_str(len_and_str(name));

src/comp/driver/rustc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn default_configuration(session::session sess, str argv0, str input) ->
4848
case (_) { "libc.so" }
4949
};
5050

51-
auto mk = attr::mk_name_value_item;
51+
auto mk = attr::mk_name_value_item_str;
5252

5353
ret [ // Target bindings.
5454
mk("target_os", std::os::target_os()),

src/comp/front/attr.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import syntax::ast;
88
import util::common;
99
import driver::session;
1010

11+
export attr_meta;
1112
export attr_metas;
1213
export find_linkage_metas;
1314
export find_attrs_by_name;
@@ -17,6 +18,9 @@ export sort_meta_items;
1718
export remove_meta_items_by_name;
1819
export require_unique_names;
1920
export get_attr_name;
21+
export get_meta_item_name;
22+
export get_meta_item_value_str;
23+
export mk_name_value_item_str;
2024
export mk_name_value_item;
2125
export mk_list_item;
2226
export mk_word_item;
@@ -78,9 +82,25 @@ fn get_meta_item_name(&@ast::meta_item meta) -> ast::ident {
7882
}
7983
}
8084

85+
// Gets the string value if the meta_item is a meta_name_value variant
86+
// containing a string, otherwise none
87+
fn get_meta_item_value_str(&@ast::meta_item meta) -> option::t[str] {
88+
alt (meta.node) {
89+
case (ast::meta_name_value(_, ?v)) {
90+
alt (v.node) {
91+
case (ast::lit_str(?s, _)) {
92+
option::some(s)
93+
}
94+
case (_) { option::none }
95+
}
96+
}
97+
case (_) { option::none }
98+
}
99+
}
100+
81101
fn attr_meta(&ast::attribute attr) -> @ast::meta_item { @attr.node.value }
82102

83-
// Get the meta_items from inside an attribute
103+
// Get the meta_items from inside a vector of attributes
84104
fn attr_metas(&vec[ast::attribute] attrs) -> vec[@ast::meta_item] {
85105
ret vec::map(attr_meta, attrs);
86106
}
@@ -95,7 +115,9 @@ fn eq(@ast::meta_item a, @ast::meta_item b) -> bool {
95115
}
96116
case (ast::meta_name_value(?na, ?va)) {
97117
alt (b.node) {
98-
case (ast::meta_name_value(?nb, ?vb)) { na == nb && va == vb }
118+
case (ast::meta_name_value(?nb, ?vb)) {
119+
na == nb && va.node == vb.node
120+
}
99121
case (_) { false }
100122
}
101123
}
@@ -188,7 +210,12 @@ fn span[T](&T item) -> ast::spanned[T] {
188210
ret rec(node=item, span=rec(lo=0u, hi=0u));
189211
}
190212

191-
fn mk_name_value_item(ast::ident name, str value) -> @ast::meta_item {
213+
fn mk_name_value_item_str(ast::ident name, str value) -> @ast::meta_item {
214+
auto value_lit = span(ast::lit_str(value, ast::sk_rc));
215+
ret mk_name_value_item(name, value_lit);
216+
}
217+
218+
fn mk_name_value_item(ast::ident name, ast::lit value) -> @ast::meta_item {
192219
ret @span(ast::meta_name_value(name, value));
193220
}
194221

src/comp/metadata/creader.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ fn find_library_crate(&session::session sess, &ast::ident ident,
6464
auto name_items = attr::find_meta_items_by_name(metas, "name");
6565
alt (vec::last(name_items)) {
6666
case (some(?i)) {
67-
alt (i.node) {
68-
case (ast::meta_name_value(_, ?v)) { v }
67+
alt (attr::get_meta_item_value_str(i)) {
68+
case (some(?n)) { n }
6969
case (_) {
7070
// FIXME: Probably want a warning here since the user
7171
// is using the wrong type of meta item
@@ -180,17 +180,13 @@ fn visit_item(env e, &@ast::item i) {
180180
if (!e.sess.add_used_library(m.native_name)) {
181181
ret;
182182
}
183-
for (ast::attribute a in i.attrs) {
184-
auto v = a.node.value.node;
185-
alt (v) {
186-
case (ast::meta_name_value(?i, ?s)) {
187-
if (i != "link_args") {
188-
cont;
189-
}
190-
e.sess.add_used_link_args(s);
191-
}
192-
case (_) {
183+
for (ast::attribute a in
184+
attr::find_attrs_by_name(i.attrs, "link_args")) {
185+
alt (attr::get_meta_item_value_str(attr::attr_meta(a))) {
186+
case (some(?linkarg)) {
187+
e.sess.add_used_link_args(linkarg);
193188
}
189+
case (none) { /* fallthrough */ }
194190
}
195191
}
196192
}

src/comp/metadata/decoder.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ fn get_meta_items(&ebml::doc md) -> vec[@ast::meta_item] {
276276
auto vd = ebml::get_doc(meta_item_doc, tag_meta_item_value);
277277
auto n = str::unsafe_from_bytes(ebml::doc_data(nd));
278278
auto v = str::unsafe_from_bytes(ebml::doc_data(vd));
279-
items += [attr::mk_name_value_item(n, v)];
279+
// FIXME (#611): Should be able to decode meta_name_value variants,
280+
// but currently they can't be encoded
281+
items += [attr::mk_name_value_item_str(n, v)];
280282
}
281283
for each (ebml::doc meta_item_doc in
282284
ebml::tagged_docs(md, tag_meta_item_list)) {

src/comp/metadata/encoder.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -429,14 +429,19 @@ fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
429429
ebml::end_tag(ebml_w);
430430
}
431431
case (meta_name_value(?name, ?value)) {
432-
ebml::start_tag(ebml_w, tag_meta_item_name_value);
433-
ebml::start_tag(ebml_w, tag_meta_item_name);
434-
ebml_w.writer.write(str::bytes(name));
435-
ebml::end_tag(ebml_w);
436-
ebml::start_tag(ebml_w, tag_meta_item_value);
437-
ebml_w.writer.write(str::bytes(value));
438-
ebml::end_tag(ebml_w);
439-
ebml::end_tag(ebml_w);
432+
alt (value.node) {
433+
case (lit_str(?value, _)) {
434+
ebml::start_tag(ebml_w, tag_meta_item_name_value);
435+
ebml::start_tag(ebml_w, tag_meta_item_name);
436+
ebml_w.writer.write(str::bytes(name));
437+
ebml::end_tag(ebml_w);
438+
ebml::start_tag(ebml_w, tag_meta_item_value);
439+
ebml_w.writer.write(str::bytes(value));
440+
ebml::end_tag(ebml_w);
441+
ebml::end_tag(ebml_w);
442+
}
443+
case (_) { /* FIXME (#611) */ }
444+
}
440445
}
441446
case (meta_list(?name, ?items)) {
442447
ebml::start_tag(ebml_w, tag_meta_item_list);
@@ -475,10 +480,10 @@ fn synthesize_crate_attrs(&@crate_ctxt cx,
475480
assert cx.link_meta.name != "";
476481
assert cx.link_meta.vers != "";
477482

478-
auto name_item = attr::mk_name_value_item("name",
479-
cx.link_meta.name);
480-
auto vers_item = attr::mk_name_value_item("vers",
481-
cx.link_meta.vers);
483+
auto name_item = attr::mk_name_value_item_str("name",
484+
cx.link_meta.name);
485+
auto vers_item = attr::mk_name_value_item_str("vers",
486+
cx.link_meta.vers);
482487

483488
auto other_items = {
484489
auto tmp = attr::remove_meta_items_by_name(items, "name");

src/comp/syntax/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ type meta_item = spanned[meta_item_];
104104
tag meta_item_ {
105105
meta_word(ident);
106106
meta_list(ident, vec[@meta_item]);
107-
meta_name_value(ident, str);
107+
meta_name_value(ident, lit);
108108
}
109109

110110
type block = spanned[block_];

src/comp/syntax/parse/parser.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,17 +2172,9 @@ fn parse_meta_item(&parser p) -> @ast::meta_item {
21722172
alt (p.peek()) {
21732173
case (token::EQ) {
21742174
p.bump();
2175-
alt (p.peek()) {
2176-
case (token::LIT_STR(?s)) {
2177-
p.bump();
2178-
auto value = p.get_str(s);
2179-
auto hi = p.get_hi_pos();
2180-
ret @spanned(lo, hi, ast::meta_name_value(ident, value));
2181-
}
2182-
case (_) {
2183-
p.fatal("Metadata items must be string literals");
2184-
}
2185-
}
2175+
auto lit = parse_lit(p);
2176+
auto hi = p.get_hi_pos();
2177+
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
21862178
}
21872179
case (token::LPAREN) {
21882180
auto inner_items = parse_meta_seq(p);

src/comp/syntax/print/pprust.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ fn print_meta_item(&ps s, &@ast::meta_item item) {
11031103
case (ast::meta_name_value(?name, ?value)) {
11041104
word_space(s, name);
11051105
word_space(s, "=");
1106-
print_string(s, value);
1106+
print_literal(s, @value);
11071107
}
11081108
case (ast::meta_list(?name, ?items)) {
11091109
word(s.s, name);

src/test/run-pass/item-attributes.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,20 @@ mod test_native_items {
204204
}
205205
}
206206

207+
mod test_literals {
208+
#[str = "s"];
209+
#[char = 'c'];
210+
#[int = 100];
211+
#[uint = 100u];
212+
#[mach_int = 100u32];
213+
#[float = 1.0];
214+
#[mach_float = 1.0f32];
215+
// FIXME (#622): Can't parse a nil literal here
216+
//#[nil = ()];
217+
#[bool = true];
218+
mod m {}
219+
}
220+
207221
fn main() {
208222
}
209223

0 commit comments

Comments
 (0)