[breaking-change] remove the sign from integer literals in the ast
This commit is contained in:
parent
625e78b700
commit
bfa66bb389
10 changed files with 55 additions and 82 deletions
|
@ -1328,15 +1328,13 @@ fn lit_to_const(sess: &Session, span: Span, lit: &ast::Lit, ty_hint: Option<Ty>)
|
||||||
}
|
}
|
||||||
ast::LitByte(n) => Uint(n as u64),
|
ast::LitByte(n) => Uint(n as u64),
|
||||||
ast::LitChar(n) => Uint(n as u64),
|
ast::LitChar(n) => Uint(n as u64),
|
||||||
ast::LitInt(n, ast::SignedIntLit(_, ast::Plus)) => Int(n as i64),
|
ast::LitInt(n, ast::SignedIntLit(_)) => Int(n as i64),
|
||||||
ast::LitInt(n, ast::UnsuffixedIntLit(ast::Plus)) => {
|
ast::LitInt(n, ast::UnsuffixedIntLit) => {
|
||||||
match ty_hint.map(|ty| &ty.sty) {
|
match ty_hint.map(|ty| &ty.sty) {
|
||||||
Some(&ty::TyUint(_)) => Uint(n),
|
Some(&ty::TyUint(_)) => Uint(n),
|
||||||
_ => Int(n as i64)
|
_ => Int(n as i64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::LitInt(n, ast::SignedIntLit(_, ast::Minus)) |
|
|
||||||
ast::LitInt(n, ast::UnsuffixedIntLit(ast::Minus)) => Int(-(n as i64)),
|
|
||||||
ast::LitInt(n, ast::UnsignedIntLit(_)) => Uint(n),
|
ast::LitInt(n, ast::UnsignedIntLit(_)) => Uint(n),
|
||||||
ast::LitFloat(ref n, _) |
|
ast::LitFloat(ref n, _) |
|
||||||
ast::LitFloatUnsuffixed(ref n) => {
|
ast::LitFloatUnsuffixed(ref n) => {
|
||||||
|
|
|
@ -106,7 +106,7 @@ impl LateLintPass for TypeLimits {
|
||||||
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
|
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
|
||||||
forbid_unsigned_negation(cx, e.span);
|
forbid_unsigned_negation(cx, e.span);
|
||||||
},
|
},
|
||||||
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
|
ast::LitInt(_, ast::UnsuffixedIntLit) => {
|
||||||
if let ty::TyUint(_) = cx.tcx.node_id_to_type(e.id).sty {
|
if let ty::TyUint(_) = cx.tcx.node_id_to_type(e.id).sty {
|
||||||
forbid_unsigned_negation(cx, e.span);
|
forbid_unsigned_negation(cx, e.span);
|
||||||
}
|
}
|
||||||
|
@ -159,8 +159,8 @@ impl LateLintPass for TypeLimits {
|
||||||
match cx.tcx.node_id_to_type(e.id).sty {
|
match cx.tcx.node_id_to_type(e.id).sty {
|
||||||
ty::TyInt(t) => {
|
ty::TyInt(t) => {
|
||||||
match lit.node {
|
match lit.node {
|
||||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
|
ast::LitInt(v, ast::SignedIntLit(_)) |
|
||||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
|
ast::LitInt(v, ast::UnsuffixedIntLit) => {
|
||||||
let int_type = if let ast::IntTy::Is = t {
|
let int_type = if let ast::IntTy::Is = t {
|
||||||
cx.sess().target.int_type
|
cx.sess().target.int_type
|
||||||
} else {
|
} else {
|
||||||
|
@ -311,10 +311,8 @@ impl LateLintPass for TypeLimits {
|
||||||
let (min, max) = int_ty_range(int_ty);
|
let (min, max) = int_ty_range(int_ty);
|
||||||
let lit_val: i64 = match lit.node {
|
let lit_val: i64 = match lit.node {
|
||||||
hir::ExprLit(ref li) => match li.node {
|
hir::ExprLit(ref li) => match li.node {
|
||||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
|
ast::LitInt(v, ast::SignedIntLit(_)) |
|
||||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => v as i64,
|
ast::LitInt(v, ast::UnsuffixedIntLit) => v as i64,
|
||||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
|
|
||||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Minus)) => -(v as i64),
|
|
||||||
_ => return true
|
_ => return true
|
||||||
},
|
},
|
||||||
_ => panic!()
|
_ => panic!()
|
||||||
|
|
|
@ -66,13 +66,13 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
|
||||||
match lit.node {
|
match lit.node {
|
||||||
ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::UintTy::U8), b as u64, false),
|
ast::LitByte(b) => C_integral(Type::uint_from_ty(cx, ast::UintTy::U8), b as u64, false),
|
||||||
ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
|
ast::LitChar(i) => C_integral(Type::char(cx), i as u64, false),
|
||||||
ast::LitInt(i, ast::SignedIntLit(t, _)) => {
|
ast::LitInt(i, ast::SignedIntLit(t)) => {
|
||||||
C_integral(Type::int_from_ty(cx, t), i, true)
|
C_integral(Type::int_from_ty(cx, t), i, true)
|
||||||
}
|
}
|
||||||
ast::LitInt(u, ast::UnsignedIntLit(t)) => {
|
ast::LitInt(u, ast::UnsignedIntLit(t)) => {
|
||||||
C_integral(Type::uint_from_ty(cx, t), u, false)
|
C_integral(Type::uint_from_ty(cx, t), u, false)
|
||||||
}
|
}
|
||||||
ast::LitInt(i, ast::UnsuffixedIntLit(_)) => {
|
ast::LitInt(i, ast::UnsuffixedIntLit) => {
|
||||||
let lit_int_ty = cx.tcx().node_id_to_type(e.id);
|
let lit_int_ty = cx.tcx().node_id_to_type(e.id);
|
||||||
match lit_int_ty.sty {
|
match lit_int_ty.sty {
|
||||||
ty::TyInt(t) => {
|
ty::TyInt(t) => {
|
||||||
|
|
|
@ -2613,9 +2613,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
ast::LitByte(_) => tcx.types.u8,
|
ast::LitByte(_) => tcx.types.u8,
|
||||||
ast::LitChar(_) => tcx.types.char,
|
ast::LitChar(_) => tcx.types.char,
|
||||||
ast::LitInt(_, ast::SignedIntLit(t, _)) => tcx.mk_mach_int(t),
|
ast::LitInt(_, ast::SignedIntLit(t)) => tcx.mk_mach_int(t),
|
||||||
ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
|
ast::LitInt(_, ast::UnsignedIntLit(t)) => tcx.mk_mach_uint(t),
|
||||||
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
|
ast::LitInt(_, ast::UnsuffixedIntLit) => {
|
||||||
let opt_ty = expected.to_option(fcx).and_then(|ty| {
|
let opt_ty = expected.to_option(fcx).and_then(|ty| {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyInt(_) | ty::TyUint(_) => Some(ty),
|
ty::TyInt(_) | ty::TyUint(_) => Some(ty),
|
||||||
|
|
|
@ -21,7 +21,6 @@ pub use self::Mutability::*;
|
||||||
pub use self::Pat_::*;
|
pub use self::Pat_::*;
|
||||||
pub use self::PathListItem_::*;
|
pub use self::PathListItem_::*;
|
||||||
pub use self::PrimTy::*;
|
pub use self::PrimTy::*;
|
||||||
pub use self::Sign::*;
|
|
||||||
pub use self::Stmt_::*;
|
pub use self::Stmt_::*;
|
||||||
pub use self::StrStyle::*;
|
pub use self::StrStyle::*;
|
||||||
pub use self::StructFieldKind::*;
|
pub use self::StructFieldKind::*;
|
||||||
|
@ -1269,36 +1268,11 @@ pub enum StrStyle {
|
||||||
/// A literal
|
/// A literal
|
||||||
pub type Lit = Spanned<Lit_>;
|
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)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
|
||||||
pub enum LitIntType {
|
pub enum LitIntType {
|
||||||
SignedIntLit(IntTy, Sign),
|
SignedIntLit(IntTy),
|
||||||
UnsignedIntLit(UintTy),
|
UnsignedIntLit(UintTy),
|
||||||
UnsuffixedIntLit(Sign)
|
UnsuffixedIntLit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
|
||||||
|
|
|
@ -683,8 +683,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
self.expr_lit(span, ast::LitInt(i as u64, ast::UnsignedIntLit(ast::UintTy::Us)))
|
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> {
|
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,
|
if i < 0 {
|
||||||
ast::Sign::new(i))))
|
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> {
|
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)))
|
self.expr_lit(sp, ast::LitInt(u as u64, ast::UnsignedIntLit(ast::UintTy::U32)))
|
||||||
|
|
|
@ -263,9 +263,27 @@ pub mod rt {
|
||||||
(signed, $t:ty, $tag:expr) => (
|
(signed, $t:ty, $tag:expr) => (
|
||||||
impl ToTokens for $t {
|
impl ToTokens for $t {
|
||||||
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
|
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
|
||||||
let lit = ast::LitInt(*self as u64, ast::SignedIntLit($tag,
|
let val = if *self < 0 {
|
||||||
ast::Sign::new(*self)));
|
-self
|
||||||
dummy_spanned(lit).to_tokens(cx)
|
} 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -586,7 +586,7 @@ pub fn integer_lit(s: &str,
|
||||||
|
|
||||||
let mut base = 10;
|
let mut base = 10;
|
||||||
let orig = s;
|
let orig = s;
|
||||||
let mut ty = ast::UnsuffixedIntLit(ast::Plus);
|
let mut ty = ast::UnsuffixedIntLit;
|
||||||
|
|
||||||
if char_at(s, 0) == '0' && s.len() > 1 {
|
if char_at(s, 0) == '0' && s.len() > 1 {
|
||||||
match char_at(s, 1) {
|
match char_at(s, 1) {
|
||||||
|
@ -618,11 +618,11 @@ pub fn integer_lit(s: &str,
|
||||||
if let Some(ref suf) = suffix {
|
if let Some(ref suf) = suffix {
|
||||||
if suf.is_empty() { sd.span_bug(sp, "found empty literal suffix in Some")}
|
if suf.is_empty() { sd.span_bug(sp, "found empty literal suffix in Some")}
|
||||||
ty = match &**suf {
|
ty = match &**suf {
|
||||||
"isize" => ast::SignedIntLit(ast::IntTy::Is, ast::Plus),
|
"isize" => ast::SignedIntLit(ast::IntTy::Is),
|
||||||
"i8" => ast::SignedIntLit(ast::IntTy::I8, ast::Plus),
|
"i8" => ast::SignedIntLit(ast::IntTy::I8),
|
||||||
"i16" => ast::SignedIntLit(ast::IntTy::I16, ast::Plus),
|
"i16" => ast::SignedIntLit(ast::IntTy::I16),
|
||||||
"i32" => ast::SignedIntLit(ast::IntTy::I32, ast::Plus),
|
"i32" => ast::SignedIntLit(ast::IntTy::I32),
|
||||||
"i64" => ast::SignedIntLit(ast::IntTy::I64, ast::Plus),
|
"i64" => ast::SignedIntLit(ast::IntTy::I64),
|
||||||
"usize" => ast::UnsignedIntLit(ast::UintTy::Us),
|
"usize" => ast::UnsignedIntLit(ast::UintTy::Us),
|
||||||
"u8" => ast::UnsignedIntLit(ast::UintTy::U8),
|
"u8" => ast::UnsignedIntLit(ast::UintTy::U8),
|
||||||
"u16" => ast::UnsignedIntLit(ast::UintTy::U16),
|
"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 \
|
debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \
|
||||||
string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix);
|
string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix);
|
||||||
|
|
||||||
let res = match u64::from_str_radix(s, base).ok() {
|
match u64::from_str_radix(s, base) {
|
||||||
Some(r) => r,
|
Ok(r) => ast::LitInt(r, ty),
|
||||||
None => {
|
Err(_) => {
|
||||||
// small bases are lexed as if they were base 10, e.g, the string
|
// 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,
|
// 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
|
// 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 {
|
if !already_errored {
|
||||||
sd.span_err(sp, "int literal is too large");
|
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -645,24 +645,16 @@ pub trait PrintState<'a> {
|
||||||
}
|
}
|
||||||
ast::LitInt(i, t) => {
|
ast::LitInt(i, t) => {
|
||||||
match t {
|
match t {
|
||||||
ast::SignedIntLit(st, ast::Plus) => {
|
ast::SignedIntLit(st) => {
|
||||||
word(self.writer(),
|
word(self.writer(),
|
||||||
&st.val_to_string(i as i64))
|
&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) => {
|
ast::UnsignedIntLit(ut) => {
|
||||||
word(self.writer(), &ut.val_to_string(i))
|
word(self.writer(), &ut.val_to_string(i))
|
||||||
}
|
}
|
||||||
ast::UnsuffixedIntLit(ast::Plus) => {
|
ast::UnsuffixedIntLit => {
|
||||||
word(self.writer(), &format!("{}", i))
|
word(self.writer(), &format!("{}", i))
|
||||||
}
|
}
|
||||||
ast::UnsuffixedIntLit(ast::Minus) => {
|
|
||||||
word(self.writer(), &format!("-{}", i))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::LitFloat(ref f, t) => {
|
ast::LitFloat(ref f, t) => {
|
||||||
|
|
|
@ -38,14 +38,10 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
|
||||||
accumulator.push(c);
|
accumulator.push(c);
|
||||||
}
|
}
|
||||||
ast::LitInt(i, ast::UnsignedIntLit(_)) |
|
ast::LitInt(i, ast::UnsignedIntLit(_)) |
|
||||||
ast::LitInt(i, ast::SignedIntLit(_, ast::Plus)) |
|
ast::LitInt(i, ast::SignedIntLit(_)) |
|
||||||
ast::LitInt(i, ast::UnsuffixedIntLit(ast::Plus)) => {
|
ast::LitInt(i, ast::UnsuffixedIntLit) => {
|
||||||
accumulator.push_str(&format!("{}", i));
|
accumulator.push_str(&format!("{}", i));
|
||||||
}
|
}
|
||||||
ast::LitInt(i, ast::SignedIntLit(_, ast::Minus)) |
|
|
||||||
ast::LitInt(i, ast::UnsuffixedIntLit(ast::Minus)) => {
|
|
||||||
accumulator.push_str(&format!("-{}", i));
|
|
||||||
}
|
|
||||||
ast::LitBool(b) => {
|
ast::LitBool(b) => {
|
||||||
accumulator.push_str(&format!("{}", b));
|
accumulator.push_str(&format!("{}", b));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue