diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ab458931b0c..536ce3c294e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -402,6 +402,7 @@ enum lit_ { lit_str(str), lit_int(i64, int_ty), lit_uint(u64, uint_ty), + lit_int_unsuffixed(i64, int_ty), lit_float(str, float_ty), lit_nil, lit_bool(bool), diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 471fe15788d..aff0334a946 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -51,7 +51,14 @@ fn need_parens(expr: @ast::expr, outer_prec: uint) -> bool { fn ends_in_lit_int(ex: @ast::expr) -> bool { alt ex.node { - ast::expr_lit(@{node: ast::lit_int(_, ast::ty_i), _}) { true } + ast::expr_lit(node) { + alt node { + @{node: ast::lit_int(_, ast::ty_i), _} | + @{node: ast::lit_int_unsuffixed(_, ast::ty_i), _} + { true } + _ { false } + } + } ast::expr_binary(_, _, sub) | ast::expr_unary(_, sub) | ast::expr_move(_, sub) | ast::expr_copy(sub) | ast::expr_assign(_, sub) | diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index c93680b40a0..115a9957c28 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -282,7 +282,10 @@ fn scan_number(c: char, rdr: reader) -> token::token { rdr.fatal("no valid digits found for number"); } let parsed = option::get(u64::from_str_radix(num_str, base as u64)); - ret token::LIT_INT(parsed as i64, ast::ty_i); + + #debug["lexing %s as an unsuffixed integer literal", + num_str]; + ret token::LIT_INT_UNSUFFIXED(parsed as i64, ast::ty_i); } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 75dae09fd0d..7e6fb726f67 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -507,7 +507,7 @@ class parser { let lo = self.span.lo; self.bump(); alt copy self.token { - token::LIT_INT(num, ty_i) { + token::LIT_INT_UNSUFFIXED(num, _) { self.bump(); some(mac_var(num as uint)) } @@ -519,7 +519,7 @@ class parser { some(mac_aq(mk_sp(lo,hi), e)) } _ { - self.fatal("expected `(` or integer literal"); + self.fatal("expected `(` or unsuffixed integer literal"); } } } @@ -540,7 +540,7 @@ class parser { token::UNDERSCORE { self.bump(); some(vstore_fixed(none)) } - token::LIT_INT(i, ty_i) if i >= 0i64 { + token::LIT_INT_UNSUFFIXED(i, _) if i >= 0i64 { self.bump(); some(vstore_fixed(some(i as uint))) } token::BINOP(token::AND) { @@ -559,6 +559,7 @@ class parser { alt tok { token::LIT_INT(i, it) { lit_int(i, it) } token::LIT_UINT(u, ut) { lit_uint(u, ut) } + token::LIT_INT_UNSUFFIXED(i, it) { lit_int_unsuffixed(i, it) } token::LIT_FLOAT(s, ft) { lit_float(self.get_str(s), ft) } token::LIT_STR(s) { lit_str(self.get_str(s)) } token::LPAREN { self.expect(token::RPAREN); lit_nil } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index ca11dfa1f9b..989699ab247 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -58,6 +58,7 @@ enum token { /* Literals */ LIT_INT(i64, ast::int_ty), LIT_UINT(u64, ast::uint_ty), + LIT_INT_UNSUFFIXED(i64, ast::int_ty), LIT_FLOAT(str_num, ast::float_ty), LIT_STR(str_num), @@ -132,6 +133,9 @@ fn to_str(in: interner<@str>, t: token) -> str { LIT_UINT(u, t) { ret uint::to_str(u as uint, 10u) + ast_util::uint_ty_to_str(t); } + LIT_INT_UNSUFFIXED(i, t) { + ret int::to_str(i as int, 10u) + ast_util::int_ty_to_str(t); + } LIT_FLOAT(s, t) { ret *interner::get(in, s) + ast_util::float_ty_to_str(t); @@ -161,6 +165,7 @@ pure fn can_begin_expr(t: token) -> bool { TILDE { true } LIT_INT(_, _) { true } LIT_UINT(_, _) { true } + LIT_INT_UNSUFFIXED(_, _) { true } LIT_FLOAT(_, _) { true } LIT_STR(_) { true } POUND { true } @@ -178,6 +183,7 @@ fn is_lit(t: token::token) -> bool { ret alt t { token::LIT_INT(_, _) { true } token::LIT_UINT(_, _) { true } + token::LIT_INT_UNSUFFIXED(_, _) { true } token::LIT_FLOAT(_, _) { true } token::LIT_STR(_) { true } _ { false } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d4e66137d67..97135a7bb75 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1628,6 +1628,17 @@ fn print_literal(s: ps, &&lit: @ast::lit) { u64::to_str(u, 10u) + ast_util::uint_ty_to_str(t)); } + ast::lit_int_unsuffixed(i, t) { + if i < 0_i64 { + word(s.s, + "-" + u64::to_str(-i as u64, 10u) + + ast_util::int_ty_to_str(t)); + } else { + word(s.s, + u64::to_str(i as u64, 10u) + + ast_util::int_ty_to_str(t)); + } + } ast::lit_float(f, t) { word(s.s, f + ast_util::float_ty_to_str(t)); } diff --git a/src/rustc/middle/const_eval.rs b/src/rustc/middle/const_eval.rs index 3fb75900faf..d0e4b715988 100644 --- a/src/rustc/middle/const_eval.rs +++ b/src/rustc/middle/const_eval.rs @@ -111,6 +111,7 @@ fn lit_to_const(lit: @lit) -> const_val { lit_str(s) { const_str(s) } lit_int(n, _) { const_int(n) } lit_uint(n, _) { const_uint(n) } + lit_int_unsuffixed(n, _) { const_int(n) } lit_float(n, _) { const_float(option::get(float::from_str(n)) as f64) } lit_nil { const_int(0i64) } lit_bool(b) { const_int(b as i64) } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index a6806d97559..07216030767 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1483,6 +1483,11 @@ fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef { alt lit.node { ast::lit_int(i, t) { C_integral(T_int_ty(cx, t), i as u64, True) } ast::lit_uint(u, t) { C_integral(T_uint_ty(cx, t), u, False) } + ast::lit_int_unsuffixed(i, t) { + // FIXME (#1425): should we be using cx.fcx.infcx to figure out what + // to actually generate from this? + C_integral(T_int_ty(cx, t), i as u64, True) + } ast::lit_float(fs, t) { C_floating(fs, T_float_ty(cx, t)) } ast::lit_bool(b) { C_bool(b) } ast::lit_nil { C_nil() } diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 50123559f02..bc7f46703e0 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -629,40 +629,32 @@ fn check_lit(fcx: @fn_ctxt, lit: @ast::lit) -> ty::t { alt lit.node { ast::lit_str(_) { ty::mk_str(tcx) } - ast::lit_int(v, t) { - alt t { - ty_char | ty_i8 | ty_i16 | ty_i32 | ty_i64 { - // If it's a char or has an explicit suffix, give it the - // appropriate integral type. - ty::mk_mach_int(tcx, t) - } - ty_i { - // Otherwise, an unsuffixed integer literal parses to a - // `ty_i`. In that case, it could have any integral type, - // so create an integral type variable for it. - let vid = fcx.infcx.next_ty_var_integral_id(); - - // We need to sniff at the value `v` provided and figure - // out how big of an int it is; that determines the set of - // possibly types it could take on. - let possible_types = alt v { - 0i64 to 127i64 { min_8bit_tys() } - 128i64 to 65535i64 { min_16bit_tys() } - 65536i64 to 4294967295i64 { min_32bit_tys() } - _ { min_64bit_tys() } - }; - - // Store the set of possible types - fcx.infcx.set(fcx.infcx.tvib, vid, - root(possible_types)); - ty::mk_var_integral(tcx, vid); - - // FIXME: remove me when #1425 is finished. - ty::mk_mach_int(tcx, t) - } - } - } + ast::lit_int(_, t) { ty::mk_mach_int(tcx, t) } ast::lit_uint(_, t) { ty::mk_mach_uint(tcx, t) } + ast::lit_int_unsuffixed(v, t) { + // An unsuffixed integer literal could have any integral type, + // so we create an integral type variable for it. + let vid = fcx.infcx.next_ty_var_integral_id(); + + // We need to sniff at the value `v` and figure out how big of + // an int it is; that determines the range of possible types + // that the integral type variable could take on. + let possible_types = alt v { + 0i64 to 127i64 { min_8bit_tys() } + 128i64 to 65535i64 { min_16bit_tys() } + 65536i64 to 4294967295i64 { min_32bit_tys() } + _ { min_64bit_tys() } + }; + + // Store the set of possible types and return the integral + // type variable. + fcx.infcx.set(fcx.infcx.tvib, vid, + root(possible_types)); + ty::mk_var_integral(tcx, vid); + + // FIXME: remove me when #1425 is finished. + ty::mk_mach_int(tcx, t) + } ast::lit_float(_, t) { ty::mk_mach_float(tcx, t) } ast::lit_nil { ty::mk_nil(tcx) } ast::lit_bool(_) { ty::mk_bool(tcx) }