about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-05-01 08:29:11 +0200
committerGitHub <noreply@github.com>2019-05-01 08:29:11 +0200
commit6d78142bf05ae8848101190cf5410ea02ef47226 (patch)
treec351c3af082e0c061531c83788993d89ca23adc3
parent1c2ea8f59643386c1cf2c41ca9a19379d0fcac72 (diff)
parentb7711bff524716c27140256e6f6e78bbb8fd1283 (diff)
Rollup merge of #60330 - varkor:range-endpoint-overflow-lint, r=estebank
Suggest using an inclusive range instead of an exclusive range when the endpoint overflows by 1

Fixes https://github.com/rust-lang/rust/issues/47213.
-rw-r--r--src/librustc/hir/lowering.rs62
-rw-r--r--src/librustc_lint/types.rs595
-rw-r--r--src/librustc_typeck/check/demand.rs68
-rw-r--r--src/test/ui/cast_char.rs4
-rw-r--r--src/test/ui/cast_char.stderr8
-rw-r--r--src/test/ui/enum/enum-discrim-too-small2.rs8
-rw-r--r--src/test/ui/enum/enum-discrim-too-small2.stderr8
-rw-r--r--src/test/ui/lint/deny-overflowing-literals.rs2
-rw-r--r--src/test/ui/lint/deny-overflowing-literals.stderr2
-rw-r--r--src/test/ui/lint/lint-range-endpoint-overflow.rs17
-rw-r--r--src/test/ui/lint/lint-range-endpoint-overflow.stderr44
-rw-r--r--src/test/ui/lint/lint-type-limits2.rs2
-rw-r--r--src/test/ui/lint/lint-type-limits2.stderr2
-rw-r--r--src/test/ui/lint/lint-type-limits3.rs2
-rw-r--r--src/test/ui/lint/lint-type-limits3.stderr2
-rw-r--r--src/test/ui/lint/lint-type-overflow.rs38
-rw-r--r--src/test/ui/lint/lint-type-overflow.stderr74
-rw-r--r--src/test/ui/lint/lint-type-overflow2.stderr10
-rw-r--r--src/test/ui/lint/type-overflow.stderr2
19 files changed, 551 insertions, 399 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index df455a725c5..0366d1e5c24 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -5400,3 +5400,65 @@ fn body_ids(bodies: &BTreeMap<hir::BodyId, hir::Body>) -> Vec<hir::BodyId> {
     body_ids.sort_by_key(|b| bodies[b].value.span);
     body_ids
 }
+
+/// Checks if the specified expression is a built-in range literal.
+/// (See: `LoweringContext::lower_expr()`).
+pub fn is_range_literal(sess: &Session, expr: &hir::Expr) -> bool {
+    use hir::{Path, QPath, ExprKind, TyKind};
+
+    // Returns whether the given path represents a (desugared) range,
+    // either in std or core, i.e. has either a `::std::ops::Range` or
+    // `::core::ops::Range` prefix.
+    fn is_range_path(path: &Path) -> bool {
+        let segs: Vec<_> = path.segments.iter().map(|seg| seg.ident.as_str().to_string()).collect();
+        let segs: Vec<_> = segs.iter().map(|seg| &**seg).collect();
+
+        // "{{root}}" is the equivalent of `::` prefix in `Path`.
+        if let ["{{root}}", std_core, "ops", range] = segs.as_slice() {
+            (*std_core == "std" || *std_core == "core") && range.starts_with("Range")
+        } else {
+            false
+        }
+    };
+
+    // Check whether a span corresponding to a range expression is a
+    // range literal, rather than an explicit struct or `new()` call.
+    fn is_lit(sess: &Session, span: &Span) -> bool {
+        let source_map = sess.source_map();
+        let end_point = source_map.end_point(*span);
+
+        if let Ok(end_string) = source_map.span_to_snippet(end_point) {
+            !(end_string.ends_with("}") || end_string.ends_with(")"))
+        } else {
+            false
+        }
+    };
+
+    match expr.node {
+        // All built-in range literals but `..=` and `..` desugar to `Struct`s.
+        ExprKind::Struct(ref qpath, _, _) => {
+            if let QPath::Resolved(None, ref path) = **qpath {
+                return is_range_path(&path) && is_lit(sess, &expr.span);
+            }
+        }
+
+        // `..` desugars to its struct path.
+        ExprKind::Path(QPath::Resolved(None, ref path)) => {
+            return is_range_path(&path) && is_lit(sess, &expr.span);
+        }
+
+        // `..=` desugars into `::std::ops::RangeInclusive::new(...)`.
+        ExprKind::Call(ref func, _) => {
+            if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.node {
+                if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.node {
+                    let new_call = segment.ident.as_str() == "new";
+                    return is_range_path(&path) && is_lit(sess, &expr.span) && new_call;
+                }
+            }
+        }
+
+        _ => {}
+    }
+
+    false
+}
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index d3223c6edb8..f4ebfd79fe1 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -1,6 +1,7 @@
 #![allow(non_snake_case)]
 
-use rustc::hir::Node;
+use rustc::hir::{ExprKind, Node};
+use rustc::hir::lowering::is_range_literal;
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx};
@@ -57,6 +58,347 @@ impl TypeLimits {
     }
 }
 
