Fixes missing overflow lint for i64 #14269
The `type_overflow` lint, doesn't catch the overflow for `i64` because the overflow happens earlier in the parse phase when the `u64` as biggest possible int gets casted to `i64` , without checking the for overflows. We can't lint in the parse phase, so a refactoring of the `LitInt` type was necessary. The types `LitInt`, `LitUint` and `LitIntUnsuffixed` where merged to one type `LitInt` which stores it's value as `u64`. An additional parameter was added which indicate the signedness of the type and the sign of the value.
This commit is contained in:
parent
795f6ae829
commit
0dc215741b
src
libfourcc
librustc
librustdoc/clean
libsyntax
test
@ -124,7 +124,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
(val << 8) | (byte as u32)
|
||||
};
|
||||
}
|
||||
let e = cx.expr_lit(sp, ast::LitUint(val as u64, ast::TyU32));
|
||||
let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
|
||||
MacExpr::new(e)
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ impl LintPass for TypeLimits {
|
||||
match expr.node {
|
||||
ast::ExprLit(lit) => {
|
||||
match lit.node {
|
||||
ast::LitUint(..) => {
|
||||
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
|
||||
cx.span_lint(UNSIGNED_NEGATE, e.span,
|
||||
"negation of unsigned int literal may \
|
||||
be unintentional");
|
||||
@ -177,15 +177,25 @@ impl LintPass for TypeLimits {
|
||||
} else { t };
|
||||
let (min, max) = int_ty_range(int_type);
|
||||
let mut lit_val: i64 = match lit.node {
|
||||
ast::LitInt(v, _) => v,
|
||||
ast::LitUint(v, _) => v as i64,
|
||||
ast::LitIntUnsuffixed(v) => v,
|
||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
|
||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
|
||||
if v > i64::MAX as u64{
|
||||
cx.span_lint(TYPE_OVERFLOW, e.span,
|
||||
"literal out of range for its type");
|
||||
return;
|
||||
}
|
||||
v as i64
|
||||
}
|
||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
|
||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => {
|
||||
-(v as i64)
|
||||
}
|
||||
_ => fail!()
|
||||
};
|
||||
if self.negated_expr_id == e.id {
|
||||
lit_val *= -1;
|
||||
}
|
||||
if lit_val < min || lit_val > max {
|
||||
if lit_val < min || lit_val > max {
|
||||
cx.span_lint(TYPE_OVERFLOW, e.span,
|
||||
"literal out of range for its type");
|
||||
}
|
||||
@ -197,9 +207,7 @@ impl LintPass for TypeLimits {
|
||||
let (min, max) = uint_ty_range(uint_type);
|
||||
let lit_val: u64 = match lit.node {
|
||||
ast::LitByte(_v) => return, // _v is u8, within range by definition
|
||||
ast::LitInt(v, _) => v as u64,
|
||||
ast::LitUint(v, _) => v,
|
||||
ast::LitIntUnsuffixed(v) => v as u64,
|
||||
ast::LitInt(v, _) => v,
|
||||
_ => fail!()
|
||||
};
|
||||
if lit_val < min || lit_val > max {
|
||||
@ -294,9 +302,10 @@ impl LintPass for TypeLimits {
|
||||
let (min, max) = int_ty_range(int_ty);
|
||||
let lit_val: i64 = match lit.node {
|
||||
ast::ExprLit(li) => match li.node {
|
||||
ast::LitInt(v, _) => v,
|
||||
ast::LitUint(v, _) => v as i64,
|
||||
ast::LitIntUnsuffixed(v) => v,
|
||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
|
||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => v as i64,
|
||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
|
||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => -(v as i64),
|
||||
_ => return true
|
||||
},
|
||||
_ => fail!()
|
||||
@ -307,9 +316,7 @@ impl LintPass for TypeLimits {
|
||||
let (min, max): (u64, u64) = uint_ty_range(uint_ty);
|
||||
let lit_val: u64 = match lit.node {
|
||||
ast::ExprLit(li) => match li.node {
|
||||
ast::LitInt(v, _) => v as u64,
|
||||
ast::LitUint(v, _) => v,
|
||||
ast::LitIntUnsuffixed(v) => v as u64,
|
||||
ast::LitInt(v, _) => v,
|
||||
_ => return true
|
||||
},
|
||||
_ => fail!()
|
||||
|
@ -560,10 +560,13 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
|
||||
}
|
||||
LitByte(n) => const_uint(n as u64),
|
||||
LitChar(n) => const_uint(n as u64),
|
||||
LitInt(n, _) => const_int(n),
|
||||
LitUint(n, _) => const_uint(n),
|
||||
LitIntUnsuffixed(n) => const_int(n),
|
||||
LitFloat(ref n, _) | LitFloatUnsuffixed(ref n) => {
|
||||
LitInt(n, ast::SignedIntLit(_, ast::Plus)) |
|
||||
LitInt(n, ast::UnsuffixedIntLit(ast::Plus)) => const_int(n as i64),
|
||||
LitInt(n, ast::SignedIntLit(_, ast::Minus)) |
|
||||
LitInt(n, ast::UnsuffixedIntLit(ast::Minus)) => const_int(-(n as i64)),
|
||||
LitInt(n, ast::UnsignedIntLit(_)) => const_uint(n),
|
||||
LitFloat(ref n, _) |
|
||||
LitFloatUnsuffixed(ref n) => {
|
||||
const_float(from_str::<f64>(n.get()).unwrap() as f64)
|
||||
}
|
||||
LitNil => const_nil,
|
||||
|
@ -47,9 +47,13 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
|
||||
match lit.node {
|
||||
ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::TyU8), b as u64, false),
|
||||
ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
|
||||
ast::LitInt(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true),
|
||||
ast::LitUint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false),
|
||||
ast::LitIntUnsuffixed(i) => {
|
||||
ast::LitInt(i, ast::SignedIntLit(t, _)) => {
|
||||
C_integral(Type::int_from_ty(cx, t), i, true)
|
||||
}
|
||||
ast::LitInt(u, ast::UnsignedIntLit(t)) => {
|
||||
C_integral(Type::uint_from_ty(cx, t), u, false)
|
||||
}
|
||||
ast::LitInt(i, ast::UnsuffixedIntLit(_)) => {
|
||||
let lit_int_ty = ty::node_id_to_type(cx.tcx(), e.id);
|
||||
match ty::get(lit_int_ty).sty {
|
||||
ty::ty_int(t) => {
|
||||
|
@ -2057,9 +2057,9 @@ fn check_lit(fcx: &FnCtxt,
|
||||
}
|
||||
ast::LitByte(_) => ty::mk_u8(),
|
||||
ast::LitChar(_) => ty::mk_char(),
|
||||
ast::LitInt(_, t) => ty::mk_mach_int(t),
|
||||
ast::LitUint(_, t) => ty::mk_mach_uint(t),
|
||||
ast::LitIntUnsuffixed(_) => {
|
||||
ast::LitInt(_, ast::SignedIntLit(t, _)) => ty::mk_mach_int(t),
|
||||
ast::LitInt(_, ast::UnsignedIntLit(t)) => ty::mk_mach_uint(t),
|
||||
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
|
||||
let opt_ty = expected.map_to_option(fcx, |sty| {
|
||||
match *sty {
|
||||
ty::ty_int(i) => Some(ty::mk_mach_int(i)),
|
||||
|
@ -1947,8 +1947,6 @@ fn lit_to_string(lit: &ast::Lit) -> String {
|
||||
},
|
||||
ast::LitChar(c) => format!("'{}'", c),
|
||||
ast::LitInt(i, _t) => i.to_string(),
|
||||
ast::LitUint(u, _t) => u.to_string(),
|
||||
ast::LitIntUnsuffixed(i) => i.to_string(),
|
||||
ast::LitFloat(ref f, _t) => f.get().to_string(),
|
||||
ast::LitFloatUnsuffixed(ref f) => f.get().to_string(),
|
||||
ast::LitBool(b) => b.to_string(),
|
||||
|
@ -18,6 +18,7 @@ use parse::token::{InternedString, str_to_ident};
|
||||
use parse::token;
|
||||
|
||||
use std::fmt;
|
||||
use std::num::Zero;
|
||||
use std::fmt::Show;
|
||||
use std::option::Option;
|
||||
use std::rc::Rc;
|
||||
@ -656,15 +657,46 @@ pub enum StrStyle {
|
||||
|
||||
pub type Lit = Spanned<Lit_>;
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub enum Sign {
|
||||
Minus,
|
||||
Plus
|
||||
}
|
||||
|
||||
impl<T: PartialOrd+Zero> Sign {
|
||||
pub fn new(n: T) -> Sign {
|
||||
if n < Zero::zero() {
|
||||
Minus
|
||||
} else {
|
||||
Plus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub enum LitIntType {
|
||||
SignedIntLit(IntTy, Sign),
|
||||
UnsignedIntLit(UintTy),
|
||||
UnsuffixedIntLit(Sign)
|
||||
}
|
||||
|
||||
impl LitIntType {
|
||||
pub fn suffix_len(&self) -> uint {
|
||||
match *self {
|
||||
UnsuffixedIntLit(_) => 0,
|
||||
SignedIntLit(s, _) => s.suffix_len(),
|
||||
UnsignedIntLit(u) => u.suffix_len()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub enum Lit_ {
|
||||
LitStr(InternedString, StrStyle),
|
||||
LitBinary(Rc<Vec<u8> >),
|
||||
LitByte(u8),
|
||||
LitChar(char),
|
||||
LitInt(i64, IntTy),
|
||||
LitUint(u64, UintTy),
|
||||
LitIntUnsuffixed(i64),
|
||||
LitInt(u64, LitIntType),
|
||||
LitFloat(InternedString, FloatTy),
|
||||
LitFloatUnsuffixed(InternedString),
|
||||
LitNil,
|
||||
|
@ -626,13 +626,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
self.expr(sp, ast::ExprLit(box(GC) respan(sp, lit)))
|
||||
}
|
||||
fn expr_uint(&self, span: Span, i: uint) -> Gc<ast::Expr> {
|
||||
self.expr_lit(span, ast::LitUint(i as u64, ast::TyU))
|
||||
self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::TyU)))
|
||||
}
|
||||
fn expr_int(&self, sp: Span, i: int) -> Gc<ast::Expr> {
|
||||
self.expr_lit(sp, ast::LitInt(i as i64, ast::TyI))
|
||||
self.expr_lit(sp, ast::LitInt(i as u64, ast::SignedIntLit(ast::TyI, ast::Sign::new(i))))
|
||||
}
|
||||
fn expr_u8(&self, sp: Span, u: u8) -> Gc<ast::Expr> {
|
||||
self.expr_lit(sp, ast::LitUint(u as u64, ast::TyU8))
|
||||
self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::TyU8)))
|
||||
}
|
||||
fn expr_bool(&self, sp: Span, value: bool) -> Gc<ast::Expr> {
|
||||
self.expr_lit(sp, ast::LitBool(value))
|
||||
|
@ -47,7 +47,7 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
}
|
||||
|
||||
// u8 literal, push to vector expression
|
||||
ast::LitUint(v, ast::TyU8) => {
|
||||
ast::LitInt(v, ast::UnsignedIntLit(ast::TyU8)) => {
|
||||
if v > 0xFF {
|
||||
cx.span_err(expr.span, "too large u8 literal in bytes!");
|
||||
err = true;
|
||||
@ -57,13 +57,14 @@ pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||
}
|
||||
|
||||
// integer literal, push to vector expression
|
||||
ast::LitIntUnsuffixed(v) => {
|
||||
ast::LitInt(_, ast::UnsuffixedIntLit(ast::Minus)) => {
|
||||
cx.span_err(expr.span, "negative integer literal in bytes!");
|
||||
err = true;
|
||||
}
|
||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
|
||||
if v > 0xFF {
|
||||
cx.span_err(expr.span, "too large integer literal in bytes!");
|
||||
err = true;
|
||||
} else if v < 0 {
|
||||
cx.span_err(expr.span, "negative integer literal in bytes!");
|
||||
err = true;
|
||||
} else {
|
||||
bytes.push(cx.expr_u8(expr.span, v as u8));
|
||||
}
|
||||
|
@ -37,11 +37,14 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
|
||||
ast::LitChar(c) => {
|
||||
accumulator.push_char(c);
|
||||
}
|
||||
ast::LitInt(i, _) | ast::LitIntUnsuffixed(i) => {
|
||||
ast::LitInt(i, ast::UnsignedIntLit(_)) |
|
||||
ast::LitInt(i, ast::SignedIntLit(_, ast::Plus)) |
|
||||
ast::LitInt(i, ast::UnsuffixedIntLit(ast::Plus)) => {
|
||||
accumulator.push_str(format!("{}", i).as_slice());
|
||||
}
|
||||
ast::LitUint(u, _) => {
|
||||
accumulator.push_str(format!("{}", u).as_slice());
|
||||
ast::LitInt(i, ast::SignedIntLit(_, ast::Minus)) |
|
||||
ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => {
|
||||
accumulator.push_str(format!("-{}", i).as_slice());
|
||||
}
|
||||
ast::LitNil => {}
|
||||
ast::LitBool(b) => {
|
||||
|
@ -996,7 +996,7 @@ impl<'a> MethodDef<'a> {
|
||||
let arms : Vec<ast::Arm> = variants.iter().enumerate()
|
||||
.map(|(index, &variant)| {
|
||||
let pat = variant_to_pat(cx, sp, &*variant);
|
||||
let lit = ast::LitUint(index as u64, ast::TyU);
|
||||
let lit = ast::LitInt(index as u64, ast::UnsignedIntLit(ast::TyU));
|
||||
cx.arm(sp, vec![pat], cx.expr_lit(sp, lit))
|
||||
}).collect();
|
||||
|
||||
|
@ -189,16 +189,17 @@ pub mod rt {
|
||||
(signed, $t:ty, $tag:ident) => (
|
||||
impl ToSource for $t {
|
||||
fn to_source(&self) -> String {
|
||||
let lit = dummy_spanned(ast::LitInt(*self as i64, ast::$tag));
|
||||
pprust::lit_to_string(&lit)
|
||||
let lit = ast::LitInt(*self as u64, ast::SignedIntLit(ast::$tag,
|
||||
ast::Sign::new(*self)));
|
||||
pprust::lit_to_string(&dummy_spanned(lit))
|
||||
}
|
||||
}
|
||||
);
|
||||
(unsigned, $t:ty, $tag:ident) => (
|
||||
impl ToSource for $t {
|
||||
fn to_source(&self) -> String {
|
||||
let lit = dummy_spanned(ast::LitUint(*self as u64, ast::$tag));
|
||||
pprust::lit_to_string(&lit)
|
||||
let lit = ast::LitInt(*self as u64, ast::UnsignedIntLit(ast::$tag));
|
||||
pprust::lit_to_string(&dummy_spanned(lit))
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -515,31 +515,13 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
|
||||
debug!("parse_integer_lit: {}", s);
|
||||
|
||||
if s.len() == 1 {
|
||||
return ast::LitIntUnsuffixed((s.char_at(0)).to_digit(10).unwrap() as i64);
|
||||
let n = (s.char_at(0)).to_digit(10).unwrap();
|
||||
return ast::LitInt(n as u64, ast::UnsuffixedIntLit(ast::Sign::new(n)));
|
||||
}
|
||||
|
||||
let mut base = 10;
|
||||
let orig = s;
|
||||
|
||||
#[deriving(Show)]
|
||||
enum Result {
|
||||
Nothing,
|
||||
Signed(ast::IntTy),
|
||||
Unsigned(ast::UintTy)
|
||||
}
|
||||
|
||||
impl Result {
|
||||
fn suffix_len(&self) -> uint {
|
||||
match *self {
|
||||
Nothing => 0,
|
||||
Signed(s) => s.suffix_len(),
|
||||
Unsigned(u) => u.suffix_len()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ty = Nothing;
|
||||
|
||||
let mut ty = ast::UnsuffixedIntLit(ast::Plus);
|
||||
|
||||
if s.char_at(0) == '0' {
|
||||
match s.char_at(1) {
|
||||
@ -556,13 +538,13 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
|
||||
|
||||
let last = s.len() - 1;
|
||||
match s.char_at(last) {
|
||||
'i' => ty = Signed(ast::TyI),
|
||||
'u' => ty = Unsigned(ast::TyU),
|
||||
'i' => ty = ast::SignedIntLit(ast::TyI, ast::Plus),
|
||||
'u' => ty = ast::UnsignedIntLit(ast::TyU),
|
||||
'8' => {
|
||||
if s.len() > 2 {
|
||||
match s.char_at(last - 1) {
|
||||
'i' => ty = Signed(ast::TyI8),
|
||||
'u' => ty = Unsigned(ast::TyU8),
|
||||
'i' => ty = ast::SignedIntLit(ast::TyI8, ast::Plus),
|
||||
'u' => ty = ast::UnsignedIntLit(ast::TyU8),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
@ -570,8 +552,8 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
|
||||
'6' => {
|
||||
if s.len() > 3 && s.char_at(last - 1) == '1' {
|
||||
match s.char_at(last - 2) {
|
||||
'i' => ty = Signed(ast::TyI16),
|
||||
'u' => ty = Unsigned(ast::TyU16),
|
||||
'i' => ty = ast::SignedIntLit(ast::TyI16, ast::Plus),
|
||||
'u' => ty = ast::UnsignedIntLit(ast::TyU16),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
@ -579,8 +561,8 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
|
||||
'2' => {
|
||||
if s.len() > 3 && s.char_at(last - 1) == '3' {
|
||||
match s.char_at(last - 2) {
|
||||
'i' => ty = Signed(ast::TyI32),
|
||||
'u' => ty = Unsigned(ast::TyU32),
|
||||
'i' => ty = ast::SignedIntLit(ast::TyI32, ast::Plus),
|
||||
'u' => ty = ast::UnsignedIntLit(ast::TyU32),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
@ -588,8 +570,8 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
|
||||
'4' => {
|
||||
if s.len() > 3 && s.char_at(last - 1) == '6' {
|
||||
match s.char_at(last - 2) {
|
||||
'i' => ty = Signed(ast::TyI64),
|
||||
'u' => ty = Unsigned(ast::TyU64),
|
||||
'i' => ty = ast::SignedIntLit(ast::TyI64, ast::Plus),
|
||||
'u' => ty = ast::UnsignedIntLit(ast::TyU64),
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
@ -597,21 +579,22 @@ pub fn integer_lit(s: &str, sd: &SpanHandler, sp: Span) -> ast::Lit_ {
|
||||
_ => { }
|
||||
}
|
||||
|
||||
|
||||
s = s.slice_to(s.len() - ty.suffix_len());
|
||||
|
||||
debug!("The suffix is {}, base {}, the new string is {}, the original \
|
||||
string was {}", ty, base, s, orig);
|
||||
|
||||
s = s.slice_to(s.len() - ty.suffix_len());
|
||||
|
||||
let res: u64 = match ::std::num::from_str_radix(s, base) {
|
||||
Some(r) => r,
|
||||
None => { sd.span_err(sp, "int literal is too large"); 0 }
|
||||
};
|
||||
|
||||
// adjust the sign
|
||||
let sign = ast::Sign::new(res);
|
||||
match ty {
|
||||
Nothing => ast::LitIntUnsuffixed(res as i64),
|
||||
Signed(t) => ast::LitInt(res as i64, t),
|
||||
Unsigned(t) => ast::LitUint(res, t)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ use ast::{Ident, NormalFn, Inherited, Item, Item_, ItemStatic};
|
||||
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl};
|
||||
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, Lit, Lit_};
|
||||
use ast::{LitBool, LitChar, LitByte, LitBinary};
|
||||
use ast::{LitNil, LitStr, LitUint, Local, LocalLet};
|
||||
use ast::{LitNil, LitStr, LitInt, Local, LocalLet};
|
||||
use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, Matcher, MatchNonterminal};
|
||||
use ast::{MatchSeq, MatchTok, Method, MutTy, BiMul, Mutability};
|
||||
use ast::{NamedField, UnNeg, NoReturn, UnNot, P, Pat, PatEnum};
|
||||
@ -1889,7 +1889,7 @@ impl<'a> Parser<'a> {
|
||||
pub fn mk_lit_u32(&mut self, i: u32) -> Gc<Expr> {
|
||||
let span = &self.span;
|
||||
let lv_lit = box(GC) codemap::Spanned {
|
||||
node: LitUint(i as u64, TyU32),
|
||||
node: LitInt(i as u64, ast::UnsignedIntLit(TyU32)),
|
||||
span: *span
|
||||
};
|
||||
|
||||
|
@ -2415,15 +2415,25 @@ impl<'a> State<'a> {
|
||||
word(&mut self.s, res.as_slice())
|
||||
}
|
||||
ast::LitInt(i, t) => {
|
||||
word(&mut self.s,
|
||||
ast_util::int_ty_to_string(t, Some(i)).as_slice())
|
||||
}
|
||||
ast::LitUint(u, t) => {
|
||||
word(&mut self.s,
|
||||
ast_util::uint_ty_to_string(t, Some(u)).as_slice())
|
||||
}
|
||||
ast::LitIntUnsuffixed(i) => {
|
||||
word(&mut self.s, format!("{}", i).as_slice())
|
||||
match t {
|
||||
ast::SignedIntLit(st, ast::Plus) => {
|
||||
word(&mut self.s,
|
||||
ast_util::int_ty_to_string(st, Some(i as i64)).as_slice())
|
||||
}
|
||||
ast::SignedIntLit(st, ast::Minus) => {
|
||||
word(&mut self.s,
|
||||
ast_util::int_ty_to_string(st, Some(-(i as i64))).as_slice())
|
||||
}
|
||||
ast::UnsignedIntLit(ut) => {
|
||||
word(&mut self.s, ast_util::uint_ty_to_string(ut, Some(i)).as_slice())
|
||||
}
|
||||
ast::UnsuffixedIntLit(ast::Plus) => {
|
||||
word(&mut self.s, format!("{}", i).as_slice())
|
||||
}
|
||||
ast::UnsuffixedIntLit(ast::Minus) => {
|
||||
word(&mut self.s, format!("-{}", i).as_slice())
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::LitFloat(ref f, t) => {
|
||||
word(&mut self.s,
|
||||
|
@ -48,6 +48,9 @@ fn main() {
|
||||
let x: i32 = -2147483649; //~ error: literal out of range for its type
|
||||
let x = -2147483649_i32; //~ error: literal out of range for its type
|
||||
|
||||
let x = 9223372036854775808_i64; //~ error: literal out of range for its type
|
||||
let x = 18446744073709551615_i64; //~ error: literal out of range for its type
|
||||
|
||||
let x = -3.40282348e+38_f32; //~ error: literal out of range for its type
|
||||
let x = 3.40282348e+38_f32; //~ error: literal out of range for its type
|
||||
let x = -1.7976931348623159e+308_f64; //~ error: literal out of range for its type
|
||||
|
@ -8,6 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -D type-overflow
|
||||
|
||||
fn main() { println!("{}", 300u8); } //~ error: literal out of range for its type
|
||||
fn main() {
|
||||
println!("{}", 18446744073709551616u64); //~ error: int literal is too large
|
||||
}
|
||||
|
@ -15,6 +15,4 @@ pub fn main() {
|
||||
assert_eq!(18446744073709551615u64, (-1 as u64));
|
||||
|
||||
assert_eq!(-2147483648i32 - 1i32, 2147483647i32);
|
||||
assert_eq!(-9223372036854775808i64 - 1i64, 9223372036854775807i64);
|
||||
assert_eq!(-9223372036854775808i - 1, 9223372036854775807);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user