diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs
index c503142e5e4..28bec872c08 100644
--- a/clippy_dev/src/update_lints.rs
+++ b/clippy_dev/src/update_lints.rs
@@ -977,7 +977,11 @@ fn remove_line_splices(s: &str) -> String {
         .and_then(|s| s.strip_suffix('"'))
         .unwrap_or_else(|| panic!("expected quoted string, found `{}`", s));
     let mut res = String::with_capacity(s.len());
-    unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, _| res.push_str(&s[range]));
+    unescape::unescape_literal(s, unescape::Mode::Str, &mut |range, ch| {
+        if ch.is_ok() {
+            res.push_str(&s[range]);
+        }
+    });
     res
 }
 
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index 5533840b166..abd681c5307 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -805,7 +805,11 @@ fn check_newlines(fmtstr: &StrLit) -> bool {
     let contents = fmtstr.symbol.as_str();
 
     let mut cb = |r: Range<usize>, c: Result<char, EscapeError>| {
-        let c = c.unwrap();
+        let c = match c {
+            Ok(c) => c,
+            Err(e) if !e.is_fatal() => return,
+            Err(e) => panic!("{:?}", e),
+        };
 
         if r.end == contents.len() && c == '\n' && !last_was_cr && !has_internal_newline {
             should_lint = true;
diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs
index e5ca3545540..6b7d5e9aea8 100644
--- a/clippy_utils/src/macros.rs
+++ b/clippy_utils/src/macros.rs
@@ -389,8 +389,10 @@ impl FormatString {
         };
 
         let mut unescaped = String::with_capacity(inner.len());
-        unescape_literal(inner, mode, &mut |_, ch| {
-            unescaped.push(ch.unwrap());
+        unescape_literal(inner, mode, &mut |_, ch| match ch {
+            Ok(ch) => unescaped.push(ch),
+            Err(e) if !e.is_fatal() => (),
+            Err(e) => panic!("{:?}", e),
         });
 
         let mut parts = Vec::new();
diff --git a/tests/ui/crashes/ice-9405.rs b/tests/ui/crashes/ice-9405.rs
new file mode 100644
index 00000000000..e2d274aeb04
--- /dev/null
+++ b/tests/ui/crashes/ice-9405.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::useless_format)]
+#![allow(clippy::print_literal)]
+
+fn main() {
+    println!(
+        "\
+
+            {}",
+        "multiple skipped lines"
+    );
+}
diff --git a/tests/ui/crashes/ice-9405.stderr b/tests/ui/crashes/ice-9405.stderr
new file mode 100644
index 00000000000..9a6e410f21e
--- /dev/null
+++ b/tests/ui/crashes/ice-9405.stderr
@@ -0,0 +1,11 @@
+warning: multiple lines skipped by escaped newline
+  --> $DIR/ice-9405.rs:6:10
+   |
+LL |           "/
+   |  __________^
+LL | |
+LL | |             {}",
+   | |____________^ skipping everything up to and including this point
+
+warning: 1 warning emitted
+