+/// Attempts to special-case the overflowing literal lint when it occurs as a range endpoint.
+/// Returns `true` iff the lint was overridden.
+fn lint_overflowing_range_endpoint<'a, 'tcx>(
+    cx: &LateContext<'a, 'tcx>,
+    lit: &ast::Lit,
+    lit_val: u128,
+    max: u128,
+    expr: &'tcx hir::Expr,
+    parent_expr: &'tcx hir::Expr,
+    ty: impl std::fmt::Debug,
+) -> bool {
+    // We only want to handle exclusive (`..`) ranges,
+    // which are represented as `ExprKind::Struct`.
+    if let ExprKind::Struct(_, eps, _) = &parent_expr.node {
+        debug_assert_eq!(eps.len(), 2);
+        // We can suggest using an inclusive range
+        // (`..=`) instead only if it is the `end` that is
+        // overflowing and only by 1.
+        if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max {
+            let mut err = cx.struct_span_lint(
+                OVERFLOWING_LITERALS,
+                parent_expr.span,
+                &format!("range endpoint is out of range for `{:?}`", ty),
+            );
+            if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) {
+                use ast::{LitKind, LitIntType};
+                // We need to preserve the literal's suffix,
+                // as it may determine typing information.
+                let suffix = match lit.node {
+                    LitKind::Int(_, LitIntType::Signed(s)) => format!("{}", s),
+                    LitKind::Int(_, LitIntType::Unsigned(s)) => format!("{}", s),
+                    LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(),
+                    _ => bug!(),
+                };
+                let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix);
+                err.span_suggestion(
+                    parent_expr.span,
+                    &"use an inclusive range instead",
+                    suggestion,
+                    Applicability::MachineApplicable,
+                );
+                err.emit();
+                return true;
+            }
+        }
+    }
+
+    false
+}
+
+// For `isize` & `usize`, be conservative with the warnings, so that the
+// warnings are consistent between 32- and 64-bit platforms.
+fn int_ty_range(int_ty: ast::IntTy) -> (i128, i128) {
+    match int_ty {
+        ast::IntTy::Isize => (i64::min_value() as i128, i64::max_value() as i128),
+        ast::IntTy::I8 => (i8::min_value() as i64 as i128, i8::max_value() as i128),
+        ast::IntTy::I16 => (i16::min_value() as i64 as i128, i16::max_value() as i128),
+        ast::IntTy::I32 => (i32::min_value() as i64 as i128, i32::max_value() as i128),
+        ast::IntTy::I64 => (i64::min_value() as i128, i64::max_value() as i128),
+        ast::IntTy::I128 =>(i128::min_value() as i128, i128::max_value()),
+    }
+}
+
+fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) {
+    match uint_ty {
+        ast::UintTy::Usize => (u64::min_value() as u128, u64::max_value() as u128),
+        ast::UintTy::U8 => (u8::min_value() as u128, u8::max_value() as u128),
+        ast::UintTy::U16 => (u16::min_value() as u128, u16::max_value() as u128),
+        ast::UintTy::U32 => (u32::min_value() as u128, u32::max_value() as u128),
+        ast::UintTy::U64 => (u64::min_value() as u128, u64::max_value() as u128),
+        ast::UintTy::U128 => (u128::min_value(), u128::max_value()),
+    }
+}
+
+fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &ast::Lit) -> Option<String> {
+    let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?;
+    let firstch = src.chars().next()?;
+
+    if firstch == '0' {
+        match src.chars().nth(1) {
+            Some('x') | Some('b') => return Some(src),
+            _ => return None,
+        }
+    }
+
+    None
+}
+
+fn report_bin_hex_error(
+    cx: &LateContext<'_, '_>,
+    expr: &hir::Expr,
+    ty: attr::IntType,
+    repr_str: String,
+    val: u128,
+    negative: bool,
+) {
+    let size = layout::Integer::from_attr(&cx.tcx, ty).size();
+    let (t, actually) = match ty {
+        attr::IntType::SignedInt(t) => {
+            let actually = sign_extend(val, size) as i128;
+            (format!("{:?}", t), actually.to_string())
+        }
+        attr::IntType::UnsignedInt(t) => {
+            let actually = truncate(val, size);
+            (format!("{:?}", t), actually.to_string())
+        }
+    };
+    let mut err = cx.struct_span_lint(
+        OVERFLOWING_LITERALS,
+        expr.span,
+        &format!("literal out of range for {}", t),
+    );
+    err.note(&format!(
+        "the literal `{}` (decimal `{}`) does not fit into \
+            an `{}` and will become `{}{}`",
+        repr_str, val, t, actually, t
+    ));
+    if let Some(sugg_ty) =
+        get_type_suggestion(&cx.tables.node_type(expr.hir_id), val, negative)
+    {
+        if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
+            let (sans_suffix, _) = repr_str.split_at(pos);
+            err.span_suggestion(
+                expr.span,
+                &format!("consider using `{}` instead", sugg_ty),
+                format!("{}{}", sans_suffix, sugg_ty),
+                Applicability::MachineApplicable
+            );
+        } else {
+            err.help(&format!("consider using `{}` instead", sugg_ty));
+        }
+    }
+
+    err.emit();
+}
+
+// This function finds the next fitting type and generates a suggestion string.
+// It searches for fitting types in the following way (`X < Y`):
+//  - `iX`: if literal fits in `uX` => `uX`, else => `iY`
+//  - `-iX` => `iY`
+//  - `uX` => `uY`
+//
+// No suggestion for: `isize`, `usize`.
+fn get_type_suggestion<'a>(
+    t: Ty<'_>,
+    val: u128,
+    negative: bool,
+) -> Option<String> {
+    use syntax::ast::IntTy::*;
+    use syntax::ast::UintTy::*;
+    macro_rules! find_fit {
+        ($ty:expr, $val:expr, $negative:expr,
+         $($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => {
+            {
+                let _neg = if negative { 1 } else { 0 };
+                match $ty {
+                    $($type => {
+                        $(if !negative && val <= uint_ty_range($utypes).1 {
+                            return Some(format!("{:?}", $utypes))
+                        })*
+                        $(if val <= int_ty_range($itypes).1 as u128 + _neg {
+                            return Some(format!("{:?}", $itypes))
+                        })*
+                        None
+                    },)*
+                    _ => None
+                }
+            }
+        }
+    }
+    match t.sty {
+        ty::Int(i) => find_fit!(i, val, negative,
+                      I8 => [U8] => [I16, I32, I64, I128],
+                      I16 => [U16] => [I32, I64, I128],
+                      I32 => [U32] => [I64, I128],
+                      I64 => [U64] => [I128],
+                      I128 => [U128] => []),
+        ty::Uint(u) => find_fit!(u, val, negative,
+                      U8 => [U8, U16, U32, U64, U128] => [],
+                      U16 => [U16, U32, U64, U128] => [],
+                      U32 => [U32, U64, U128] => [],
+                      U64 => [U64, U128] => [],
+                      U128 => [U128] => []),
+        _ => None,
+    }
+}
+
+fn lint_int_literal<'a, 'tcx>(
+    cx: &LateContext<'a, 'tcx>,
+    type_limits: &TypeLimits,
+    e: &'tcx hir::Expr,
+    lit: &ast::Lit,
+    t: ast::IntTy,
+    v: u128,
+) {
+    let int_type = if let ast::IntTy::Isize = t {
+        cx.sess().target.isize_ty
+    } else {
+        t
+    };
+
+    let (_, max) = int_ty_range(int_type);
+    let max = max as u128;
+    let negative = type_limits.negated_expr_id == e.hir_id;
+
+    // Detect literal value out of range [min, max] inclusive
+    // avoiding use of -min to prevent overflow/panic
+    if (negative && v > max + 1) || (!negative && v > max) {
+        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
+            report_bin_hex_error(
+                cx,
+                e,
+                attr::IntType::SignedInt(t),
+                repr_str,
+                v,
+                negative,
+            );
+            return;
+        }
+
+        let par_id = cx.tcx.hir().get_parent_node_by_hir_id(e.hir_id);
+        if let Node::Expr(par_e) = cx.tcx.hir().get_by_hir_id(par_id) {
+            if let hir::ExprKind::Struct(..) = par_e.node {
+                if is_range_literal(cx.sess(), par_e)
+                    && lint_overflowing_range_endpoint(cx, lit, v, max, e, par_e, t)
+                {
+                    // The overflowing literal lint was overridden.
+                    return;
+                }
+            }
+        }
+
+        cx.span_lint(
+            OVERFLOWING_LITERALS,
+            e.span,
+            &format!("literal out of range for `{:?}`", t),
+        );
+    }
+}
+
+fn lint_uint_literal<'a, 'tcx>(
+    cx: &LateContext<'a, 'tcx>,
+    e: &'tcx hir::Expr,
+    lit: &ast::Lit,
+    t: ast::UintTy,
+) {
+    let uint_type = if let ast::UintTy::Usize = t {
+        cx.sess().target.usize_ty
+    } else {
+        t
+    };
+    let (min, max) = uint_ty_range(uint_type);
+    let lit_val: u128 = match lit.node {
+        // _v is u8, within range by definition
+        ast::LitKind::Byte(_v) => return,
+        ast::LitKind::Int(v, _) => v,
+        _ => bug!(),
+    };
+    if lit_val < min || lit_val > max {
+        let parent_id = cx.tcx.hir().get_parent_node_by_hir_id(e.hir_id);
+        if let Node::Expr(par_e) = cx.tcx.hir().get_by_hir_id(parent_id) {
+            match par_e.node {
+                hir::ExprKind::Cast(..) => {
+                    if let ty::Char = cx.tables.expr_ty(par_e).sty {
+                        let mut err = cx.struct_span_lint(
+                            OVERFLOWING_LITERALS,
+                            par_e.span,
+                            "only `u8` can be cast into `char`",
+                        );
+                        err.span_suggestion(
+                            par_e.span,
+                            &"use a `char` literal instead",
+                            format!("'\\u{{{:X}}}'", lit_val),
+                            Applicability::MachineApplicable,
+                        );
+                        err.emit();
+                        return;
+                    }
+                }
+                hir::ExprKind::Struct(..)
+                    if is_range_literal(cx.sess(), par_e) => {
+                        if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, par_e, t) {
+                            // The overflowing literal lint was overridden.
+                            return;
+                        }
+                    }
+                _ => {}
+            }
+        }
+        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
+            report_bin_hex_error(cx, e, attr::IntType::UnsignedInt(t), repr_str, lit_val, false);
+            return;
+        }
+        cx.span_lint(
+            OVERFLOWING_LITERALS,
+            e.span,
+            &format!("literal out of range for `{:?}`", t),
+        );
+    }
+}
+
+fn lint_literal<'a, 'tcx>(
+    cx: &LateContext<'a, 'tcx>,
+    type_limits: &TypeLimits,
+    e: &'tcx hir::Expr,
+    lit: &ast::Lit,
+) {
+    match cx.tables.node_type(e.hir_id).sty {
+        ty::Int(t) => {
+            match lit.node {
+                ast::LitKind::Int(v, ast::LitIntType::Signed(_)) |
+                ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => {
+                    lint_int_literal(cx, type_limits, e, lit, t, v)
+                }
+                _ => bug!(),
+            };
+        }
+        ty::Uint(t) => {
+            lint_uint_literal(cx, e, lit, t)
+        }
+        ty::Float(t) => {
+            let is_infinite = match lit.node {
+                ast::LitKind::Float(v, _) |
+                ast::LitKind::FloatUnsuffixed(v) => {
+                    match t {
+                        ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
+                        ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
+                    }
+                }
+                _ => bug!(),
+            };
+            if is_infinite == Ok(true) {
+                cx.span_lint(OVERFLOWING_LITERALS,
+                             e.span,
+                             &format!("literal out of range for `{:?}`", t));
+            }
+        }
+        _ => {}
+    }
+}
+
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) {
         match e.node {
@@ -73,118 +415,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
                                  "comparison is useless due to type limits");
                 }
             }
