Skip to content

Commit ecf1bd7

Browse files
committed
rustc: Use spans on extfmt error messages
Issue #444
1 parent 794221b commit ecf1bd7

File tree

6 files changed

+68
-29
lines changed

6 files changed

+68
-29
lines changed

src/comp/front/extfmt.rs

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,44 +25,45 @@ fn expand_syntax_ext(&ext_ctxt cx,
2525
option::t[str] body) -> @ast::expr {
2626

2727
if (vec::len[@ast::expr](args) == 0u) {
28-
// FIXME: Handle error correctly.
29-
log_err "malformed #fmt call";
30-
fail;
28+
cx.span_err(sp, "#fmt requires a format string");
3129
}
3230

33-
auto fmt = expr_to_str(args.(0));
31+
auto fmt = expr_to_str(cx, args.(0));
3432

3533
// log "Format string:";
3634
// log fmt;
3735

3836
auto pieces = parse_fmt_string(fmt);
3937
auto args_len = vec::len[@ast::expr](args);
4038
auto fmt_args = vec::slice[@ast::expr](args, 1u, args_len - 1u);
41-
ret pieces_to_expr(p, pieces, args);
39+
ret pieces_to_expr(cx, p, sp, pieces, args);
4240
}
4341

44-
fn expr_to_str(@ast::expr expr) -> str {
42+
fn expr_to_str(&ext_ctxt cx, @ast::expr expr) -> str {
43+
auto err_msg = "first argument to #fmt must be a string literal";
4544
alt (expr.node) {
4645
case (ast::expr_lit(?l, _)) {
4746
alt (l.node) {
4847
case (ast::lit_str(?s)) {
4948
ret s;
5049
}
51-
case (_) { /* fallthrough */ }
50+
case (_) {
51+
cx.span_err(l.span, err_msg);
52+
}
5253
}
5354
}
54-
case (_) { /* fallthrough */ }
55+
case (_) {
56+
cx.span_err(expr.span, err_msg);
57+
}
5558
}
56-
log_err "first argument to #fmt must be a string literal";
57-
fail;
5859
}
5960

6061
// FIXME: A lot of these functions for producing expressions can probably
6162
// be factored out in common with other code that builds expressions.
6263
// FIXME: Probably should be using the parser's span functions
6364
// FIXME: Cleanup the naming of these functions
64-
fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
65-
-> @ast::expr {
65+
fn pieces_to_expr(&ext_ctxt cx, parser p, common::span sp,
66+
vec[piece] pieces, vec[@ast::expr] args) -> @ast::expr {
6667

6768
fn make_new_lit(parser p, common::span sp, ast::lit_ lit) -> @ast::expr {
6869
auto sp_lit = @rec(node=lit, span=sp);
@@ -263,7 +264,8 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
263264
ret make_call(p, arg.span, path, args);
264265
}
265266

266-
fn make_new_conv(parser p, conv cnv, @ast::expr arg) -> @ast::expr {
267+
fn make_new_conv(&ext_ctxt cx, parser p, common::span sp,
268+
conv cnv, @ast::expr arg) -> @ast::expr {
267269

268270
// FIXME: Extract all this validation into extfmt::ct
269271
fn is_signed_type(conv cnv) -> bool {
@@ -301,15 +303,14 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
301303
}
302304
case (flag_sign_always) {
303305
if (!is_signed_type(cnv)) {
304-
log_err "+ flag only valid in signed #fmt conversion";
305-
fail;
306+
cx.span_err(sp, "+ flag only valid in "
307+
+ "signed #fmt conversion");
306308
}
307309
}
308310
case (flag_space_for_sign) {
309311
if (!is_signed_type(cnv)) {
310-
log_err "space flag only valid in "
311-
+ "signed #fmt conversions";
312-
fail;
312+
cx.span_err(sp, "space flag only valid in "
313+
+ "signed #fmt conversions");
313314
}
314315
}
315316
case (flag_left_zero_pad) {
@@ -471,40 +472,41 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
471472
}
472473
}
473474

474-
auto sp = args.(0).span;
475+
auto fmt_sp = args.(0).span;
475476
auto n = 0u;
476477
auto tmp_expr = make_new_str(p, sp, "");
477478
auto nargs = vec::len[@ast::expr](args);
478479

479480
for (piece pc in pieces) {
480481
alt (pc) {
481482
case (piece_string(?s)) {
482-
auto s_expr = make_new_str(p, sp, s);
483-
tmp_expr = make_add_expr(p, sp, tmp_expr, s_expr);
483+
auto s_expr = make_new_str(p, fmt_sp, s);
484+
tmp_expr = make_add_expr(p, fmt_sp, tmp_expr, s_expr);
484485
}
485486
case (piece_conv(?conv)) {
487+
n += 1u;
488+
486489
if (n >= nargs) {
487-
log_err "too many conversions in #fmt string";
488-
fail;
490+
cx.span_err(sp, "not enough arguments to #fmt "
491+
+ "for the given format string");
489492
}
490493

491494
// TODO: Remove debug logging
492495
//log "Building conversion:";
493496
//log_conv(conv);
494497

495-
n += 1u;
496498
auto arg_expr = args.(n);
497-
auto c_expr = make_new_conv(p, conv, arg_expr);
498-
tmp_expr = make_add_expr(p, sp, tmp_expr, c_expr);
499+
auto c_expr = make_new_conv(cx, p, fmt_sp, conv, arg_expr);
500+
tmp_expr = make_add_expr(p, fmt_sp, tmp_expr, c_expr);
499501
}
500502
}
501503
}
502504

503505
auto expected_nargs = n + 1u; // n conversions + the fmt string
504506
if (expected_nargs < nargs) {
505-
log_err #fmt("too many arguments to #fmt. found %u, expected %u",
506-
nargs, expected_nargs);
507-
fail;
507+
cx.span_err(sp,
508+
#fmt("too many arguments to #fmt. found %u, expected %u",
509+
nargs, expected_nargs));
508510
}
509511

510512
// TODO: Remove this debug logging
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// xfail-stage0
2+
// error-pattern:format string
3+
4+
fn main() {
5+
#fmt();
6+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// xfail-stage0
2+
// error-pattern: literal
3+
4+
fn main() {
5+
// #fmt's first argument must be a literal. Hopefully this
6+
// restriction can be eased eventually to just require a
7+
// compile-time constant.
8+
auto x = #fmt(20);
9+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// xfail-stage0
2+
// error-pattern:not enough arguments
3+
4+
use std;
5+
6+
fn main() {
7+
auto s = #fmt("%s%s%s", "test", "test");
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// xfail-stage0
2+
// error-pattern:only valid in signed #fmt conversion
3+
4+
fn main() {
5+
// Can't use a sign on unsigned conversions
6+
#fmt("%+u", 10u);
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// xfail-stage0
2+
// error-pattern:only valid in signed #fmt conversion
3+
4+
fn main() {
5+
// Can't use a space on unsigned conversions
6+
#fmt("% u", 10u);
7+
}

0 commit comments

Comments
 (0)