[breaking-change] remove the sign from integer literals in the ast

This commit is contained in:
Oliver Schneider
2016-02-11 09:52:55 +01:00
parent 625e78b700
commit bfa66bb389
10 changed files with 55 additions and 82 deletions

View File

@@ -21,7 +21,6 @@ pub use self::Mutability::*;
pub use self::Pat_::*;
pub use self::PathListItem_::*;
pub use self::PrimTy::*;
pub use self::Sign::*;
pub use self::Stmt_::*;
pub use self::StrStyle::*;
pub use self::StructFieldKind::*;
@@ -1269,36 +1268,11 @@ pub enum StrStyle {
/// A literal
pub type Lit = Spanned<Lit_>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum Sign {
Minus,
Plus
}
impl Sign {
pub fn new<T: IntSign>(n: T) -> Sign {
n.sign()
}
}
pub trait IntSign {
fn sign(&self) -> Sign;
}
macro_rules! doit {
($($t:ident)*) => ($(impl IntSign for $t {
#[allow(unused_comparisons)]
fn sign(&self) -> Sign {
if *self < 0 {Minus} else {Plus}
}
})*)
}
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum LitIntType {
SignedIntLit(IntTy, Sign),
SignedIntLit(IntTy),
UnsignedIntLit(UintTy),
UnsuffixedIntLit(Sign)
UnsuffixedIntLit,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]

View File

@@ -683,8 +683,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::UintTy::Us)))
}
fn expr_isize(&self, sp: Span, i: isize) -> P<ast::Expr> {
self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::IntTy::Is,
ast::Sign::new(i))))
if i < 0 {
let i = (-i) as u64;
let lit = self.expr_lit(sp, ast::LitInt(i, ast::SignedIntLit(ast::IntTy::Is)));
self.expr_unary(sp, ast::UnOp::Neg, lit)
} else {
self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::IntTy::Is)))
}
}
fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> {
self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::UintTy::U32)))

View File

@@ -263,9 +263,27 @@ pub mod rt {
(signed, $t:ty, $tag:expr) => (
impl ToTokens for $t {
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
let lit = ast::LitInt(*self as u64, ast::SignedIntLit($tag,
ast::Sign::new(*self)));
dummy_spanned(lit).to_tokens(cx)
let val = if *self < 0 {
-self
} else {
*self
};
let lit = ast::LitInt(val as u64, ast::SignedIntLit($tag));
let lit = P(ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Lit(P(dummy_spanned(lit))),
span: DUMMY_SP,
attrs: None,
});
if *self >= 0 {
return lit.to_tokens(cx);
}
P(ast::Expr {
id: ast::DUMMY_NODE_ID,
node: ast::ExprKind::Unary(ast::UnOp::Neg, lit),
span: DUMMY_SP,
attrs: None,
}).to_tokens(cx)
}
}
);

View File

@@ -586,7 +586,7 @@ pub fn integer_lit(s: &str,
let mut base = 10;
let orig = s;
let mut ty = ast::UnsuffixedIntLit(ast::Plus);
let mut ty = ast::UnsuffixedIntLit;
if char_at(s, 0) == '0' && s.len() > 1 {
match char_at(s, 1) {
@@ -618,11 +618,11 @@ pub fn integer_lit(s: &str,
if let Some(ref suf) = suffix {
if suf.is_empty() { sd.span_bug(sp, "found empty literal suffix in Some")}
ty = match &**suf {
"isize" => ast::SignedIntLit(ast::IntTy::Is, ast::Plus),
"i8" => ast::SignedIntLit(ast::IntTy::I8, ast::Plus),
"i16" => ast::SignedIntLit(ast::IntTy::I16, ast::Plus),
"i32" => ast::SignedIntLit(ast::IntTy::I32, ast::Plus),
"i64" => ast::SignedIntLit(ast::IntTy::I64, ast::Plus),
"isize" => ast::SignedIntLit(ast::IntTy::Is),
"i8" => ast::SignedIntLit(ast::IntTy::I8),
"i16" => ast::SignedIntLit(ast::IntTy::I16),
"i32" => ast::SignedIntLit(ast::IntTy::I32),
"i64" => ast::SignedIntLit(ast::IntTy::I64),
"usize" => ast::UnsignedIntLit(ast::UintTy::Us),
"u8" => ast::UnsignedIntLit(ast::UintTy::U8),
"u16" => ast::UnsignedIntLit(ast::UintTy::U16),
@@ -651,9 +651,9 @@ pub fn integer_lit(s: &str,
debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \
string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix);
let res = match u64::from_str_radix(s, base).ok() {
Some(r) => r,
None => {
match u64::from_str_radix(s, base) {
Ok(r) => ast::LitInt(r, ty),
Err(_) => {
// small bases are lexed as if they were base 10, e.g, the string
// might be `0b10201`. This will cause the conversion above to fail,
// but these cases have errors in the lexer: we don't want to emit
@@ -665,16 +665,8 @@ pub fn integer_lit(s: &str,
if !already_errored {
sd.span_err(sp, "int literal is too large");
}
0
ast::LitInt(0, ty)
}
};
// adjust the sign
let sign = ast::Sign::new(res);
match ty {
ast::SignedIntLit(t, _) => ast::LitInt(res, ast::SignedIntLit(t, sign)),
ast::UnsuffixedIntLit(_) => ast::LitInt(res, ast::UnsuffixedIntLit(sign)),
us@ast::UnsignedIntLit(_) => ast::LitInt(res, us)
}
}

View File

@@ -645,24 +645,16 @@ pub trait PrintState<'a> {
}
ast::LitInt(i, t) => {
match t {
ast::SignedIntLit(st, ast::Plus) => {
ast::SignedIntLit(st) => {
word(self.writer(),
&st.val_to_string(i as i64))
}
ast::SignedIntLit(st, ast::Minus) => {
let istr = st.val_to_string(-(i as i64));
word(self.writer(),
&format!("-{}", istr))
}
ast::UnsignedIntLit(ut) => {
word(self.writer(), &ut.val_to_string(i))
}
ast::UnsuffixedIntLit(ast::Plus) => {
ast::UnsuffixedIntLit => {
word(self.writer(), &format!("{}", i))
}
ast::UnsuffixedIntLit(ast::Minus) => {
word(self.writer(), &format!("-{}", i))
}
}
}
ast::LitFloat(ref f, t) => {