-            hir::ExprKind::Lit(ref lit) => {
-                match cx.tables.node_type(e.hir_id).sty {
-                    ty::Int(t) => {
-                        match lit.node {
-                            ast::LitKind::Int(v, ast::LitIntType::Signed(_)) |
-                            ast::LitKind::Int(v, ast::LitIntType::Unsuffixed) => {
-                                let int_type = if let ast::IntTy::Isize = t {
-                                    cx.sess().target.isize_ty
-                                } else {
-                                    t
-                                };
-                                let (_, max) = int_ty_range(int_type);
-                                let max = max as u128;
-                                let negative = self.negated_expr_id == e.hir_id;
-
-                                // Detect literal value out of range [min, max] inclusive
-                                // avoiding use of -min to prevent overflow/panic
-                                if (negative && v > max + 1) || (!negative && v > max) {
-                                    if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
-                                        report_bin_hex_error(
-                                            cx,
-                                            e,
-                                            attr::IntType::SignedInt(t),
-                                            repr_str,
-                                            v,
-                                            negative,
-                                        );
-                                        return;
-                                    }
-                                    cx.span_lint(
-                                        OVERFLOWING_LITERALS,
-                                        e.span,
-                                        &format!("literal out of range for {:?}", t),
-                                    );
-                                    return;
-                                }
-                            }
-                            _ => bug!(),
-                        };
-                    }
-                    ty::Uint(t) => {
-                        let uint_type = if let ast::UintTy::Usize = t {
-                            cx.sess().target.usize_ty
-                        } else {
-                            t
-                        };
-                        let (min, max) = uint_ty_range(uint_type);
-                        let lit_val: u128 = match lit.node {
-                            // _v is u8, within range by definition
-                            ast::LitKind::Byte(_v) => return,
-                            ast::LitKind::Int(v, _) => v,
-                            _ => bug!(),
-                        };
-                        if lit_val < min || lit_val > max {
-                            let parent_id = cx.tcx.hir().get_parent_node_by_hir_id(e.hir_id);
-                            if let Node::Expr(parent_expr) = cx.tcx.hir().get_by_hir_id(parent_id) {
-                                if let hir::ExprKind::Cast(..) = parent_expr.node {
-                                    if let ty::Char = cx.tables.expr_ty(parent_expr).sty {
-                                        let mut err = cx.struct_span_lint(
-                                                             OVERFLOWING_LITERALS,
-                                                             parent_expr.span,
-                                                             "only u8 can be cast into char");
-                                        err.span_suggestion(
-                                            parent_expr.span,
-                                            &"use a char literal instead",
-                                            format!("'\\u{{{:X}}}'", lit_val),
-                                            Applicability::MachineApplicable
-                                        );
-                                        err.emit();
-                                        return
-                                    }
-                                }
-                            }
-                            if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
-                                report_bin_hex_error(
-                                    cx,
-                                    e,
-                                    attr::IntType::UnsignedInt(t),
-                                    repr_str,
-                                    lit_val,
-                                    false,
-                                );
-                                return;
-                            }
-                            cx.span_lint(
-                                OVERFLOWING_LITERALS,
-                                e.span,
-                                &format!("literal out of range for {:?}", t),
-                            );
-                        }
-                    }
-                    ty::Float(t) => {
-                        let is_infinite = match lit.node {
-                            ast::LitKind::Float(v, _) |
-                            ast::LitKind::FloatUnsuffixed(v) => {
-                                match t {
-                                    ast::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
-                                    ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
-                                }
-                            }
-                            _ => bug!(),
-                        };
-                        if is_infinite == Ok(true) {
-                            cx.span_lint(OVERFLOWING_LITERALS,
-                                         e.span,
-                                         &format!("literal out of range for {:?}", t));
-                        }
-                    }
-                    _ => (),
-                };
-            }
-            _ => (),
+            hir::ExprKind::Lit(ref lit) => lint_literal(cx, self, e, lit),
+            _ => {}
         };
 
         fn is_valid<T: cmp::PartialOrd>(binop: hir::BinOp, v: T, min: T, max: T) -> bool {
@@ -209,30 +441,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
                             })
         }
 
