syntax: Fix printing INT64_MIN

Integers are always parsed as a u64 in libsyntax, but they're stored as i64. The
parser and pretty printer both printed an i64 instead of u64, sometimes
introducing an extra negative sign.
This commit is contained in:
Alex Crichton 2014-05-10 20:16:51 -07:00
parent 1237530452
commit 042c8ae40e
6 changed files with 39 additions and 25 deletions

View File

@ -355,18 +355,14 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> StrBuf {
ty_bot => "!".to_strbuf(),
ty_bool => "bool".to_strbuf(),
ty_char => "char".to_strbuf(),
ty_int(t) => ast_util::int_ty_to_str(t, None),
ty_uint(t) => ast_util::uint_ty_to_str(t, None),
ty_float(t) => ast_util::float_ty_to_str(t),
ty_box(typ) => {
("@".to_owned() + ty_to_str(cx, typ).as_slice()).to_strbuf()
}
ty_uniq(typ) => {
("~".to_owned() + ty_to_str(cx, typ).as_slice()).to_strbuf()
}
ty_ptr(ref tm) => {
("*".to_owned() + mt_to_str(cx, tm).as_slice()).to_strbuf()
}
ty_int(t) => ast_util::int_ty_to_str(t, None,
ast_util::AutoSuffix).to_strbuf(),
ty_uint(t) => ast_util::uint_ty_to_str(t, None,
ast_util::AutoSuffix).to_strbuf(),
ty_float(t) => ast_util::float_ty_to_str(t).to_strbuf(),
ty_box(typ) => "@".to_strbuf() + ty_to_str(cx, typ),
ty_uniq(typ) => "~".to_strbuf() + ty_to_str(cx, typ),
ty_ptr(ref tm) => "*".to_strbuf() + mt_to_str(cx, tm),
ty_rptr(r, ref tm) => {
let mut buf = region_ptr_to_str(cx, r);
buf.push_str(mt_to_str(cx, tm).as_slice());
@ -374,7 +370,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> StrBuf {
}
ty_tup(ref elems) => {
let strs: Vec<StrBuf> = elems.iter().map(|elem| ty_to_str(cx, *elem)).collect();
("(".to_owned() + strs.connect(",") + ")").to_strbuf()
("(".to_strbuf() + strs.connect(",") + ")").to_strbuf()
}
ty_closure(ref f) => {
closure_to_str(cx, *f)

View File

@ -711,7 +711,8 @@ pub enum IntTy {
impl fmt::Show for IntTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "{}", ast_util::int_ty_to_str(*self, None))
write!(f.buf, "{}",
ast_util::int_ty_to_str(*self, None, ast_util::AutoSuffix))
}
}
@ -726,7 +727,8 @@ pub enum UintTy {
impl fmt::Show for UintTy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f.buf, "{}", ast_util::uint_ty_to_str(*self, None))
write!(f.buf, "{}",
ast_util::uint_ty_to_str(*self, None, ast_util::AutoSuffix))
}
}

View File

@ -132,11 +132,19 @@ pub fn is_path(e: @Expr) -> bool {
return match e.node { ExprPath(_) => true, _ => false };
}
pub enum SuffixMode {
ForceSuffix,
AutoSuffix,
}
// Get a string representation of a signed int type, with its value.
// We want to avoid "45int" and "-3int" in favor of "45" and "-3"
pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> StrBuf {
pub fn int_ty_to_str(t: IntTy, val: Option<i64>, mode: SuffixMode) -> StrBuf {
let s = match t {
TyI if val.is_some() => "",
TyI if val.is_some() => match mode {
AutoSuffix => "",
ForceSuffix => "i",
},
TyI => "int",
TyI8 => "i8",
TyI16 => "i16",
@ -145,7 +153,7 @@ pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> StrBuf {
};
match val {
Some(n) => format!("{}{}", n, s).to_strbuf(),
Some(n) => format!("{}{}", n as u64, s).to_strbuf(),
None => s.to_strbuf()
}
}
@ -161,9 +169,12 @@ pub fn int_ty_max(t: IntTy) -> u64 {
// Get a string representation of an unsigned int type, with its value.
// We want to avoid "42uint" in favor of "42u"
pub fn uint_ty_to_str(t: UintTy, val: Option<u64>) -> StrBuf {
pub fn uint_ty_to_str(t: UintTy, val: Option<u64>, mode: SuffixMode) -> StrBuf {
let s = match t {
TyU if val.is_some() => "u",
TyU if val.is_some() => match mode {
AutoSuffix => "",
ForceSuffix => "u",
},
TyU => "uint",
TyU8 => "u8",
TyU16 => "u16",

View File

@ -203,9 +203,11 @@ pub fn to_str(t: &Token) -> StrBuf {
res.push_char('\'');
res
}
LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i)),
LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u)),
LIT_INT_UNSUFFIXED(i) => { i.to_str().to_strbuf() }
LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i),
ast_util::ForceSuffix),
LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u),
ast_util::ForceSuffix),
LIT_INT_UNSUFFIXED(i) => { (i as u64).to_str().to_strbuf() }
LIT_FLOAT(s, t) => {
let mut body = StrBuf::from_str(get_ident(s).get());
if body.as_slice().ends_with(".") {

View File

@ -2232,11 +2232,13 @@ impl<'a> State<'a> {
}
ast::LitInt(i, t) => {
word(&mut self.s,
ast_util::int_ty_to_str(t, Some(i)).as_slice())
ast_util::int_ty_to_str(t, Some(i),
ast_util::AutoSuffix).as_slice())
}
ast::LitUint(u, t) => {
word(&mut self.s,
ast_util::uint_ty_to_str(t, Some(u)).as_slice())
ast_util::uint_ty_to_str(t, Some(u),
ast_util::AutoSuffix).as_slice())
}
ast::LitIntUnsuffixed(i) => {
word(&mut self.s, format!("{}", i))

View File

@ -16,4 +16,5 @@ pub fn main() {
assert_eq!(-2147483648i32 - 1i32, 2147483647i32);
assert_eq!(-9223372036854775808i64 - 1i64, 9223372036854775807i64);
assert_eq!(-9223372036854775808 - 1, 9223372036854775807);
}