diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs index 1856b81ce584e..c3d4fffcbab86 100644 --- a/src/comp/front/extfmt.rs +++ b/src/comp/front/extfmt.rs @@ -28,11 +28,17 @@ fn expand_syntax_ext(&ext_ctxt cx, } auto fmt = expr_to_str(cx, args.(0)); + auto fmtspan = args.(0).span; log "Format string:"; log fmt; - auto pieces = parse_fmt_string(fmt); + fn parse_fmt_err_(&ext_ctxt cx, common::span sp, str msg) -> ! { + cx.span_err(sp, msg); + } + + auto parse_fmt_err = bind parse_fmt_err_(cx, fmtspan, _); + auto pieces = parse_fmt_string(fmt, parse_fmt_err); auto args_len = vec::len[@ast::expr](args); auto fmt_args = vec::slice[@ast::expr](args, 1u, args_len - 1u); ret pieces_to_expr(cx, sp, pieces, args); diff --git a/src/lib/extfmt.rs b/src/lib/extfmt.rs index 2df831c0cab73..43ff490757b3d 100644 --- a/src/lib/extfmt.rs +++ b/src/lib/extfmt.rs @@ -78,7 +78,9 @@ mod ct { piece_conv(conv); } - fn parse_fmt_string(str s) -> vec[piece] { + type error_fn = fn (str) -> !; + + fn parse_fmt_string(str s, error_fn error) -> vec[piece] { let vec[piece] pieces = []; auto lim = str::byte_len(s); auto buf = ""; @@ -97,15 +99,14 @@ mod ct { if (str::eq(curr, "%")) { i += 1u; if (i >= lim) { - log_err "unterminated conversion at end of string"; - fail; + error("unterminated conversion at end of string"); } auto curr2 = str::substr(s, i, 1u); if (str::eq(curr2, "%")) { i += 1u; } else { buf = flush_buf(buf, pieces); - auto res = parse_conversion(s, i, lim); + auto res = parse_conversion(s, i, lim, error); pieces += [res._0]; i = res._1; } @@ -141,12 +142,13 @@ mod ct { }; } - fn parse_conversion(str s, uint i, uint lim) -> tup(piece, uint) { + fn parse_conversion(str s, uint i, uint lim, + error_fn error) -> tup(piece, uint) { auto parm = parse_parameter(s, i, lim); auto flags = parse_flags(s, parm._1, lim); auto width = parse_count(s, flags._1, lim); auto prec = parse_precision(s, width._1, lim); - auto ty = parse_type(s, prec._1, lim); + auto ty = parse_type(s, prec._1, lim, error); ret tup(piece_conv(rec(param = parm._0, flags = flags._0, width = width._0, @@ -258,10 +260,9 @@ mod ct { }; } - fn parse_type(str s, uint i, uint lim) -> tup(ty, uint) { + fn parse_type(str s, uint i, uint lim, error_fn error) -> tup(ty, uint) { if (i >= lim) { - log_err "missing type in conversion"; - fail; + error("missing type in conversion"); } auto tstr = str::substr(s, i, 1u); @@ -287,7 +288,8 @@ mod ct { } else if (str::eq(tstr, "o")) { ty_octal } else { - log_err "unknown type in conversion"; + // FIXME: Shouldn't need explicit fail here. Issue #542 + error("unknown type in conversion: " + tstr); fail }; diff --git a/src/test/compile-fail/extfmt-missing-type.rs b/src/test/compile-fail/extfmt-missing-type.rs new file mode 100644 index 0000000000000..8f82e3317e19e --- /dev/null +++ b/src/test/compile-fail/extfmt-missing-type.rs @@ -0,0 +1,5 @@ +// error-pattern:missing type + +fn main() { + #fmt("%+"); +} diff --git a/src/test/compile-fail/extfmt-unknown-type.rs b/src/test/compile-fail/extfmt-unknown-type.rs new file mode 100644 index 0000000000000..08d5da0a496a6 --- /dev/null +++ b/src/test/compile-fail/extfmt-unknown-type.rs @@ -0,0 +1,5 @@ +// error-pattern:unknown type + +fn main() { + #fmt("%w"); +} diff --git a/src/test/compile-fail/extfmt-unterminated-conv.rs b/src/test/compile-fail/extfmt-unterminated-conv.rs new file mode 100644 index 0000000000000..8c75c75f9fda4 --- /dev/null +++ b/src/test/compile-fail/extfmt-unterminated-conv.rs @@ -0,0 +1,5 @@ +// error-pattern:unterminated conversion + +fn main() { + #fmt("%"); +}