From 2bb5b5c07c5cd015c567ce86eae07e92db07bb8a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 6 Apr 2018 14:20:22 -0700 Subject: [PATCH] core: Remove an implicit panic from Formatter::pad The expression `&s[..i]` in general can panic if `i` is out of bounds or not on a character boundary for a string, and this caused the codegen for `Formatter::pad` to be a bit larger than it otherwise needed to be. This commit replaces this with `s.get(..i).unwrap_or(&s)` which while having different behavior if `i` is out of bounds has a much smaller code footprint and otherwise avoids the need for `unsafe` code. --- src/libcore/fmt/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index d55219d7226e6..277bef2bf661a 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1212,7 +1212,11 @@ impl<'a> Formatter<'a> { // truncation. However other flags like `fill`, `width` and `align` // must act as always. if let Some((i, _)) = s.char_indices().skip(max).next() { - &s[..i] + // LLVM here can't prove that `..i` won't panic `&s[..i]`, but + // we know that it can't panic. Use `get` + `unwrap_or` to avoid + // `unsafe` and otherwise don't emit any panic-related code + // here. + s.get(..i).unwrap_or(&s) } else { &s }