-        // for isize & usize, be conservative with the warnings, so that the
-        // warnings are consistent between 32- and 64-bit platforms
-        fn int_ty_range(int_ty: ast::IntTy) -> (i128, i128) {
-            match int_ty {
-                ast::IntTy::Isize => (i64::min_value() as i128, i64::max_value() as i128),
-                ast::IntTy::I8 => (i8::min_value() as i64 as i128, i8::max_value() as i128),
-                ast::IntTy::I16 => (i16::min_value() as i64 as i128, i16::max_value() as i128),
-                ast::IntTy::I32 => (i32::min_value() as i64 as i128, i32::max_value() as i128),
-                ast::IntTy::I64 => (i64::min_value() as i128, i64::max_value() as i128),
-                ast::IntTy::I128 =>(i128::min_value() as i128, i128::max_value()),
-            }
-        }
-
-        fn uint_ty_range(uint_ty: ast::UintTy) -> (u128, u128) {
-            match uint_ty {
-                ast::UintTy::Usize => (u64::min_value() as u128, u64::max_value() as u128),
-                ast::UintTy::U8 => (u8::min_value() as u128, u8::max_value() as u128),
-                ast::UintTy::U16 => (u16::min_value() as u128, u16::max_value() as u128),
-                ast::UintTy::U32 => (u32::min_value() as u128, u32::max_value() as u128),
-                ast::UintTy::U64 => (u64::min_value() as u128, u64::max_value() as u128),
-                ast::UintTy::U128 => (u128::min_value(), u128::max_value()),
-            }
-        }
-
         fn check_limits(cx: &LateContext<'_, '_>,
                         binop: hir::BinOp,
                         l: &hir::Expr,
@@ -289,119 +497,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
                 _ => false,
             }
         }
-
-        fn get_bin_hex_repr(cx: &LateContext<'_, '_>, lit: &ast::Lit) -> Option<String> {
-            let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?;
-            let firstch = src.chars().next()?;
-
-            if firstch == '0' {
-                match src.chars().nth(1) {
-                    Some('x') | Some('b') => return Some(src),
-                    _ => return None,
-                }
-            }
-
-            None
-        }
-
-        // This function finds the next fitting type and generates a suggestion string.
-        // It searches for fitting types in the following way (`X < Y`):
-        //  - `iX`: if literal fits in `uX` => `uX`, else => `iY`
-        //  - `-iX` => `iY`
-        //  - `uX` => `uY`
-        //
-        // No suggestion for: `isize`, `usize`.
-        fn get_type_suggestion<'a>(
-            t: Ty<'_>,
-            val: u128,
-            negative: bool,
-        ) -> Option<String> {
-            use syntax::ast::IntTy::*;
-            use syntax::ast::UintTy::*;
-            macro_rules! find_fit {
-                ($ty:expr, $val:expr, $negative:expr,
-                 $($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => {
-                    {
-                        let _neg = if negative { 1 } else { 0 };
-                        match $ty {
-                            $($type => {
-                                $(if !negative && val <= uint_ty_range($utypes).1 {
-                                    return Some(format!("{:?}", $utypes))
-                                })*
-                                $(if val <= int_ty_range($itypes).1 as u128 + _neg {
-                                    return Some(format!("{:?}", $itypes))
-                                })*
-                                None
-                            },)*
-                            _ => None
-                        }
-                    }
-                }
-            }
-            match t.sty {
-                ty::Int(i) => find_fit!(i, val, negative,
-                              I8 => [U8] => [I16, I32, I64, I128],
-                              I16 => [U16] => [I32, I64, I128],
-                              I32 => [U32] => [I64, I128],
-                              I64 => [U64] => [I128],
-                              I128 => [U128] => []),
-                ty::Uint(u) => find_fit!(u, val, negative,
-                              U8 => [U8, U16, U32, U64, U128] => [],
-                              U16 => [U16, U32, U64, U128] => [],
-                              U32 => [U32, U64, U128] => [],
-                              U64 => [U64, U128] => [],
-                              U128 => [U128] => []),
-                _ => None,
-            }
-        }
-
-        fn report_bin_hex_error(
-            cx: &LateContext<'_, '_>,
-            expr: &hir::Expr,
-            ty: attr::IntType,
-            repr_str: String,
-            val: u128,
-            negative: bool,
-        ) {
-            let size = layout::Integer::from_attr(&cx.tcx, ty).size();
-            let (t, actually) = match ty {
-                attr::IntType::SignedInt(t) => {
-                    let actually = sign_extend(val, size) as i128;
-                    (format!("{:?}", t), actually.to_string())
-                }
-                attr::IntType::UnsignedInt(t) => {
-                    let actually = truncate(val, size);
-                    (format!("{:?}", t), actually.to_string())
-                }
-            };
-            let mut err = cx.struct_span_lint(
-                OVERFLOWING_LITERALS,
-                expr.span,
-                &format!("literal out of range for {}", t),
-            );
-            err.note(&format!(
-                "the literal `{}` (decimal `{}`) does not fit into \
-                 an `{}` and will become `{}{}`",
-                repr_str, val, t, actually, t
-            ));
-            if let Some(sugg_ty) =
-                get_type_suggestion(&cx.tables.node_type(expr.hir_id), val, negative)
-            {
-                if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
-                    let (sans_suffix, _) = repr_str.split_at(pos);
-                    err.span_suggestion(
-                        expr.span,
-                        &format!("consider using `{}` instead", sugg_ty),
-                        format!("{}{}", sans_suffix, sugg_ty),
-                        Applicability::MachineApplicable
-                    );
-                } else {
-                    err.help(&format!("consider using `{}` instead", sugg_ty));
-                }
-            }
-
-            err.emit();
-        }
     }
 }
 
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 689996ccb25..8ae66a96c76 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -7,7 +7,7 @@ use syntax_pos::Span;
 use rustc::hir;
 use rustc::hir::def::Def;
 use rustc::hir::Node;
