rust/src/libsyntax/ext/bytes.rs
Kevin Ballard b0647feab0 Limit spans in bytes!() error messages to the argument in question
This constrains the span to the appropriate argument, so you know which
one caused the problem. Instead of

  foo.rs:2:4: 2:21 error: Too large integer literal in bytes!
  foo.rs:2    bytes!(1, 256, 2)
              ^~~~~~~~~~~~~~~~~

it will say

  foo.rs:2:14 2:17 error: Too large integer literal in bytes!
  foo.rs:2    bytes!(1, 256, 2)
                        ^~~
2013-09-16 18:55:56 -07:00

75 lines
2.7 KiB
Rust

// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/* The compiler code necessary to support the bytes! extension. */
use ast;
use codemap::Span;
use ext::base::*;
use ext::base;
use ext::build::AstBuilder;
use std::char;
pub fn expand_syntax_ext(cx: @ExtCtxt, sp: Span, tts: &[ast::token_tree]) -> base::MacResult {
// Gather all argument expressions
let exprs = get_exprs_from_tts(cx, sp, tts);
let mut bytes = ~[];
for expr in exprs.iter() {
match expr.node {
// expression is a literal
ast::ExprLit(lit) => match lit.node {
// string literal, push each byte to vector expression
ast::lit_str(s) => {
for byte in s.byte_iter() {
bytes.push(cx.expr_u8(expr.span, byte));
}
}
// u8 literal, push to vector expression
ast::lit_uint(v, ast::ty_u8) => {
if v > 0xFF {
cx.span_err(expr.span, "Too large u8 literal in bytes!")
} else {
bytes.push(cx.expr_u8(expr.span, v as u8));
}
}
// integer literal, push to vector expression
ast::lit_int_unsuffixed(v) => {
if v > 0xFF {
cx.span_err(expr.span, "Too large integer literal in bytes!")
} else if v < 0 {
cx.span_err(expr.span, "Negative integer literal in bytes!")
} else {
bytes.push(cx.expr_u8(expr.span, v as u8));
}
}
// char literal, push to vector expression
ast::lit_char(v) => {
if char::from_u32(v).unwrap().is_ascii() {
bytes.push(cx.expr_u8(expr.span, v as u8));
} else {
cx.span_err(expr.span, "Non-ascii char literal in bytes!")
}
}
_ => cx.span_err(expr.span, "Unsupported literal in bytes!")
},
_ => cx.span_err(expr.span, "Non-literal in bytes!")
}
}
let e = cx.expr_vec_slice(sp, bytes);
MRExpr(e)
}