From 75d951e1adf515b6ef549c4cf12432dfbe1b8ac5 Mon Sep 17 00:00:00 2001
From: flip1995 <hello@philkrones.com>
Date: Fri, 27 Sep 2019 15:36:20 +0200
Subject: [PATCH 1/2] Add regression test for ICE #4579

---
 tests/ui/ice-4579.rs | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 tests/ui/ice-4579.rs

diff --git a/tests/ui/ice-4579.rs b/tests/ui/ice-4579.rs
new file mode 100644
index 00000000000..2e7e279f847
--- /dev/null
+++ b/tests/ui/ice-4579.rs
@@ -0,0 +1,13 @@
+#![allow(clippy::single_match)]
+
+use std::ptr;
+
+fn main() {
+    match Some(0_usize) {
+        Some(_) => {
+            let s = "012345";
+            unsafe { ptr::read(s.as_ptr().offset(1) as *const [u8; 5]) };
+        },
+        _ => (),
+    };
+}

From 4e7e71b46c88f9ba8b0a424053fe0f28c5e61ab3 Mon Sep 17 00:00:00 2001
From: flip1995 <hello@philkrones.com>
Date: Fri, 27 Sep 2019 15:36:56 +0200
Subject: [PATCH 2/2] Fix ICE #4579

---
 clippy_lints/src/consts.rs       | 8 +++++---
 clippy_lints/src/neg_multiply.rs | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs
index 0e1c1e60178..c8ee818d885 100644
--- a/clippy_lints/src/consts.rs
+++ b/clippy_lints/src/consts.rs
@@ -152,7 +152,7 @@ impl Constant {
 }
 
 /// Parses a `LitKind` to a `Constant`.
-pub fn lit_to_constant(lit: &LitKind, ty: Ty<'_>) -> Constant {
+pub fn lit_to_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {
     use syntax::ast::*;
 
     match *lit {
@@ -161,7 +161,9 @@ pub fn lit_to_constant(lit: &LitKind, ty: Ty<'_>) -> Constant {
         LitKind::ByteStr(ref s) => Constant::Binary(Lrc::clone(s)),
         LitKind::Char(c) => Constant::Char(c),
         LitKind::Int(n, _) => Constant::Int(n),
-        LitKind::Float(ref is, _) | LitKind::FloatUnsuffixed(ref is) => match ty.sty {
+        LitKind::Float(ref is, FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
+        LitKind::Float(ref is, FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),
+        LitKind::FloatUnsuffixed(ref is) => match ty.expect("type of float is known").sty {
             ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
             ty::Float(FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),
             _ => bug!(),
@@ -225,7 +227,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
         match e.node {
             ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id),
             ExprKind::Block(ref block, _) => self.block(block),
-            ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty(e))),
+            ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty_opt(e))),
             ExprKind::Array(ref vec) => self.multi(vec).map(Constant::Vec),
             ExprKind::Tup(ref tup) => self.multi(tup).map(Constant::Tuple),
             ExprKind::Repeat(ref value, _) => {
diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs
index c235661a432..8cbfee4f1fe 100644
--- a/clippy_lints/src/neg_multiply.rs
+++ b/clippy_lints/src/neg_multiply.rs
@@ -49,7 +49,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply {
 fn check_mul(cx: &LateContext<'_, '_>, span: Span, lit: &Expr, exp: &Expr) {
     if_chain! {
         if let ExprKind::Lit(ref l) = lit.node;
-        if let Constant::Int(val) = consts::lit_to_constant(&l.node, cx.tables.expr_ty(lit));
+        if let Constant::Int(val) = consts::lit_to_constant(&l.node, cx.tables.expr_ty_opt(lit));
         if val == 1;
         if cx.tables.expr_ty(exp).is_integral();
         then {