From 1a9fc18e830dc57731e2976edb5c5f0fabc5019c Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 9 Mar 2020 11:16:23 +0100
Subject: [PATCH] panic_bounds_check: use caller_location, like PanicFnLangItem

---
 src/libcore/panicking.rs              | 18 ++++++++++++++++++
 src/librustc_codegen_ssa/mir/block.rs |  6 +++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 61b764f2d62..d58a7cfec95 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -52,6 +52,24 @@ pub fn panic(expr: &str) -> ! {
     panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), Location::caller())
 }
 
+#[cfg(not(bootstrap))]
+#[cold]
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[track_caller]
+#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
+fn panic_bounds_check(index: usize, len: usize) -> ! {
+    if cfg!(feature = "panic_immediate_abort") {
+        unsafe { super::intrinsics::abort() }
+    }
+
+    panic_fmt(
+        format_args!("index out of bounds: the len is {} but the index is {}", len, index),
+        Location::caller(),
+    )
+}
+
+// For bootstrap, we need a variant with the old argument order.
+#[cfg(bootstrap)]
 #[cold]
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
 #[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index a1b54607b80..f22c0216a78 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -415,11 +415,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             AssertKind::BoundsCheck { ref len, ref index } => {
                 let len = self.codegen_operand(&mut bx, len).immediate();
                 let index = self.codegen_operand(&mut bx, index).immediate();
-                (lang_items::PanicBoundsCheckFnLangItem, vec![location, index, len])
+                // It's `fn panic_bounds_check(index: usize, len: usize)`, and
+                // `#[track_caller]` adds an implicit third argument.
+                (lang_items::PanicBoundsCheckFnLangItem, vec![index, len, location])
             }
             _ => {
                 let msg_str = Symbol::intern(msg.description());
                 let msg = bx.const_str(msg_str);
+                // It's `pub fn panic(expr: &str)`, with the wide reference being passed
+                // as two arguments, and `#[track_caller]` adds an implicit third argument.
                 (lang_items::PanicFnLangItem, vec![msg.0, msg.1, location])
             }
         };