-use rustc::hir::print;
+use rustc::hir::{print, lowering::is_range_literal};
 use rustc::ty::{self, Ty, AssociatedItem};
 use rustc::ty::adjustment::AllowTwoPhase;
 use errors::{Applicability, DiagnosticBuilder};
@@ -380,7 +380,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             hir::ExprKind::Cast(_, _) |
                             hir::ExprKind::Binary(_, _, _) => true,
                             // parenthesize borrows of range literals (Issue #54505)
-                            _ if self.is_range_literal(expr) => true,
+                            _ if is_range_literal(self.tcx.sess, expr) => true,
                             _ => false,
                         };
                         let sugg_expr = if needs_parens {
@@ -479,70 +479,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         None
     }
 
-    /// This function checks if the specified expression is a built-in range literal.
-    /// (See: `LoweringContext::lower_expr()` in `src/librustc/hir/lowering.rs`).
-    fn is_range_literal(&self, expr: &hir::Expr) -> bool {
-        use hir::{Path, QPath, ExprKind, TyKind};
-
-        // We support `::std::ops::Range` and `::core::ops::Range` prefixes
-        let is_range_path = |path: &Path| {
-            let mut segs = path.segments.iter()
-                .map(|seg| seg.ident.as_str());
-
-            if let (Some(root), Some(std_core), Some(ops), Some(range), None) =
-                (segs.next(), segs.next(), segs.next(), segs.next(), segs.next())
-            {
-                // "{{root}}" is the equivalent of `::` prefix in Path
-                root == "{{root}}" && (std_core == "std" || std_core == "core")
-                    && ops == "ops" && range.starts_with("Range")
-            } else {
-                false
-            }
-        };
-
-        let span_is_range_literal = |span: &Span| {
-            // Check whether a span corresponding to a range expression
-            // is a range literal, rather than an explicit struct or `new()` call.
-            let source_map = self.tcx.sess.source_map();
-            let end_point = source_map.end_point(*span);
-
-            if let Ok(end_string) = source_map.span_to_snippet(end_point) {
-                !(end_string.ends_with("}") || end_string.ends_with(")"))
-            } else {
-                false
-            }
-        };
-
-        match expr.node {
-            // All built-in range literals but `..=` and `..` desugar to Structs
-            ExprKind::Struct(ref qpath, _, _) => {
-                if let QPath::Resolved(None, ref path) = **qpath {
-                    return is_range_path(&path) && span_is_range_literal(&expr.span);
-                }
-            }
-            // `..` desugars to its struct path
-            ExprKind::Path(QPath::Resolved(None, ref path)) => {
-                return is_range_path(&path) && span_is_range_literal(&expr.span);
-            }
-
-            // `..=` desugars into `::std::ops::RangeInclusive::new(...)`
-            ExprKind::Call(ref func, _) => {
-                if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.node {
-                    if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.node {
-                        let call_to_new = segment.ident.as_str() == "new";
-
-                        return is_range_path(&path) && span_is_range_literal(&expr.span)
-                            && call_to_new;
-                    }
-                }
-            }
-
-            _ => {}
-        }
-
-        false
-    }
-
     pub fn check_for_cast(
         &self,
         err: &mut DiagnosticBuilder<'tcx>,
diff --git a/src/test/ui/cast_char.rs b/src/test/ui/cast_char.rs
index 8c319af9c96..9634ed56f7b 100644
--- a/src/test/ui/cast_char.rs
+++ b/src/test/ui/cast_char.rs
@@ -2,9 +2,9 @@
 
 fn main() {
     const XYZ: char = 0x1F888 as char;
-    //~^ ERROR only u8 can be cast into char
+    //~^ ERROR only `u8` can be cast into `char`
     const XY: char = 129160 as char;
-    //~^ ERROR only u8 can be cast into char
+    //~^ ERROR only `u8` can be cast into `char`
     const ZYX: char = '\u{01F888}';
     println!("{}", XYZ);
 }
diff --git a/src/test/ui/cast_char.stderr b/src/test/ui/cast_char.stderr
index f0c9b898890..37ef98bcb50 100644
--- a/src/test/ui/cast_char.stderr
+++ b/src/test/ui/cast_char.stderr
@@ -1,8 +1,8 @@
-error: only u8 can be cast into char
+error: only `u8` can be cast into `char`
   --> $DIR/cast_char.rs:4:23
    |
 LL |     const XYZ: char = 0x1F888 as char;
-   |                       ^^^^^^^^^^^^^^^ help: use a char literal instead: `'\u{1F888}'`
+   |                       ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'`
    |
 note: lint level defined here
   --> $DIR/cast_char.rs:1:9
@@ -10,11 +10,11 @@ note: lint level defined here
 LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: only u8 can be cast into char
+error: only `u8` can be cast into `char`
   --> $DIR/cast_char.rs:6:22
    |
 LL |     const XY: char = 129160 as char;
-   |                      ^^^^^^^^^^^^^^ help: use a char literal instead: `'\u{1F888}'`
+   |                      ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/enum/enum-discrim-too-small2.rs b/src/test/ui/enum/enum-discrim-too-small2.rs
index af605643025..85cd73d6f08 100644
--- a/src/test/ui/enum/enum-discrim-too-small2.rs
+++ b/src/test/ui/enum/enum-discrim-too-small2.rs
@@ -5,28 +5,28 @@
 enum Ei8 {
     Ai8 = 23,
     Bi8 = -23,
-    Ci8 = 223, //~ ERROR literal out of range for i8
+    Ci8 = 223, //~ ERROR literal out of range for `i8`
 }
 
 #[repr(i16)]
 enum Ei16 {
     Ai16 = 23,
     Bi16 = -22333,
-    Ci16 = 55555, //~ ERROR literal out of range for i16
+    Ci16 = 55555, //~ ERROR literal out of range for `i16`
 }
 
 #[repr(i32)]
 enum Ei32 {
     Ai32 = 23,
     Bi32 = -2_000_000_000,
-    Ci32 = 3_000_000_000, //~ ERROR literal out of range for i32
+    Ci32 = 3_000_000_000, //~ ERROR literal out of range for `i32`
 }
 
 #[repr(i64)]
 enum Ei64 {
     Ai64 = 23,
     Bi64 = -9223372036854775808,
-    Ci64 = 9223372036854775809, //~ ERROR literal out of range for i64
+    Ci64 = 9223372036854775809, //~ ERROR literal out of range for `i64`
 }
 
 // u64 currently allows negative numbers, and i64 allows numbers greater than `1<<63`.  This is a
diff --git a/src/test/ui/enum/enum-discrim-too-small2.stderr b/src/test/ui/enum/enum-discrim-too-small2.stderr
index 6340f5a856e..f7220044ba4 100644
--- a/src/test/ui/enum/enum-discrim-too-small2.stderr
+++ b/src/test/ui/enum/enum-discrim-too-small2.stderr
@@ -1,4 +1,4 @@
-error: literal out of range for i8
+error: literal out of range for `i8`
   --> $DIR/enum-discrim-too-small2.rs:8:11
    |
 LL |     Ci8 = 223,
@@ -10,19 +10,19 @@ note: lint level defined here
 LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: literal out of range for i16
+error: literal out of range for `i16`
   --> $DIR/enum-discrim-too-small2.rs:15:12
    |
 LL |     Ci16 = 55555,
    |            ^^^^^
 
-error: literal out of range for i32
+error: literal out of range for `i32`
   --> $DIR/enum-discrim-too-small2.rs:22:12
    |
 LL |     Ci32 = 3_000_000_000,
    |            ^^^^^^^^^^^^^
 
-error: literal out of range for i64
+error: literal out of range for `i64`
   --> $DIR/enum-discrim-too-small2.rs:29:12
    |
 LL |     Ci64 = 9223372036854775809,
diff --git a/src/test/ui/lint/deny-overflowing-literals.rs b/src/test/ui/lint/deny-overflowing-literals.rs
index ebd6654d39b..b887f66e94b 100644
--- a/src/test/ui/lint/deny-overflowing-literals.rs
+++ b/src/test/ui/lint/deny-overflowing-literals.rs
@@ -1,4 +1,4 @@
 fn main() {
     let x: u8 = 256;
-    //~^ error: literal out of range for u8
+    //~^ error: literal out of range for `u8`
 }
diff --git a/src/test/ui/lint/deny-overflowing-literals.stderr b/src/test/ui/lint/deny-overflowing-literals.stderr
index 7313dd0bfb5..1263a7bb7fd 100644
--- a/src/test/ui/lint/deny-overflowing-literals.stderr
+++ b/src/test/ui/lint/deny-overflowing-literals.stderr
@@ -1,4 +1,4 @@
-error: literal out of range for u8
+error: literal out of range for `u8`
   --> $DIR/deny-overflowing-literals.rs:2:17
    |
 LL |     let x: u8 = 256;
diff --git a/src/test/ui/lint/lint-range-endpoint-overflow.rs b/src/test/ui/lint/lint-range-endpoint-overflow.rs
new file mode 100644
index 00000000000..7034d56aa5d
--- /dev/null
+++ b/src/test/ui/lint/lint-range-endpoint-overflow.rs
@@ -0,0 +1,17 @@
+#![deny(overflowing_literals)]
+
+fn main() {
+    let range_a = 0..256; //~ ERROR range endpoint is out of range for `u8`
+    let range_b = 0..=255; // ok
+    let range_c = 0..=256; //~ ERROR literal out of range for `u8`
+    let range_d = 256..5; //~ ERROR literal out of range for `u8`
+    let range_e = 0..257; //~ ERROR literal out of range for `u8`
+    let _range_f = 0..256u8;  //~ ERROR range endpoint is out of range for `u8`
+    let _range_g = 0..128i8;  //~ ERROR range endpoint is out of range for `i8`
+
+    range_a.collect::<Vec<u8>>();
+    range_b.collect::<Vec<u8>>();
+    range_c.collect::<Vec<u8>>();
+    range_d.collect::<Vec<u8>>();
+    range_e.collect::<Vec<u8>>();
+}
diff --git a/src/test/ui/lint/lint-range-endpoint-overflow.stderr b/src/test/ui/lint/lint-range-endpoint-overflow.stderr
new file mode 100644
index 00000000000..939451d6bc0
--- /dev/null
+++ b/src/test/ui/lint/lint-range-endpoint-overflow.stderr
@@ -0,0 +1,44 @@
+error: range endpoint is out of range for `u8`
+  --> $DIR/lint-range-endpoint-overflow.rs:4:19
+   |
+LL |     let range_a = 0..256;
+   |                   ^^^^^^ help: use an inclusive range instead: `0..=255`
+   |
+note: lint level defined here
+  --> $DIR/lint-range-endpoint-overflow.rs:1:9
+   |
+LL | #![deny(overflowing_literals)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: literal out of range for `u8`
+  --> $DIR/lint-range-endpoint-overflow.rs:6:23
+   |
+LL |     let range_c = 0..=256;
+   |                       ^^^
+
+error: literal out of range for `u8`
+  --> $DIR/lint-range-endpoint-overflow.rs:7:19
+   |
+LL |     let range_d = 256..5;
+   |                   ^^^
+
+error: literal out of range for `u8`
+  --> $DIR/lint-range-endpoint-overflow.rs:8:22
+   |
+LL |     let range_e = 0..257;
+   |                      ^^^
+
+error: range endpoint is out of range for `u8`
+  --> $DIR/lint-range-endpoint-overflow.rs:9:20
+   |
+LL |     let _range_f = 0..256u8;
+   |                    ^^^^^^^^ help: use an inclusive range instead: `0..=255u8`
+
+error: range endpoint is out of range for `i8`
+  --> $DIR/lint-range-endpoint-overflow.rs:10:20
+   |
+LL |     let _range_g = 0..128i8;
+   |                    ^^^^^^^^ help: use an inclusive range instead: `0..=127i8`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/test/ui/lint/lint-type-limits2.rs b/src/test/ui/lint/lint-type-limits2.rs
index c4486e06768..3f90119cd89 100644
--- a/src/test/ui/lint/lint-type-limits2.rs
+++ b/src/test/ui/lint/lint-type-limits2.rs
@@ -11,5 +11,5 @@ fn bar() -> i8 {
 
 fn baz() -> bool {
     128 > bar() //~ ERROR comparison is useless due to type limits
-                //~| WARN literal out of range for i8
+                //~| WARN literal out of range for `i8`
 }
diff --git a/src/test/ui/lint/lint-type-limits2.stderr b/src/test/ui/lint/lint-type-limits2.stderr
index e7bc407422a..0b3d2928567 100644
--- a/src/test/ui/lint/lint-type-limits2.stderr
+++ b/src/test/ui/lint/lint-type-limits2.stderr
@@ -6,7 +6,7 @@ LL |     128 > bar()
    |
    = note: requested on the command line with `-D unused-comparisons`
 
-warning: literal out of range for i8
+warning: literal out of range for `i8`
   --> $DIR/lint-type-limits2.rs:13:5
    |
 LL |     128 > bar()
diff --git a/src/test/ui/lint/lint-type-limits3.rs b/src/test/ui/lint/lint-type-limits3.rs
index a715c69f784..ceecf9ab30b 100644
--- a/src/test/ui/lint/lint-type-limits3.rs
+++ b/src/test/ui/lint/lint-type-limits3.rs
@@ -7,7 +7,7 @@ fn main() { }
 fn qux() {
     let mut i = 1i8;
     while 200 != i { //~ ERROR comparison is useless due to type limits
-                     //~| WARN literal out of range for i8
+                     //~| WARN literal out of range for `i8`
         i += 1;
     }
 }
diff --git a/src/test/ui/lint/lint-type-limits3.stderr b/src/test/ui/lint/lint-type-limits3.stderr
index 742b6695c24..70cd9c859ec 100644
--- a/src/test/ui/lint/lint-type-limits3.stderr
+++ b/src/test/ui/lint/lint-type-limits3.stderr
@@ -6,7 +6,7 @@ LL |     while 200 != i {
    |
    = note: requested on the command line with `-D unused-comparisons`
 
-warning: literal out of range for i8
+warning: literal out of range for `i8`
   --> $DIR/lint-type-limits3.rs:9:11
    |
 LL |     while 200 != i {
diff --git a/src/test/ui/lint/lint-type-overflow.rs b/src/test/ui/lint/lint-type-overflow.rs
index 847cdf31dc7..9672da6d358 100644
--- a/src/test/ui/lint/lint-type-overflow.rs
+++ b/src/test/ui/lint/lint-type-overflow.rs
@@ -1,5 +1,3 @@
-//
-
 #![deny(overflowing_literals)]
 
 fn test(x: i8) {
@@ -9,39 +7,39 @@ fn test(x: i8) {
 #[allow(unused_variables)]
 fn main() {
     let x1: u8 = 255; // should be OK
-    let x1: u8 = 256; //~ error: literal out of range for u8
+    let x1: u8 = 256; //~ error: literal out of range for `u8`
 
     let x1 = 255_u8; // should be OK
-    let x1 = 256_u8; //~ error: literal out of range for u8
+    let x1 = 256_u8; //~ error: literal out of range for `u8`
 
     let x2: i8 = -128; // should be OK
-    let x1: i8 = 128; //~ error: literal out of range for i8
+    let x1: i8 = 128; //~ error: literal out of range for `i8`
 
-    let x3: i8 = -129; //~ error: literal out of range for i8
-    let x3: i8 = -(129); //~ error: literal out of range for i8
-    let x3: i8 = -{129}; //~ error: literal out of range for i8
+    let x3: i8 = -129; //~ error: literal out of range for `i8`
+    let x3: i8 = -(129); //~ error: literal out of range for `i8`
+    let x3: i8 = -{129}; //~ error: literal out of range for `i8`
 
-    test(1000); //~ error: literal out of range for i8
+    test(1000); //~ error: literal out of range for `i8`
 
-    let x = 128_i8; //~ error: literal out of range for i8
+    let x = 128_i8; //~ error: literal out of range for `i8`
     let x = 127_i8;
     let x = -128_i8;
     let x = -(128_i8);
-    let x = -129_i8; //~ error: literal out of range for i8
+    let x = -129_i8; //~ error: literal out of range for `i8`
 
     let x: i32 = 2147483647; // should be OK
     let x = 2147483647_i32; // should be OK
-    let x: i32 = 2147483648; //~ error: literal out of range for i32
-    let x = 2147483648_i32; //~ error: literal out of range for i32
+    let x: i32 = 2147483648; //~ error: literal out of range for `i32`
+    let x = 2147483648_i32; //~ error: literal out of range for `i32`
     let x: i32 = -2147483648; // should be OK
     let x = -2147483648_i32; // should be OK
-    let x: i32 = -2147483649; //~ error: literal out of range for i32
-    let x = -2147483649_i32; //~ error: literal out of range for i32
-    let x = 2147483648; //~ error: literal out of range for i32
+    let x: i32 = -2147483649; //~ error: literal out of range for `i32`
+    let x = -2147483649_i32; //~ error: literal out of range for `i32`
+    let x = 2147483648; //~ error: literal out of range for `i32`
 
-    let x = 9223372036854775808_i64; //~ error: literal out of range for i64
+    let x = 9223372036854775808_i64; //~ error: literal out of range for `i64`
     let x = -9223372036854775808_i64; // should be OK
-    let x = 18446744073709551615_i64; //~ error: literal out of range for i64
-    let x: i64 = -9223372036854775809; //~ error: literal out of range for i64
-    let x = -9223372036854775809_i64; //~ error: literal out of range for i64
+    let x = 18446744073709551615_i64; //~ error: literal out of range for `i64`
+    let x: i64 = -9223372036854775809; //~ error: literal out of range for `i64`
+    let x = -9223372036854775809_i64; //~ error: literal out of range for `i64`
 }
diff --git a/src/test/ui/lint/lint-type-overflow.stderr b/src/test/ui/lint/lint-type-overflow.stderr
index 9da007457aa..6fcd9b58b2d 100644
--- a/src/test/ui/lint/lint-type-overflow.stderr
+++ b/src/test/ui/lint/lint-type-overflow.stderr
@@ -1,113 +1,113 @@
-error: literal out of range for u8
-  --> $DIR/lint-type-overflow.rs:12:18
+error: literal out of range for `u8`
+  --> $DIR/lint-type-overflow.rs:10:18
    |
 LL |     let x1: u8 = 256;
    |                  ^^^
    |
 note: lint level defined here
-  --> $DIR/lint-type-overflow.rs:3:9
+  --> $DIR/lint-type-overflow.rs:1:9
    |
 LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: literal out of range for u8
-  --> $DIR/lint-type-overflow.rs:15:14
+error: literal out of range for `u8`
+  --> $DIR/lint-type-overflow.rs:13:14
    |
 LL |     let x1 = 256_u8;
    |              ^^^^^^
 
-error: literal out of range for i8
-  --> $DIR/lint-type-overflow.rs:18:18
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow.rs:16:18
    |
 LL |     let x1: i8 = 128;
    |                  ^^^
 
-error: literal out of range for i8
-  --> $DIR/lint-type-overflow.rs:20:19
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow.rs:18:19
    |
 LL |     let x3: i8 = -129;
    |                   ^^^
 
-error: literal out of range for i8
-  --> $DIR/lint-type-overflow.rs:21:19
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow.rs:19:19
    |
 LL |     let x3: i8 = -(129);
    |                   ^^^^^
 
-error: literal out of range for i8
-  --> $DIR/lint-type-overflow.rs:22:20
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow.rs:20:20
    |
 LL |     let x3: i8 = -{129};
    |                    ^^^
 
-error: literal out of range for i8
-  --> $DIR/lint-type-overflow.rs:24:10
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow.rs:22:10
    |
 LL |     test(1000);
    |          ^^^^
 
-error: literal out of range for i8
-  --> $DIR/lint-type-overflow.rs:26:13
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow.rs:24:13
    |
 LL |     let x = 128_i8;
    |             ^^^^^^
 
-error: literal out of range for i8
-  --> $DIR/lint-type-overflow.rs:30:14
+error: literal out of range for `i8`
+  --> $DIR/lint-type-overflow.rs:28:14
    |
 LL |     let x = -129_i8;
    |              ^^^^^^
 
-error: literal out of range for i32
-  --> $DIR/lint-type-overflow.rs:34:18
+error: literal out of range for `i32`
+  --> $DIR/lint-type-overflow.rs:32:18
    |
 LL |     let x: i32 = 2147483648;
    |                  ^^^^^^^^^^
 
-error: literal out of range for i32
-  --> $DIR/lint-type-overflow.rs:35:13
+error: literal out of range for `i32`
+  --> $DIR/lint-type-overflow.rs:33:13
    |
 LL |     let x = 2147483648_i32;
    |             ^^^^^^^^^^^^^^
 
-error: literal out of range for i32
-  --> $DIR/lint-type-overflow.rs:38:19
+error: literal out of range for `i32`
+  --> $DIR/lint-type-overflow.rs:36:19
    |
 LL |     let x: i32 = -2147483649;
    |                   ^^^^^^^^^^
 
-error: literal out of range for i32
-  --> $DIR/lint-type-overflow.rs:39:14
+error: literal out of range for `i32`
+  --> $DIR/lint-type-overflow.rs:37:14
    |
 LL |     let x = -2147483649_i32;
    |              ^^^^^^^^^^^^^^
 
-error: literal out of range for i32
-  --> $DIR/lint-type-overflow.rs:40:13
+error: literal out of range for `i32`
+  --> $DIR/lint-type-overflow.rs:38:13
    |
 LL |     let x = 2147483648;
    |             ^^^^^^^^^^
 
-error: literal out of range for i64
-  --> $DIR/lint-type-overflow.rs:42:13
+error: literal out of range for `i64`
+  --> $DIR/lint-type-overflow.rs:40:13
    |
 LL |     let x = 9223372036854775808_i64;
    |             ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: literal out of range for i64
-  --> $DIR/lint-type-overflow.rs:44:13
+error: literal out of range for `i64`
+  --> $DIR/lint-type-overflow.rs:42:13
    |
 LL |     let x = 18446744073709551615_i64;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: literal out of range for i64
-  --> $DIR/lint-type-overflow.rs:45:19
+error: literal out of range for `i64`
+  --> $DIR/lint-type-overflow.rs:43:19
    |
 LL |     let x: i64 = -9223372036854775809;
    |                   ^^^^^^^^^^^^^^^^^^^
 
-error: literal out of range for i64
-  --> $DIR/lint-type-overflow.rs:46:14
+error: literal out of range for `i64`
+  --> $DIR/lint-type-overflow.rs:44:14
    |
 LL |     let x = -9223372036854775809_i64;
    |              ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr
index 5255f6c7593..c76e9e25d5a 100644
--- a/src/test/ui/lint/lint-type-overflow2.stderr
+++ b/src/test/ui/lint/lint-type-overflow2.stderr
@@ -1,4 +1,4 @@
-warning: literal out of range for i8
+warning: literal out of range for `i8`
   --> $DIR/lint-type-overflow2.rs:9:20
    |
 LL |     let x2: i8 = --128;
@@ -10,25 +10,25 @@ note: lint level defined here
 LL | #![warn(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for f32
+warning: literal out of range for `f32`
   --> $DIR/lint-type-overflow2.rs:11:14
    |
 LL |     let x = -3.40282357e+38_f32;
    |              ^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for f32
+warning: literal out of range for `f32`
   --> $DIR/lint-type-overflow2.rs:12:14
    |
 LL |     let x =  3.40282357e+38_f32;
    |              ^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for f64
+warning: literal out of range for `f64`
   --> $DIR/lint-type-overflow2.rs:13:14
    |
 LL |     let x = -1.7976931348623159e+308_f64;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-warning: literal out of range for f64
+warning: literal out of range for `f64`
   --> $DIR/lint-type-overflow2.rs:14:14
    |
 LL |     let x =  1.7976931348623159e+308_f64;
diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr
index 5235c9851b5..dabfb876fbb 100644
--- a/src/test/ui/lint/type-overflow.stderr
+++ b/src/test/ui/lint/type-overflow.stderr
@@ -1,4 +1,4 @@
-warning: literal out of range for i8
+warning: literal out of range for `i8`
   --> $DIR/type-overflow.rs:5:17
    |
 LL |     let error = 255i8;