Skip to content

Commit 57e6340

Browse files
committed
Allow 'newtype' syntax for tags
Doing this: tag foo = mytype; is now equivalent to doing this: tag foo { foo(mytype); }
1 parent fb72be0 commit 57e6340

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

src/comp/front/parser.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
945945
hi = es.span.hi;
946946
ex = ast::expr_call(f, es.node);
947947
} else if (is_ident(p.peek()) && !is_word(p, "true") &&
948-
!is_word(p, "false")) {
948+
!is_word(p, "false")) {
949949
check_bad_word(p);
950950
auto pth = parse_path_and_ty_param_substs(p);
951951
hi = pth.span.hi;
@@ -1979,6 +1979,21 @@ fn parse_item_tag(&parser p, vec[ast::attribute] attrs) -> @ast::item {
19791979
auto id = parse_ident(p);
19801980
auto ty_params = parse_ty_params(p);
19811981
let vec[ast::variant] variants = [];
1982+
// Newtype syntax
1983+
if (p.peek() == token::EQ) {
1984+
if (p.get_bad_expr_words().contains_key(id)) {
1985+
p.fatal("found " + id + " in tag constructor position");
1986+
}
1987+
p.bump();
1988+
auto ty = parse_ty(p);
1989+
expect(p, token::SEMI);
1990+
auto variant = spanned(ty.span.lo, ty.span.hi,
1991+
rec(name=id,
1992+
args=[rec(ty=ty, id=p.get_id())],
1993+
id=p.get_id()));
1994+
ret mk_item(p, lo, ty.span.hi, id,
1995+
ast::item_tag([variant], ty_params), attrs);
1996+
}
19821997
expect(p, token::LBRACE);
19831998
while (p.peek() != token::RBRACE) {
19841999
auto tok = p.peek();

src/comp/pretty/pprust.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -383,27 +383,43 @@ fn print_item(&ps s, &@ast::item item) {
383383
break_offset(s.s, 0u, 0);
384384
}
385385
case (ast::item_tag(?variants, ?params)) {
386-
head(s, "tag");
386+
auto newtype = vec::len(variants) == 1u &&
387+
str::eq(item.ident, variants.(0).node.name) &&
388+
vec::len(variants.(0).node.args) == 1u;
389+
if (newtype) {
390+
ibox(s, indent_unit);
391+
word_space(s, "tag");
392+
} else {
393+
head(s, "tag");
394+
}
387395
word(s.s, item.ident);
388396
print_type_params(s, params);
389397
space(s.s);
390-
bopen(s);
391-
for (ast::variant v in variants) {
392-
space(s.s);
393-
maybe_print_comment(s, v.span.lo);
394-
word(s.s, v.node.name);
395-
if (vec::len(v.node.args) > 0u) {
396-
popen(s);
397-
fn print_variant_arg(&ps s, &ast::variant_arg arg) {
398-
print_type(s, *arg.ty);
398+
if (newtype) {
399+
word_space(s, "=");
400+
print_type(s, *variants.(0).node.args.(0).ty);
401+
word(s.s, ";");
402+
end(s);
403+
} else {
404+
bopen(s);
405+
for (ast::variant v in variants) {
406+
space(s.s);
407+
maybe_print_comment(s, v.span.lo);
408+
word(s.s, v.node.name);
409+
if (vec::len(v.node.args) > 0u) {
410+
popen(s);
411+
fn print_variant_arg(&ps s, &ast::variant_arg arg) {
412+
print_type(s, *arg.ty);
413+
}
414+
commasep(s, consistent, v.node.args,
415+
print_variant_arg);
416+
pclose(s);
399417
}
400-
commasep(s, consistent, v.node.args, print_variant_arg);
401-
pclose(s);
418+
word(s.s, ";");
419+
maybe_print_trailing_comment(s, v.span, none[uint]);
402420
}
403-
word(s.s, ";");
404-
maybe_print_trailing_comment(s, v.span, none[uint]);
421+
bclose(s, item.span);
405422
}
406-
bclose(s, item.span);
407423
}
408424
case (ast::item_obj(?_obj, ?params, _)) {
409425
head(s, "obj");

0 commit comments

Comments
 (0)