diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 5e3cfff086c..e8e817db7ab 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -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::LitChar(n) => Uint(n as u64),
-        ast::LitInt(n, ast::SignedIntLit(_, ast::Plus)) => Int(n as i64),
-        ast::LitInt(n, ast::UnsuffixedIntLit(ast::Plus)) => {
+        ast::LitInt(n, ast::SignedIntLit(_)) => Int(n as i64),
+        ast::LitInt(n, ast::UnsuffixedIntLit) => {
             match ty_hint.map(|ty| &ty.sty) {
                 Some(&ty::TyUint(_)) => Uint(n),
                 _ => 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::LitFloat(ref n, _) |
         ast::LitFloatUnsuffixed(ref n) => {
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index bd5f237cbfb..9993234c36a 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -106,7 +106,7 @@ impl LateLintPass for TypeLimits {
                         ast::LitInt(_, ast::UnsignedIntLit(_)) => {
                             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 {
                                 forbid_unsigned_negation(cx, e.span);
                             }
@@ -159,8 +159,8 @@ impl LateLintPass for TypeLimits {
                 match cx.tcx.node_id_to_type(e.id).sty {
                     ty::TyInt(t) => {
                         match lit.node {
-                            ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
-                            ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
+                            ast::LitInt(v, ast::SignedIntLit(_)) |
+                            ast::LitInt(v, ast::UnsuffixedIntLit) => {
                                 let int_type = if let ast::IntTy::Is = t {
                                     cx.sess().target.int_type
                                 } else {
@@ -311,10 +311,8 @@ impl LateLintPass for TypeLimits {
                     let (min, max) = int_ty_range(int_ty);
                     let lit_val: i64 = match lit.node {
                         hir::ExprLit(ref li) => match li.node {
-                            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),
+                            ast::LitInt(v, ast::SignedIntLit(_)) |
+                            ast::LitInt(v, ast::UnsuffixedIntLit) => v as i64,
                             _ => return true
                         },
                         _ => panic!()
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 329a291cd68..81df4746d10 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -66,13 +66,13 @@ pub fn const_lit(cx: &CrateContext, e: &hir::Expr, lit: &ast::Lit)
     match lit.node {
         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::LitInt(i, ast::SignedIntLit(t, _)) => {
+        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(_)) => {
+        ast::LitInt(i, ast::UnsuffixedIntLit) => {
             let lit_int_ty = cx.tcx().node_id_to_type(e.id);
             match lit_int_ty.sty {
                 ty::TyInt(t) => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 066805e54a1..176f9bcd4f6 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2613,9 +2613,9 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         }
         ast::LitByte(_) => tcx.types.u8,
         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::UnsuffixedIntLit(_)) => {
+        ast::LitInt(_, ast::UnsuffixedIntLit) => {
             let opt_ty = expected.to_option(fcx).and_then(|ty| {
                 match ty.sty {
                     ty::TyInt(_) | ty::TyUint(_) => Some(ty),
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index dbc73f01bc2..464e9da3724 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -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)]
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 1af29f2f93a..1c2d1cebf3d 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -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)))
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index a9f480daa0e..dfe3f8e3c54 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -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)
                 }
             }
         );
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 2472da36d52..d800b6925c0 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -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)
     }
 }
 
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 2054c0fc9bd..a02a7d47d32 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -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) => {
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index f5c2805c4ca..9f6cf73ed64 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -38,14 +38,10 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
                         accumulator.push(c);
                     }
                     ast::LitInt(i, ast::UnsignedIntLit(_)) |
-                    ast::LitInt(i, ast::SignedIntLit(_, ast::Plus)) |
-                    ast::LitInt(i, ast::UnsuffixedIntLit(ast::Plus)) => {
+                    ast::LitInt(i, ast::SignedIntLit(_)) |
+                    ast::LitInt(i, ast::UnsuffixedIntLit) => {
                         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) => {
                         accumulator.push_str(&format!("{}", b));
                     }